2

给定以下代码:

#include<iostream>
int main(){
  char container[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
  for(char* cptr = container; *cptr != 0; cptr++)
    std::cout << *cptr << std::endl;
  return 0;
}

每次我执行它时,它都会按顺序打印这些字符。我不明白为什么循环会终止,因为我没有在容器数组的末尾明确指定任何空终止符。请帮忙。

4

4 回答 4

8

这只是运气,真的。

碰巧对应的内存区域container[7]为0,所以你很幸运。

超出数组的界限是未定义的行为。在您的情况下,它恰好是您希望的行为,但您不能依赖它。

于 2013-10-14T16:43:12.407 回答
3

首先,您发布的代码有一个可怕的错误:cptr != 0应该是*cptr != 0. 您应该检查给定地址处的字符是否为空,而不是指针本身是否为空。

其他答案和评论都是正确的。您获得正确输出的唯一原因是因为在容器数组的末尾恰好有一些归零的内存。将container数组放入结构中将有助于消除编译器可能插入的额外填充:

#include<iostream>
int main(){
  struct {
    char container[7];
    char alphabet[27];
  } x = {
    {'a', 'b', 'c', 'd', 'e', 'f', 'g'},
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  };
  for(char* cptr = x.container; *cptr != 0; cptr++)
    std::cout << *cptr << std::endl;
  return 0;
}

如果你运行这个版本,你会看到你的数组'a'-<code>'g' 被打印出来,然后它会跑到第二个数组中并打印'A'-<code>'Z',然后在字符串的末尾点击 null。

于 2013-10-14T17:01:33.993 回答
2

您正在运行调用未定义行为的数组的末尾。一种可能的未定义行为是它以看似合理的方式工作。在这种情况下,可能发生的事情是未定义的行为正在用零填充您的数组。

于 2013-10-14T16:43:24.827 回答
1

您正在唤起未定义的行为。未定义的行为意味着“任何事情都可能发生”,其中有时包括您想要发生的事情。这就是这里发生的事情。

您调用未定义行为的原因是因为您正在从未初始化的内存中读取,当您访问container.

于 2013-10-14T16:48:41.760 回答