C语言中"int arr[] = {}"和"int arr[]"的区别



查看以下代码:

int arr[4];
for (int index = 0; index < 4; ++index) {
printf("%dt", arr[index]);
}

它打印随机值,如下所示:

27224   -6784   32766   0   

但是当我arr设置为{}时,它会打印零。

int arr[4] = {};
for (int index = 0; index < 4; ++index) {
printf("%dt", arr[index]);
}
0   0   0   0   

为什么?

默认情况下,数组元素是未初始化的,这意味着它们将包含垃圾值:

int arr[4];

使用大括号初始值设定项,您可以显式设置初始值,例如

int arr[4] = {1, 2, 3, 4};

但是,如果大括号中的数字数小于数组的长度,则其余数字用零填充。这就是在这种情况下发生的事情:

int arr[4] = {};

请注意,这在 C 中无效,仅在 C++ 中有效,但您的编译器显然无论如何都允许它。在标准 C 中,必须至少写入一个值:

int arr[4] = {0};

当我在编译器(gcc 9.3)中尝试您的代码时,它会发出以下警告:

prog_c.c:14:12: warning: ISO C forbids empty initializer braces [-Wpedantic]
14 | int arr[4]={};

我认为它认为这相当于int arr[4]={a_single_value};但没有这个单一值(这是不正确的)。
当您为少于 元素,则语言认为缺少的元素是 设置为零。
在您不正确的情况下,我想编译器应用相同的规则 对于所有元素。
您的{}初始化被视为部分初始化 的数组。

这两个代码片段都无效。

在第一个代码片段中,数组具有自动存储持续时间,并且未初始化。所以它的元素具有不确定的值。因此,程序具有未定义的行为。

在第二个代码片段中,使用了无效的构造来初始化数组

int arr[4] = {};

您不能在 C 中使用空大括号(尽管它在 C++ 中有效)。此构造可以是 C 的特定编译器扩展。正确的初始化如下所示

int arr[4] = { 0 };

当初始化少于初始化元素的数量时,没有显式初始值设定项的元素初始化为零。

来自 C 标准(6.7.9 初始化)

21 如果大括号括起来的列表中的初始值设定项少于 是聚合的元素或成员,或 字符串文字,用于初始化已知大小的数组,而不是那里 是数组中的元素,聚合的其余部分应为 隐式初始化与具有静态存储的对象相同 期间。

10 如果具有自动存储持续时间的对象未初始化 明确地说,它的值是不确定的。如果对象具有静态 或线程存储持续时间未显式初始化,则:

— 如果它具有指针类型,则将其初始化为空指针;

— 如果它具有算术类型,则初始化为 (正或 无符号)零;

— 如果它是一个聚合,则初始化每个成员(递归) 根据这些规则,任何填充都初始化为零位;

— 如果是联合,则初始化第一个命名成员 (递归)根据这些规则,并且初始化任何填充 到零位;

因此,在此声明中,数组的第一个元素由 0 显式初始化,数组的所有其他元素由编译器使用 0 隐式初始化。

在 C 中这样的初始化

int arr[4] = { 0 };

等效于以下初始化形式

int arr[4] = { [0] = 0 };

或例如以下形式

int arr[4] = { [3] = 0 };

或者您甚至可以省略数组声明中的元素数量,例如

int arr[] = { [3] = 0 };

也就是说,所有没有显式初始值设定项的元素都将为零初始化。

代码

int arr[4];

为四个整数的数组(在堆栈上)分配内存,但不初始化它。你得到的输出只是内存中发生的一切的表示 - 实际上是随机的。

int arr[4] = {}

指示编译器将所有值设置为零。

你可以把

int arr[4]  = {1,2,3,4}

初始化为特定值

通过声明int arr [4],您只是在创建一个引用。由于从未为其赋值,因此此引用指向的值不会更改。这是因为 C 是一种显式语言。因此,那里的值是内存 arr[4] 正在使用的先前保存的任何值。

通过声明int arr[4] = {};,您将数组显式设置为等于某些内容。这将清除使用 arr[4] 引用的内存,并将其设置为等于值 {}。由于 {} 中没有任何值,因此C++将其默认为 0。

看起来您正在运行一个可以编译 C 和 C++ 代码的 IDE。这就是为什么它默认为 0。C 比 C++ 更明确,因此对于 C 代码,您必须将值放在括号中,例如
int arr[4] = {1, 2, 3, 4};

希望对您有所帮助!

相关内容

最新更新