ANSI C - 初始化数组

时间:2012-11-15 14:16:58

标签: c arrays

我一直在做的是:

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

它始终有效。

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

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

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

6 个答案:

答案 0 :(得分:5)

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

很好,完全正确。无需改变。

答案 1 :(得分: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 (常量,只读数据)部分,而后者则驻留在读/写数据段中。任何改变前者的尝试都可能导致分段错误


存储值的位置不同。

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

char[] arr2 = "abcde";
arr2[1] = 'f'; //no issue

答案 2 :(得分:2)

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

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

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

这与您尝试做的很接近。虽然术语“ANSI C”通常用于表示C89 / 90,但此功能不可用。

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

答案 3 :(得分:1)

为什么第二个版本会优于第一个?

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

答案 4 :(得分:0)

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

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

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

那是为什么你可以编写像

这样的东西
char *foo = "This is a test";

字符串文字"This is a test"是“15个元素数组char”类型的数组表达式;因为它不是sizeof&运算符的操作数,并且不用于初始化另一个char数组,所以表达式的类型变为“指向{{的指针1}}“,并将第一个字符的地址分配给char。相比之下,

foo

char foo[] = "This is a test"; 声明为foo数组;大小由初始化字符串的大小(15个字符)计算,字符串文字的内容被复制到char

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

foo

不会创建int *foo = {1, 2, 3}; 的3元素数组,并将第一个元素的地址指定给int;相反,如果我正在阅读this

6.7.9初始化

约束

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

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

foo

需要使用强制转换表达式int *foo = (int []) {1, 2, 3}; 。这会创建一个(int [])的新3元素数组,并将第一个元素的地址分配给int。与字符串文字不同,像这样的复合文字仅在封闭块 1 的持续时间内存在; IOW,如果你做了像

这样的事情
foo

int *foo = NULL; if (condition()) { foo = (int []){1, 2, 3}; // do stuff } // do more stuff 指向的匿名数组对象仅存在于foo块中;一旦if块退出,阵列就不再存在,if的值不再有效。

<小时/> 1。如果复合文字是在文件范围内定义的(在任何函数之外),那么它的持续时间为foo,并且在程序的生命周期内存在。

答案 5 :(得分:-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);