C char数组的初始化
我不确定在初始化之后char数组中有什么会以下面的方式。
1. char buf[10] = "";
2. char buf[10] = " ";
3. char buf[10] = "a";
对于情况2,我认为buf[0]
应该是' '
, buf[1]
应该是'\0'
,并且从buf[2]
到buf[9]
将是随机内容。 对于案例3,我认为buf[0]
应该是'a'
, buf[1]
应该是'\ 0',并且从buf[2]
到buf[9]
将是随机内容。
那是对的吗?
而对于案例1, buf
将会是什么? buf[0] == '\0'
和从buf[1]
到buf[9]
将是随机内容吗?
这不是你如何初始化一个数组,但是:
-
第一个声明:
char buf[10] = "";
相当于
char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
第二个声明:
char buf[10] = " ";
相当于
char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
第三个声明:
char buf[10] = "a";
相当于
char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
正如你所看到的,没有随机的内容:如果初始化器较less,则数组的其余部分用0
初始化。 这种情况下,即使数组是在一个函数内声明的。
编辑:OP(或一个编辑器)在提供这个答案后,默默地改变了原始问题中的一些单引号到双引号。
您的代码将导致编译器错误。 你的第一个代码片段:
char buf[10] ; buf = ''
是非法的。 首先,在C中,不存在空char
。 您可以使用双引号来指定一个空string,如下所示:
char* buf = "";
这会给你一个指向NUL
string的指针,即只有NUL
字符的单string。 但是你不能使用单引号,里面没有任何东西 – 这是未定义的。 如果你需要指定NUL
字符,你必须指定它:
char buf = '\0';
反斜杠是从字符'0'
消除歧义的必要条件。
char buf = 0;
完成同样的事情,但是我认为,前者阅读起来不太模糊。
其次,你不能在数组被定义之后初始化数组。
char buf[10];
声明和定义数组。 数组标识符buf
现在是内存中的地址,不能通过赋值来更改buf
位置。 所以
buf = // anything on RHS
是非法的。 由于这个原因,你的第二个和第三个代码段是非法的。
要初始化一个数组,你必须在定义的时候这样做:
char buf [10] = ' ';
会给你一个10个字符的数组,第一个字符是空格'\040'
,其余的是NUL
,即'\0'
。 当一个数组被声明并且用一个初始值定义时,数组元素(如果有)超过了具有指定初始值的数组元素将被自动填充0
。 不会有任何“随机内容”。
如果您声明并定义数组,但不要初始化它,如下所示:
char buf [10];
你会在所有的元素中有随机的内容。
-
这些是相同的
char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
这些是相同的
char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
这些是相同的
char buf[10] = "a"; char buf[10] = {'a'}; char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
C11标准草案n1570 6.7.9初始化的相关部分说:
14字符types的数组可以通过string文字或UTF-8string文字来初始化,可以用大括号括起来。 string文字的连续字节(包括终止空字符,如果有空间或数组未知大小)初始化数组的元素。
和
21 如果大括号括起来的列表中的初始值设定项less于聚合的元素或成员,或者用于初始化比数组中元素大的已知大小数组的string文字中的字符数更less,那么聚合的其余部分应该被隐式地初始化为具有静态存储持续时间的对象。
因此, 如果有足够的空间 ,则附加'\ 0',其余的字符用static char c;
来初始化static char c;
将在一个函数内初始化。
最后,
10如果具有自动存储持续时间的对象未被明确初始化,则其值是不确定的。 如果具有静态或线程存储持续时间的对象未被明确初始化,则:
[ – ]
- 如果有算术types,则将其初始化为(正或无符号)零;
[ – ]
因此, char
是算术types,数组的其余部分也保证用零初始化。
有趣的是,可以在程序中随时以任何方式初始化数组,只要它们是struct
或union
成员。
示例程序:
#include <stdio.h> struct ccont { char array[32]; }; struct icont { int array[32]; }; int main() { int cnt; char carray[32] = { 'A', 66, 6*11+1 }; // 'A', 'B', 'C', '\0', '\0', ... int iarray[32] = { 67, 42, 25 }; struct ccont cc = { 0 }; struct icont ic = { 0 }; /* these don't work carray = { [0]=1 }; // expected expression before '{' token carray = { [0 ... 31]=1 }; // (likewise) carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *' iarray = (int[32]){ 1 }; // (likewise, but s/char/int/g) */ // but these perfectly work... cc = (struct ccont){ .array='a' }; // 'a', '\0', '\0', '\0', ... // the following is a gcc extension, cc = (struct ccont){ .array={ [0 ... 2]='a' } }; // 'a', 'a', 'a', '\0', '\0', ... ic = (struct icont){ .array={ 42,67 } }; // 42, 67, 0, 0, 0, ... // index ranges can overlap, the latter override the former // (no compiler warning with -Wall -Wextra) ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ... for (cnt=0; cnt<5; cnt++) printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]); return 0; }
我不知道,但我通常初始化一个数组“”在这种情况下,我不需要担心string的空端。
main() { void something(char[]); char s[100] = ""; something(s); printf("%s", s); } void something(char s[]) { // ... do something, pass the output to s // no need to add s[i] = '\0'; because all unused slot is already set to '\0' }