节目选择' \ 0'即使没有提到 - 澄清

时间:2017-07-10 18:24:46

标签: c++ arrays

所以,我可以预测这个程序会做什么:

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[],所以它是这个程序的垃圾值正在采摘?我做了这个,同时应该无限次地运行。是吗?

2 个答案:

答案 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外找到。