为什么这个简单的程序会打印“1Hello World”?

Why is this simple program printing "1Hello World"?

我仍在尝试进入 C++,我已经编写了以下代码:

#include <iostream>
using namespace std;

int main()
{

    cout << " "<< endl << cout << "Hello world!" <<endl;

}

输出为:

1Hello world!

为什么Hello World前面有一个1?

编辑:我的程序可以编译,看来我的编译器版本很旧。

对您的问题的简短回答是,您用于输出数据的语法略有偏差。如果将一堆输出语句链接在一起,约定是将流放在最左边并且不重复。所以而不是写

cout << " " << endl << cout << "Hello world!" << endl;
                       ~~~~~~~

随便写

cout << " "<< endl << "Hello world!" << endl;

您在这里看到 1 的原因有点技术性。流类型都提供了一个重载运算符,您可以使用它来测试流是否有效。例如,你可以这样写:

if (cout) {
    // Everything is okay!
} else {
    // I don't know how you did it, but you broke cout and you can
    // no longer write anything to it!
}

(这通常用于 输入 流,但输出流也支持此)。由于此语法,如果您尝试将 cout 插入输出流,C++ 将首先尝试将 cout 转换为布尔值并打印该值。默认情况下,布尔值打印为 1(真)或 0(假),因此您看到的 1 是 C++ 表示 "yes, this stream is up and running."

(从技术上讲,重载运算符会生成 void* 而不是 bool,但我现在将忽略该细节。)

请注意,现代版本的 C++(C++11 及更高版本)不支持此行为,如果您尝试使用现代编译器执行此操作,实际上会出现编译器错误。如果可能的话,我会建议升级您的编译器版本,这会给您带来错误,而不是生成不符合您预期的代码。

在我的 lapi 中,我正在使用 CodeBlocks 并获得输出

0x489944Hello world!

发生这种情况是因为 cout 是一个对象 ostream class 并且当您正在执行类似

的操作时
cout << " "<< endl << cout << "Hello world!" <<endl;

第一个 cout 正在控制台屏幕上打印,第二个 cout 被视为要与 "hello world" 一起打印的值,后者是第二个要打印的值 cout.

所以基本上你从第二个 cout 得到输出 "Hello world" 并且你在 hello 之前得到 1 或一些其他数值,它被第一个 cout 打印为第二个参考地址cout.

在您的情况下,1 作为 cout 的参考地址打印在控制台上,这可能因编译器而异。

对于大多数 << 操作,cout << x(其中 x 属于 "most" 类型)returns cout 本身。

(这不是绝对规则,您可以定义一些 operator << 不正确的地方;但通常 是这种情况)

所以cout << " "<< endl << cout被解析为((cout << " ") << endl) << cout

So 等同于:

auto o1 = cout << " ";
auto o2 = o1 << endl;
auto o3 = o2 << cout;

所以第一个赋值(o1)输出一个space和return cout(实际上是对它的引用)。

(of o2) 的第二次赋值输出行尾,刷新缓冲区,并且 return cout.

o3 的赋值计算 cout << cout;

没有定义该运算符的重载。右边的cout转成一个bool,净效果和cout << true一样输出1和returns cout