0

我一直在做的是:

int arr[] = {2, 3, 4};

它总是有效的。

我听说过使用指针初始化新数组的更好方法:

int *arr = {2, 3, 4};

但是,它在任何 IDE 中都不起作用,它会引发一些错误,例如int differs in levels of indirection from int, 或too many initializers. 我该怎么做?

4

6 回答 6

5
int arr[] = {2, 3, 4};

很好,而且完全正确。无需更改。

于 2012-11-15T14:18:43.447 回答
5

在 gcc 上,该初始化似乎对我有用,但不正确。

int *arr = {2, 3, 4}; //weird behaviour, stores first value `2` as read-only

int arr[] = {2, 3, 4}; //array decl

前者不是初始化数组的正确方法。

对于char*,它更有意义

char* arr = "abcde"; //Pointer to a read-only char array in memory

char[] arr = "abcde"; //Normal char array

区别:

前者被写入程序集的Rodata(常量、只读数据)部分,而后者位于读/写Data-Segment中。任何更改前者的尝试都可能导致分段错误


存储值的位置不同。

char* arr = "abcde";
arr[1] = 'f'; //(undefined behavior)

char[] arr2 = "abcde";
arr2[1] = 'f'; //no issue
于 2012-11-15T14:21:28.200 回答
2

如果要“初始化数组”,则必须初始化数组,而不是指针。

无论如何,在 C99中可以使用复合文字,并且可以将指针初始化为

int *arr = (int []) {2, 3, 4};

这与您尝试做的很接近。尽管术语“ANSI C”通常用于指代 C89/90,但该功能不可用。

这种方法没有什么“更好”的了。它只是给你一个指针而不是一个数组,所以这真的是你需要什么的问题。

于 2012-11-15T15:41:51.860 回答
1

为什么第二个版本比第一个更好?

至少第一个版本是明确的:您定义一个具有给定元素的 int 数组。让编译器确定如何以最佳方式执行此操作。

于 2012-11-15T14:19:51.317 回答
1

从您对 Evan Li 的评论开始(“字符串也是一种数组,它是用指针​​初始化的。因此,数组也应该以这种方式初始化。”)。如果教练真的告诉你这个,我会认真考虑找一个新的教练,因为他对事情感到困惑。

字符串文字是一个数组表达式;文字 "Hello" 是char(const char在 C++ 中) 的 6 元素数组。字符串字面量的存储方式是在程序的整个生命周期内分配它们的内存;此内存可能是只读的,也可能不是只读的,具体取决于平台。尝试修改字符串文字内容的行为是undefined,这意味着您可能会遇到段错误,或者字符串可能会被修改,或者发生其他事情。

当数组表达式出现在上下文中而不是作为sizeof或一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字时,则表达式的类型从“N”转换(“衰减”) -element 数组T“指向”的指针T,表达式的值是数组第一个元素的地址。

这就是为什么你可以写类似的东西

char *foo = "This is a test";

字符串字面"This is a test"量是“15 元素数组char”类型的数组表达式;因为它不是sizeofor&运算符的操作数,也不是用于初始化 的另一个数组char,所以表达式的类型变为“指向char”,并且第一个字符的地址被分配给foo。通过对比,

char foo[] = "This is a test";

声明foo为;的数组 char大小是根据初始化字符串的大小(15 个字符)计算得出的,并且字符串文字的内容被复制到foo.

字符串是数组表达式;用大括号括起来的值列表不是.

int *foo = {1, 2, 3};

不会创建 3 元素数组int并将第一个元素的地址分配给foo; 相反,如果我没看错的话,这应该是违反约束

6.7.9 初始化

约束

2 初始化器不得尝试为未包含在被初始化实体中的对象提供值。

从 C99 开始,您可以使用所谓的复合文字,如下所示:

int *foo = (int []) {1, 2, 3};

强制转换表达式(int [])是必需的。这确实创建了一个新的 3 元素数组,int并将第一个元素的地址分配给foo. 与字符串文字不同,像这样的复合文字只存在于封闭块1的持续时间内;IOW,如果你做了类似的事情

int *foo = NULL;
if (condition())
{
  foo = (int []){1, 2, 3};
  // do stuff
}
// do more stuff

指向的匿名数组对象foo只存在于if块内;一旦if块退出,数组就不再存在,并且 的值foo不再有效。


1. 如果复合文字是在文件范围内定义的(在任何函数之外),那么它具有static持续时间并且在程序的生命周期内都存在。

于 2012-11-15T17:33:21.113 回答
-1

int arr[] = {2, 3, 4}; 没关系。

如果要使用指针,则必须使用例如 malloc 分配内存。类似的东西:

  int *arr = malloc(sizeof(int)*4);

  arr[0]=1;
  arr[1]=2;
  arr[2]=3;
  arr[3]=4;

  //display
  printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);

  free(arr);
于 2012-11-15T14:33:09.160 回答