所有的字符数组是否都会自动添加空字符结尾?

14

也许我只是太愚蠢了,无法通过搜索找到答案,但我一直认为字符数组只能通过字面量初始化(char x[]="asdf";)才会得到空终止符,当我发现这似乎不是这种情况时有点惊讶。

int main()
{
    char x[2];
    printf("%d", x[2]);
    return 0;
}

输出:0

一个声明尺寸为2*char的数组不应该得到两个字符的大小吗?或者我在这里做错了什么?我的意思是,使用字符数组作为简单的字符数组而不是字符串并不常见,或者是吗?

3个回答

28

您正在访问一个未初始化的数组,超出了它的边界。这是双重的未定义行为,任何事情都可能发生,甚至会得到0作为输出。

回答您的实际问题:只有字符串字面值才被空字符终止,这意味着char x[]="asdf"是一个由5个元素组成的数组。


1
@user1329846:数组结束后存储在内存中的任何内容都取决于编译器,你现在得到的是0,但也可能得到其他数字,因为标准规定如果你尝试读取该位置,则一切皆有可能。让我明确一下:即使你总是幸运地得到0,你的代码仍会触发“未定义行为”,并且随时可能失败。 - K-ballo
1
谢谢您不使用“任何事情都可能发生,甚至您的计算机可能会自燃”的说法。不,它不可能。所有那些夸张的例子都很愚蠢。 - jn1kk
3
@skynorth: 他们并不是愚蠢的,只是为了戏剧效果而简化了。正确的版本是,“按照标准,任何事情都是允许发生的——实现可以将计算机点燃”。幽默版本忽略了除 C 标准外计算机行为受到的其他限制——操作系统、硬件、消防安全法规、物理法则等。 - Steve Jessop
1
@skynorth:对于一些人来说,某些东西能够正常工作似乎就意味着它是符合标准和正确的代码。告诉他们它明天可能会崩溃并不会产生任何影响,因为他们所关心的只是它现在能否正常工作。另一方面,“它可能会让你的电脑起火”这种说法会让他们停下来仔细思考。也许他们本应该主修表演而不是计算机科学... - K-ballo
1
@K-ballo,现在只是遵循指示的问题。如果我的同事或上司每次都要告诉我,如果我违反他们的建议(做错事)可能会导致电脑着火,那么我可能不会长时间保住工作。也许他们应该专攻戏剧专业,因为似乎他们不适合编程(一个遵循已有知识和偶尔创新的领域)。但这不是我的工作去评判。 - jn1kk
显示剩余5条评论

5

char数组并不会自动地以NULL字符('\0')结尾,只有字符串字面量如char *myArr = "string literal";和一些由stdlib库的字符串方法返回的字符串指针才是以NULL字符结尾的。

C语言没有边界检查。因此声明大小为2*char的数组会给你两个可以使用的内存槽位,但你可以在其两边自由读写内存,从而引发未定义行为。你可能会看到那里的0字节。你可能会写入array[-1]并导致程序崩溃。你有责任跟踪你的数组大小并避免触及你没有分配的内存。

通常,char数组被用作简单的字节数组,即除了C字符串外,例如用于保存任意原始字节缓冲区。


1
如果t是大小为2的数组,则最后一个情况是t [2-1] = t [1]而不是2。t [2]越界了。

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