在C中为什么这样做是合法的
char * str = "Hello";
但非法行事
int * arr = {0,1,2,3};
答案 0 :(得分:12)
我想这就是初始化程序在C中的工作原理。但是,你可以这样做:
int *v = (int[]){1, 2, 3}; /* C99. */
答案 1 :(得分:8)
至于C89:
"A string"
在char
数组初始化之外使用时,是一个字符串文字;标准说当你使用字符串文字时,就好像你创建了一个初始化为该值的全局char
数组并写下了它的名字而不是文字(还有一个额外的限制,即任何修改字符串文字结果的尝试在未定义的行为)。在您的代码中,您正在使用字符串文字初始化char *
,该字符串文字会衰减为char
指针,一切正常。
但是,如果你使用一个字符串文字来初始化一个char
数组,那么几个魔术规则就会起作用,所以它不再“像一个数组......等”(这在数组中不起作用)初始化),但这只是告诉编译器应该如何初始化数组的好方法。
初始化数组的{1, 2, 3}
方法只保留了这个语义:它只用于数组的初始化,它不是“数组文字”。
答案 2 :(得分:5)
以下情况:
char * str = "Hello";
"Hello"
是一个字符串文字。它在程序运行时被加载到内存中(但通常是只读的),并且具有可以分配给像char *str
这样的指针的内存地址。但是,像这样的字符串文字是个例外。
使用:
int * arr = {0,1,2,3};
..你有效地试图指向一个没有被放在内存中的任何地方的数组。 arr
是一个指针,而不是一个数组;它拥有一个内存地址,但本身并没有存储数组数据。如果您使用int arr[]
而不是int *arr
,那么它可以工作,因为像这样的数组与其内容的存储相关联。虽然数组在许多情况下衰减到指向其数据的指针,但它并不是一回事。
即使使用字符串文字,char *str = "Hello";
和char str[] = "Hello";
也会做不同的事情。第一个将指针str
设置为指向字符串文字,第二个将数组str
初始化为"Hello"
的值。该数组具有与其关联的数据的存储空间,但指针只指向恰好已经加载到内存中的数据。
答案 3 :(得分:3)
因为声明和初始化指向int数组的指针没有意义,所以当数组名称可以用作指向第一个元素的指针时。之后
int arr[] = { 0, 1, 2, 3 };
您几乎可以在所有上下文中使用arr
,例如int *
(例外情况为sizeof
的操作数)。
答案 4 :(得分:2)
...或者您可以滥用字符串文字并将数字存储为字符串文字,对于小端程序机器将如下所示:
int * arr = (int *)"\0\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0";