所以,我可以预测这个程序会做什么:
int main()
{
char d[] = {'h','e','l','l','o'};
const char *c = d;
std::cout << *c << std::endl;
while ( *c ) {
c = c + 1;
std::cout << *c << std::endl;
if ( *c == '\0' )
std::cout << "Yes" << std::endl;
}
return 0;
}
根据我的理解,代码应该永远不会打印是,因为字符数组\0
中没有d[]
,所以它是这个程序的垃圾值正在采摘?我做了这个,同时应该无限次地运行。是吗?
答案 0 :(得分:7)
这个问题的正确答案是该程序表现出未定义的行为,因为它超越了数组的末尾。
更改程序以使用字符串文字进行初始化会将行为更改为&#34;始终打印"Yes"
:
char d[] = "hello";
我做了这个,而应该无限次地运行。
一旦发生未定义的行为,所有投注都将被取消。但是,通常程序设法在d[]
之外的内存中找到零字节,此时它会打印"Yes"
并退出循环。
答案 1 :(得分:-2)
您的代码是一个示例,其中数组d
不是字符串(更准确地说,不是一个非字符串的字符串),因此它是错误地将该数组用作字符串。这意味着,所有使用char*
字符串并使用\0
作为字符串结束符号的函数都会分配给d
....并且somtimes \0
可以使用的内存在外面找到(没有人事先知道这个\0
会在哪里找到)。再一次,这是错误的使用,可能导致与数组边界违规相关的错误。
最后,因为if
语句和while
的条件是&#34;关联&#34;在意义上&#34;(* c ==&#39; \ 0&#39;)在循环的最后一次迭代时为真(* c){...}&#34; while(*c){...}
无限的可能性非常低,&#34;是&#34;最终将被打印出来。
<强>更新强>
让我们另外考虑以下例子:
#include <iostream>
using namespace std;
int main()
{
char d1[] = { 'h', 'e', 'l', 'l', 'o' }; // no nul-terminator here
char d2[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
char d3[] = "hello";
cout << "Memory allocated for d1 - " << sizeof(d1) << endl;
cout << "Length of string in d1 - " << strlen(d1) << endl;
cout << "Memory allocated for d2 - " << sizeof(d2) << endl;
cout << "Length of string in d2 - " << strlen(d2) << endl;
cout << "Memory allocated for d3 - " << sizeof(d3) << endl;
cout << "Length of string in d3 - " << strlen(d3) << endl;
return 0;
}
输出将是(对于第二行并不总是完全相同,但相似):
为d1 - 5分配的内存
d1 - 19中的字符串长度
为d2 - 6分配的内存
d2 - 5中的字符串长度
为d3 - 6分配的内存
d3 - 5中的字符串长度
在这里你可以看到3种char-array初始化方法。此处d3
初始化为字符串文字,其中添加了\0
,因为值在""
中。数组d1
没有nul-terminator,结果strlen
返回值比sizeof
更重要 - \0
在数组d1
外找到。