【发布时间】:2010-03-24 16:00:03
【问题描述】:
#include<stdio.h>
int main()
{
char a[5]="hello";
puts(a); //prints hello
}
为什么代码编译正确?我们需要六个地方来存储"hello",对吗?
【问题讨论】:
-
可能是因为标题与问题不匹配。
-
在我被谷歌搜索误导后修复了标题
#include<stdio.h>
int main()
{
char a[5]="hello";
puts(a); //prints hello
}
为什么代码编译正确?我们需要六个地方来存储"hello",对吗?
【问题讨论】:
C 编译器会让你跑完数组的末尾,它不做那种检查。
【讨论】:
C 编译器允许您明确要求不使用空终止符。
char a[] = "Hello"; /* adds a terminator implicitly */
char a[6] = "Hello"; /* adds a terminator implicitly */
char a[5] = "Hello"; /* skips it */
任何小于 5 的值都会导致错误。
至于为什么 - 一种可能性是您的字符串是固定大小的,或者被用作字节值的缓冲区。在这些情况下,您不需要空终止符。
最佳做法是使用char a[],以便编译器可以自动将其设置为正确的值(包括终止符)。
【讨论】:
a 不包含空终止字符串(固定大小数组的额外初始值设定项 - 例如"hello" 中的空终止符 - 被丢弃),因此将指向该数组的指针传递给 @987654323 时的行为@ 未定义。
【讨论】:
puts,而不是以空结尾的字符串。 char 数组的初始化是有效的,即使是可疑的。
根据我的经验,很多编译器都会让你免于编译它。不过,它通常会在运行时崩溃(因为您没有空终止符)。
【讨论】:
仅当有空间或未指定数组尺寸时,C char 数组初始化才包含终止 null。
【讨论】:
您需要 6 个字符来将“hello”存储为以空字符结尾的字符串。但是 char 数组不限于存储以 nul 结尾的字符串,您可能需要将该数组用于其他目的,在这些情况下强制使用额外的 nul 字符将毫无意义。
【讨论】:
这是因为在 C 中,内存管理是手动完成的,不像在 java 和其他一些语言中...... 在编译期间不会检查您分配的六个位置,但如果您 必须进入归档(我的意思是实际存储)您将遇到运行时错误,因为程序在内存中为字符保留了五个位置(但预计会保留六个)但编译器没有检查!
【讨论】:
"hello" 字符串保存在只读内存中,最后为 0。 “a”指向这个字符串,这就是程序可以正常工作的原因。但我认为通常这是未定义的行为。 有必要查看编译器生成的汇编代码以了解究竟发生了什么。如果您想在这种情况下获得垃圾输出,请尝试:
char a[5] = {'h', 'e', 'l', 'l', 'o'}【讨论】:
hello 作为输出!
您使用的 C 编译器不会检查字符串文字是否适合 char 数组。您需要数组中的 6 个字符来适应文字“Hello”,因为文字包含终止零。现代编译器,例如 Visual C++ 2010 会检查这些内容并给出错误。
【讨论】: