这个问题在这里已有答案:
我仍然试图进入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 ++说“是的,此流已启动并正在运行”。
(从技术上讲,重载的运算符产生的是void*
而不是bool
,但我现在会掩盖这个细节。)
请注意,现代版本的C ++(C ++ 11和转发版)不支持此行为,如果您尝试使用现代编译器执行此操作,则实际上会遇到编译器错误。如果可能的话,我建议升级你的编译器版本,这会给你一个错误,而不是生成不符合你的想法的代码。
在我的lapi和我使用CodeBlocks并获得输出
0x489944你好世界!
它正在发生,因为cout
是一个对象ostream
类,当你做的事情像
cout << " "<< endl << cout << "Hello world!" <<endl;
第一个cout
正在控制台屏幕上打印,第二个cout
被视为要打印的值以及“hello world”,这是第二个cout
打印的值。
所以基本上你从第二个cout
得到输出“Hello world”,你得到1或其他一些数值,然后在第一个cout
作为第二个cout
的参考地址打印。
在你的情况下,1作为cout
的参考地址打印在控制台上,这可能会使编译器与编译器不同。
对于大多数<<
操作,cout << x
(其中x
是“最”类型)返回cout
本身。
(这不是一个绝对的规则,你可以定义一些不正确的operator <<
;但通常是这种情况)
所以cout << " "<< endl << cout
被解析为((cout << " ") << endl) << cout
所以是这样的:
auto o1 = cout << " ";
auto o2 = o1 << endl;
auto o3 = o2 << cout;
所以第一个赋值(o1
)输出一个空格并返回cout
(实际上是对它的引用)。
(o2
)的第二个赋值输出行结束,刷新缓冲区,并返回cout
。
o3
的任务计算cout << cout
;
该运算符没有定义的重载。右cout
转换为bool
,净效果与输出1并返回cout << true
的cout
相同