我一直在做的是:
int arr[] = {2, 3, 4};
它总是有效的。
我听说过使用指针初始化新数组的更好方法:
int *arr = {2, 3, 4};
但是,它在任何 IDE 中都不起作用,它会引发一些错误,例如int differs in levels of indirection from int
, 或too many initializers
. 我该怎么做?
int arr[] = {2, 3, 4};
很好,而且完全正确。无需更改。
在 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
如果要“初始化数组”,则必须初始化数组,而不是指针。
无论如何,在 C99中可以使用复合文字,并且可以将指针初始化为
int *arr = (int []) {2, 3, 4};
这与您尝试做的很接近。尽管术语“ANSI C”通常用于指代 C89/90,但该功能不可用。
这种方法没有什么“更好”的了。它只是给你一个指针而不是一个数组,所以这真的是你需要什么的问题。
为什么第二个版本比第一个更好?
至少第一个版本是明确的:您定义一个具有给定元素的 int 数组。让编译器确定如何以最佳方式执行此操作。
从您对 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
”类型的数组表达式;因为它不是sizeof
or&
运算符的操作数,也不是用于初始化 的另一个数组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
不再有效。
static
持续时间并且在程序的生命周期内都存在。
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);