编译器如何填充char array[100] = {0};
中的值?它背后的魔力是什么?
我想知道内部编译器如何初始化。
答案 0 :(得分:161)
这不是魔术。
C中此代码的行为在C规范(online draft of C spec)的6.7.8.21节中描述:对于没有指定值的元素,编译器将指针初始化为NULL和算术类型为零(并递归地将其应用于聚合)。
C ++中的代码行为在C ++规范(online draft of C++ spec)的8.5.1.7节中描述:编译器聚合初始化没有指定值的元素。
另外,请注意,在C ++(但不是C)中,您可以使用空的初始化列表,从而使编译器聚合初始化数组的所有元素:
char array[100] = {};
关于编译器在执行此操作时可能生成的代码类型,请查看以下问题:Strange assembly from array 0-initialization
答案 1 :(得分:34)
实现取决于编译器开发人员。
如果你的问题是“这种声明会发生什么” - 编译器会将第一个数组元素设置为你提供的值(0),所有其他数组元素将设置为零,因为它是省略的数组元素的默认值
答案 2 :(得分:27)
如果您的编译器是GCC,您还可以使用以下语法:
int array[256] = {[0 ... 255] = 0};
请看 http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits,请注意,这是特定于编译器的功能。
答案 3 :(得分:17)
这取决于你进行初始化的地方。
如果数组是静态的,如
char array[100] = {0};
int main(void)
{
...
}
然后是编译器在程序的数据段中保留100 0字节。在这种情况下,您可以省略初始化器。
如果您的阵列是自动的,那么这是另一个故事。
int foo(void)
{
char array[100] = {0};
...
}
在这种情况下,每次调用函数foo时,你都会有一个隐藏的memset。
上面的代码相当于
int foo(void)
{
char array[100];
memset(array, 0, sizeof(array));
....
}
如果省略初始化程序,则数组将包含随机数据(堆栈数据)。
如果您的本地数组声明为静态,如
int foo(void)
{
static char array[100] = {0};
...
}
然后它在技术上与第一个相同。