{0}和""之间有什么区别?

7

我想知道以下两者是否有区别:

char s[32] = "";

并且:

char s[32] = {0};

感谢您使用我们的服务。

答案已经给出。但万一你现在认为{0}""没有区别,可以尝试其他类型进行比较,例如使用int数组而不是char数组,这时你就会看到区别了。 - Mr Lister
5个回答

18

两种声明方式没有区别:

char bla[32] = {0};

and

char bla[32] = "";

请参考 C 标准的相关段落(重点在于下面的文字):

(C99,6.7.8p21)"如果大括号中包含的初始化项少于聚合体(aggregate)的元素或成员数量,或者用于初始化已知大小数组的字符串字面值中字符数少于数组元素数量,则该聚合体的其余部分将隐式地被初始化为具有静态存储期的对象相同。"


1
也就是说,只要'\0' == 0 - Philip
2
@Philip 我没有标准的引用,但这是K&R第二版所说的:“字符常量'\0'表示值为零的字符,即空字符。 '\0'通常代替0来强调某些表达式的字符性质,但数字值只是0。” - ouah
3
在n1570中,它是6.4.4.4,分别为(5)和(10),还有(12)。'\0'只是另一种写int 0的方式。 - Daniel Fischer

10
在这种情况下,两者没有区别,都将数组的所有插槽初始化为0。一般来说,"" 仅适用于char类型的数组(带或不带像constunsigned之类的修改),但{0} 适用于所有数字类型的数组。
在标准(n1570)的第6.7.9节中,第21点阅读:
如果花括号括起来的列表中初始化器比聚合体中的元素或成员少,或者初始化尺寸已知的数组的字符串文字中字符比数组中的元素少,则聚集体的其余部分应该隐式地初始化为具有静态存储期的对象。
所以即使是""也会初始化整个数组。

+1 {0}适用于允许具有初始化程序的任何数据类型。另一方面,它适用于所有数组,即不适用于VLA,因为这些数组不能有初始化程序。 - Jens Gustedt

2

没有区别。你也可以自己看看!这是你能得到的最可靠的答案。只需使用调试器。执行这两行并比较结果。但是你应该重命名数组。我使用gcc/gdb编译以下代码:

int main(int argc, char* argv[])
{
    char s[5] = {0};
    char t[5] = "";
    return 0;
}

通过gcc -g test.c编译代码,然后调用gdb a.out进行调试。在gdb中输入

break 5
run
print s
最后一个语句的输出如下:
$1 = "\000\000\000\000"

我继续输入"print t"并得到了相应的结果。
$2 = "\000\000\000\000"

这告诉我,在我选择的编译器下,这两个语句的结果是相同的。


3
Matthias说:“那并不是最可靠的方法,因为任何未定义的行为都可能因编译器实现或未初始化内存内容的差异而有所不同。” - Tony Delroy
@tony-delroy 我澄清了,希望我表达得更清楚了(不过我还没有理解你的观点...) - Matthias
1
我的观点是,知道程序在特定运行时的行为并不能证明任何C++编译器生成的可执行文件都必须遵循C++标准所要求的行为。如果你想要可靠的代码,你应该坚持遵循标准所保证的内容,因为可观察的程序行为可能会有所不同。例如,如果你从未初始化的变量中读取 - int x; std::cout << x << '\n'; - 你可能会偶然看到你期望的数字(特别是如果你期望得到0),但重新运行程序或重新编译它,你可能会得到不同的输出... - Tony Delroy
1
@tony-delroy 毫无疑问。但是换另一种方式看待它。标准规定“x”,而你使用的编译器却说“y”。这就是我在写“可靠”的时候所考虑的。当然,我的答案可能更适合初学者。而你的答案则适用于专业人士,他们需要部署能在各种平台上运行并将被用于数十年的代码。同意吗? - Matthias
1
我认为初学者可以通过实验学习很多编程知识,但怀疑未初始化的变量是否恰好为0是由运气还是符合标准并不是其中之一。序列点是另一个太多初学者试图通过实验学习的领域。无论如何,我已经解释了我的担忧 - 读者可以看到两面... :-)。 - Tony Delroy

2

除了已经说过的内容以外:

char s[32] = "";

=

char s[32] = {'\0'};

=

char s[32] = {0};

=

char s[32] = {0, 0, 0, /* ...32 zeroes here*/ ,0 };

所有这些都会产生完全相同的机器代码:一个填满所有零的32字节数组。

2
两个表达式的结果都是一样的:一个空字符串。然而,第一个表达式更加显式,因此更易读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接