为什么这个简单的程序会打印“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
我仍在尝试进入 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