0

当我尝试

    char bla[32] = "foobar";
    int i;
    putchar(bla[i]);

strlen(bla) < i < 32bla[i]总是\0。但这实际上不是未定义的行为,应该避免吗?

4

7 回答 7

5

在 C99 标准的第 6.7.8 节中,第 21 段规定:

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

第 10 段指出静态算术类型(包括 char)被初始化为零。

基于此,当使用字符串文字作为初始值设定项时,您应该期望数组的其余部分被初始化为零。

于 2010-07-06T16:00:30.590 回答
4

C89 规范,第 8.7 节“初始化”:

如果数组的大小是固定的,则初始化器的数量不能超过数组的成员数;如果数量较少,则将尾随成员初始化为 0。

因此,在您的使用中,尾随字符用零初始化。

于 2010-07-06T16:02:47.423 回答
2

C 语言在初始化时遵循全有或全无的原则。对象要么完全未初始化,要么完全初始化。后者意味着如果您指定的初始化程序少于初始化整个对象所需的初始化程序,则编译器会为您隐式零初始化该对象的其余部分。

这适用于所有聚合类型。在您的情况下,它恰好是一个用字符串文字初始化的字符数组。在这种情况下,例如,

int a[100] = { 1 };

你得到一个 100 s 的数组,int第一个初始化为1,其余设置为0.

于 2010-07-06T16:17:31.797 回答
1

我认为这是定义明确的行为,实际上是一个功能。只要您初始化数组中的一个元素,或者struct所有未显式初始化的剩余元素都初始化为0.

于 2010-07-06T15:51:11.640 回答
0

数组未初始化部分的内容取决于它所在的位置(即在哪个数据段上)。如果它在堆栈上,则未初始化的元素是随机值。一般来说,如果是全局范围的数组,初始内容也是未定义的。如果提供了static说明符,则编译器在程序启动时将其内容初始化为零。

不禁止访问这个未初始化的部分,这不会假设未定义的行为,但结果可能是未定义的。即使访问bla[i]ifi > sizeof(bla)也不是未定义的行为,因为您要么有随机值,要么有分段错误异常。

于 2010-07-06T15:20:18.173 回答
0

它是未定义的行为这一事实意味着它可以做任何事情。它可能每次都做同样的事情,但所做的是任何人的猜测。

于 2010-07-06T15:20:56.737 回答
0

这不是编译器的“功能”,而是有据可查的行为。C 编程语言不保证未初始化变量的值。因此,您只是在猜测 i 的值是什么,您可以轻松访问不属于您的进程和 Windows 平台的内存,例如,这将导致 Access Violation 异常。有关详细信息,请参阅http://en.wikipedia.org/wiki/Uninitialized_variable

于 2010-07-06T15:25:43.653 回答