为什么结果如此不同

why the results are so different?

本文关键字:结果 为什么      更新时间:2023-10-16

我不知道为什么相似的代码有很大的区别?第一个代码正常输出,但第二个代码输出一些无法识别的字符。谁能为我解释呢?

Thks

#include <iostream>
using namespace std;
int main(){
    char a[5] = { 'A', 'B', 'C', 'D' };
    cout << a + 1 << endl;
    char b[5] = {'a','b','c','d','e'};
    cout << b+1 << endl;
    return 0;
}

表达式a+1b+1都降级为char*,然后<<将其视为以NUL结尾的字符串,但只有a以NUL结束。以NUL结尾的字符串访问b会导致未定义的行为,在您的情况下,这似乎是在前几个字符之后打印垃圾。(注意,我最初说两者都不是以NUL结尾的,但后来我注意到a的初始值设定项中只有4个字符,但指定了5的大小。这意味着第五个元素将被零初始化,有效地NUL终止a。)

如果你想在不引起未定义行为的情况下正确打印它们,请确保它们是NUL终止的:

int main(){
    char a[5] = { 'A', 'B', 'C', 'D' }; // Works as-is, but not good form
    cout << a + 1 << endl;
    char b[6] = {'a','b','c','d','e', ''}; // Needed NUL-terminated, but still not the best way
    cout << b+1 << endl;
    return 0;
}

或者,正如本征克里斯在一条评论中指出的那样,您可以依靠编译器通过使用字符串常量来为您NUL终止它:

char a[] = "ABCD";
char b[] = "abcde"; // Probably the best way to do this.

由于将char *参数发送到cout,如ab,因此需要c样式的字符串。这也意味着每个字符串都需要零终止字符。因此,以下操作将起作用:

char a[5] = { 'A', 'B', 'C', 'D', '' };
cout << a + 1 << endl;
char b[6] = {'a', 'b', 'c', 'd', 'e', ''};
cout << b + 1 << endl;

发生在b上的情况是,通过定义所有5个字符来覆盖零个字符。0应该是第六个字符。

当您cout << a+1时,输出将是"BCD",因为'D'之后的字符是一个nul(
这是因为您指定了数组大小为5,但只给了它4个值。剩余的未指定值将设置为0。

当您cout << b+1时,您将得到"bcdeXXXX",它将一直持续到找到一个nul为止
(根据内存中的内容,XXX将是不可预测的字符。)

这是因为您指定了所有5个字符的值,而超出该值的内存是未定义的。它可能是nuls,也可能是早期程序遗留下来的随机值。没有办法确定。但是cout将继续打印,直到它遇到nul ,或者通过读取不可访问的存储器地址导致分段/访问违规。

这就是为什么在第二个输出中得到随机垃圾的原因

相关文章: