C中数组初始化的差异

Posted

技术标签:

【中文标题】C中数组初始化的差异【英文标题】:Difference in array initialization in C 【发布时间】:2022-01-09 19:28:37 【问题描述】:

我有这个代码:

#include <stdio.h> 
int main()

    int arr2[5];
    arr2[0] = 0;
    arr2[1] = 1;
    arr2[2] = 2;
    arr2[3] = 3;
    int arr3[5] = 1, 2, 3, 4;

当我打印每个数组的第五个位置时,我会得到不同的结果:

printf("Fifth: %d\n", arr2[4]); // Prints Random number 
printf("Fifth: %d\n", arr3[4]); // Prints Zero!

输出:

Fifth: -858993460
Fifth: 0

我知道第一个是指向内存中第五个位置的指针,第二个是数组初始化为 0 的方式。 我不明白他们为什么给我 2 个不同的值。在这两种情况下,我都将数组的大小设置为 5;为什么会这样?

【问题讨论】:

实际上初始化了所有数组成员,而留下arr2[5] 只是分配而不初始化。您正在访问一个未定义的数组成员,这是未定义的行为。 【参考方案1】:

int arr2[5];
arr2[0] = 0;
arr2[1] = 1;
arr2[2] = 2;
arr2[3] = 3;

您实际上并没有初始化数组。您创建它时未初始化并为每个元素使用 indeterminate 值。然后你分配到四个独立的元素,让第五个未初始化。

另一方面,与

int arr3[5] = 1, 2, 3, 4;

你明确地初始化所有元素。前四个具有显式值,然后其余(单个,对于此特定数组)元素为零。

【讨论】:

【参考方案2】:

一个没有显式初始化的局部变量会得到不确定的值,如果你愿意的话,就是“垃圾”。打印不确定的值是未指定的行为,这意味着输出可能根本不遵循任何逻辑。每次打印相同的未初始化位置时,您甚至可能会得到不同的值。

在某些情况下,访问未初始化的局部变量甚至是未定义的行为 - 请参阅 (Why) is using an uninitialized variable undefined behavior?

C 中的初始化与变量声明发生在同一行。由于int arr2[5]; 线上没有=,因此没有进行初始化。以下几行不是初始化,而是运行时的赋值。而你遗漏了最后一项,所以它仍然是不确定的。

但是,如果数组被部分初始化,则数组中的其余项会被隐式初始化,“就好像它们具有静态存储持续时间一样”,这实际上意味着它们被设置为零并且这种行为很好 -已定义。

【讨论】:

将不确定的值传递给库函数是 UB(在标准中省略;DR451 将其指定为 UB)。 @M.M 是的,我记得听说过类似的事情。尽管在这种情况下,更相关的部分是访问一个未初始化的局部变量,该变量没有获取其地址(请参阅链接),该变量始终为 UB。但它不适用于使用[] 访问的数组。 printf 是一个库函数 @M.M 是的,你提到的 DR 没有进入 C17,也没有在 DR 中讨论过他们的“摇摆不定的类型”。实际标准中没有提到如果将不确定的值传递给库函数会发生什么。 由于遗漏而未定义,那么。但我认为我们可以将委员会决议视为意图的象征【参考方案3】:

您的数据在堆栈中。对于此类变量,标准不保证初始值(因此未定义)。 您没有初始化 arr2[4],并且您得到的值标准不提供任何保证,因此它们实际上可以是任何值。

【讨论】:

以上是关于C中数组初始化的差异的主要内容,如果未能解决你的问题,请参考以下文章

二维数组初始化的差异[重复]

C语言中怎么把一维数组初始化都为0,

两个STRING数组进行比较

C语言数组初始化问题。

C语言数组的初始化表示方法

C中如何实现数组的传值引用