我一直在做的是:
int arr[] = {2, 3, 4};
它始终有效。
我已经听说过使用指针初始化新数组的更好方法:
int *arr = {2, 3, 4};
但是,它在任何IDE中都不起作用,它会引发一些错误,例如int differs in levels of indirection from int
或too many initializers
。我该怎么做?
答案 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);