我不确定在初始化后以下列方式将在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]
则为随机内容。< / p>
这是对的吗?
对于案例1,buf
中的内容是什么? buf[0] == '\0'
和buf[1]
到buf[9]
会是随机内容吗?
答案 0 :(得分:187)
这不是初始化数组的方式,而是用于:
第一个声明:
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};
如您所见,没有随机内容:如果初始化程序较少,则使用0
初始化数组的剩余部分。即使数组在函数内声明也是如此。
答案 1 :(得分:20)
编辑:在提供此答案后,OP(或编辑)默默地将原始问题中的一些单引号更改为双引号。
您的代码将导致编译器错误。你的第一个代码片段:
char buf[10] ; buf = ''
是双重违法。首先,在C中,没有空char
这样的东西。您可以使用双引号指定空字符串,如:
char* buf = "";
这会给你一个指向NUL
字符串的指针,即一个只包含NUL
字符的单字符字符串。但你不能在其中没有任何内容使用单引号 - 这是未定义的。如果您需要指定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];
您将在所有元素中包含随机内容。
答案 2 :(得分:18)
这些是等效的
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};
答案 3 :(得分:6)
C11标准草案n1570相关部分6.7.9初始化说:
14 字符类型数组可以用字符串文字或UTF-8字符串初始化 文字,可选择括在括号中。字符串文字的连续字节(包括 如果有空间或数组的大小未知,则终止空字符)初始化 数组的元素。
和
21 如果支持括号列表中的初始值设定项少于元素或成员 用于初始化已知数组的字符串文字中的聚合或更少的字符 大小比数组中的元素大,其余的聚合应该是 隐式初始化与具有静态存储持续时间的对象相同。
因此,附加'\ 0',如果有足够的空间,其余的字符初始化为static char c;
将在函数内初始化。< / p>
最后,
10 如果未显式初始化具有自动存储持续时间的对象,则其值为 不定。如果未初始化具有静态或线程存储持续时间的对象 明确地说:
[ - ]
- 如果它有算术类型,则初始化为(正数或无符号)零;
[ - ]
因此,char
是一个算术类型,数组的其余部分也保证用零初始化。
答案 4 :(得分:3)
有趣的是,只要它们是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;
}
答案 5 :(得分:0)
我不确定,但我通常会将数组初始化为“” 在这种情况下,我不需要担心字符串的空结尾。
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'
}