这个C ++程序会发生什么?

时间:2015-09-23 14:31:10

标签: c++ cout pointer-arithmetic

考虑以下计划:

#include <iostream>
int main()
{
    int num=345;
    std::cout<<"num " + num<<'\n';
}

当我运行此程序时,它显示F作为输出。怎么样?是否在这里执行指针运算?如果我使用 - 符号而不是+,则会出现空白输出。

3 个答案:

答案 0 :(得分:14)

字符串文字"num "const char[5],它会衰减到您要添加偏移量的const char*

以下代码相当于您正在做的事情:

#include <iostream>
int main()
{
    int num = 345;
    const char* c_str = "num ";
    std::cout << c_str + num << '\n';
}

A:您有未定义的行为,因为您正在访问数组范围之外的内存位置。你违反了记忆安全。

由于cout只有在找到'\0&#39;对于c-strings,你可以继续打印直到它。您无法知道该值何时会发生,因此您有未定义的行为,如 A 中所述。

答案 1 :(得分:7)

假设你有"num"字符串。在内存中它可能看起来像,

 0  1  2  3  4
[n][u][m][ ][\0]

打印时,它将用作指针。现在你为它添加了一个345的偏移量。

 0  1  2  3  4   5  6  7     345
[n][u][m][ ][\0][?][?][?]....[F][?][?]

您的程序可能打印的不仅仅是F,它会在找到的第一个\0上停止。这是未定义的行为,因为您的程序可以打印任何内容,并将访问无效的内存地址。

如果您的目标是打印整数,那么您可以编写

std::cout << "num" << num << std::endl;

答案 2 :(得分:6)

编译所有警告非常有益:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:6:25: warning: array subscript is above array bounds [-Warray-bounds]
     std::cout<<"num " + num<<'\n';

                         ^

请参阅here

基本上编译器告诉你,你已经在存储"num "的底层数组上完成了指针算术。实质上"num "是一个数组,用于存储该字符串文字所需的字符。当你对它进行算术运算时,它衰减到const char*,然后你将指针地址加345。此内存地址位于已定义的数组之外,而您的特定计算机上这个值恰好是值F。然而,这是未定义的行为,输出可能完全在另一台机器上。

这些编译器警告通常是错误的结果,所以注意编译器告诉你的内容通常很有价值。