给出以下代码:
#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;
}
每次执行时都会按顺序打印这些字符。我无法理解为什么循环会终止,因为我没有在容器数组的末尾显式指定任何null终止符。请帮忙。
答案 0 :(得分:8)
真的很幸运。
恰好与container[7]
对应的内存区域为0,所以你很幸运。
超出数组的范围是未定义的行为。在你的情况下,它恰好是你所希望的行为,但你不能依赖它。
答案 1 :(得分:3)
首先,您发布的代码有一个可怕的错误:cptr != 0
应为*cptr != 0
。您应该检查给定地址处的字符是否为空,而不是指针本身是否为空。
其他答案和评论是正确的。获得正确输出的唯一原因是因为在容器数组的末尾恰好有一些归零的内存。将container
数组放在struct中将有助于消除编译器可能插入的额外填充:
#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'
- 'g'
已打印出来,然后它会跳转到第二个阵列并打印'A'
- 'Z'
之前在该字符串的末尾点击null。
答案 2 :(得分:2)
你正在运行调用未定义行为的数组的末尾。一种可能的未定义行为是它以一种看似合理的方式工作。在这种情况下,可能发生的事情是未定义的行为是用零填充数组。
答案 3 :(得分:1)
您正在唤起未定义的行为。未定义的行为意味着“任何事情都可能发生”,其中有时包括您想要发生的事情。这就是这里发生的事情。
您调用未定义行为的原因是因为您正在读取未初始化的内存,当您访问container
之后的元素时。