cout 的流式输出与 endl
在上一节,我们讲到使用 cout 进行输出
cout << "Hello,World!" << endl;
但其实,可以不止输出一次
cout << "Hello,World!" << endl;
cout << "Hello,World!" << endl;
但要是我们需要输出很多不同的内容
cout << "There is no end though there is a start in space -- Infinity." << endl;
cout << "It has own power, it ruins, and it goes though there is a start also in the star -- Finite." << endl;
cout << "Only the person who has wisdom can read the most foolish one from the history." << endl;
cout << "The fish that lives in the sea doesn't know the world in the land. It also ruins and goes if they have wisdom." << endl;
cout << "It is funnier that man exceeds the speed of light than fish start living in the land." << endl;
cout << "It can be said that this is an ultimatum from the god to the people who can fight." << endl;
每输出一句就要多写一句 cout,这太烦人了!其实,cout 是一个字符输出流,它的全称可以是 Character OUTput stream,我们之前所做的其实就是通过流运算符(<< 或者接下来会讲到的 >>)将字符“送”到输出流而已,换句话说:我们其实在这样使用 cout:
cout << /* 第一个要输出的内容 */ << /* 第二个要输出的内容 */ << /* 省略 */;
我们可以把上面的代码写成这样:
cout << "There is no end though there is a start in space -- Infinity." << endl<< "It has own power, it ruins, and it goes though there is a start also in the star -- Finite." << endl<< "Only the person who has wisdom can read the most foolish one from the history." << endl<< "The fish that lives in the sea doesn't know the world in the land. It also ruins and goes if they have wisdom." << endl<< "It is funnier that man exceeds the speed of light than fish start living in the land." << endl<< "It can be said that this is an ultimatum from the god to the people who can fight." << endl;
你可能会问:前面几行的末尾不需要分号吗?其实这里并不需要,分号的作用是结束语句,而这里我们这几行其实都可以缩成一条语句,所以一定要理解概念
细心的你也许发现了,我们在每一行的末尾都加了 endl,现在解释一下:它是特别用于流的换行符,当 cout 接收到 endl 的时候,它会开启新的一行,并刷新缓存区(如果你现在还不清楚什么是缓存区,你可以暂时不理会缓存区这个概念)
使用 cin 输入
在这里先超纲一下,接下来我会使用到下面的语句:
int a;
它的作用就是定义一个叫做 a 的变量,这个变量可以存放整数。(如果你不知道什么是变量,可以先把它理解成为一个可以用来存东西的盒子。当然这个 a 可以被替换成其他内容,我们会在下一节讲变量的时候深入探究)
我们可以使用 cin 语句输入 a 的值,并使用 cout 输出出来。现在运行代码:
#include <iostream>
using namespace std;
int main() {int a;cin >> a;cout << a;cin >> a;return 0;
}
如果你在使用 Windows,可以直接双击生成的 exe 程序运行,这个时候你会发现它什么都没有输出——它在等你输入。你可以随便输入一个整数,然后按下回车。你会发现你输入的数字被原封不动地输出了!

这是为什么?因为我们在一开始调用了一次 cin,cin 将输入的整数放进了变量 a。然后我们又调用了 cout 输出了一遍!
cin >> a;
cout << a;
cin >> a;
你也许发现我在之后又调用了一次 cin,我这样做的原因让程序变成输入状态,这个时候它会等待你输入,这样你就可以进行观察(不然它就会一闪而过以至于你无法看到输出了什么)
和 cout 类似,cin 其实代指字符输入流,全称 Character INput stream, 你应该像这样使用 cin:
cin >> /*第一个输入的内容*/ >> /*第二个输出的内容*/ >> /* ...省略... */;
流操作符
虽然我们还没正式开始讲操作符,但我还是需要先告知你这两个我们现在接触到的两个操作符:
>>流输入运算符,用于与诸如cin等输入流搭配使用<<流输出运算符,一般与诸如cout等输出流搭配使用
记忆它们很简单,看它们的箭头朝向就知道数据要“流”向哪里。例如 cout << "aaa"; 箭头朝向 cout 所以最后会输出,而 cin >> a; 最后是从 cin 流向外面,所以是输入。
补充:printf 和 scanf
这里只是为了教程的完整性而进行的补充
也许你在其他 C++ 教程里见过另一个版本的 HelloWorld
#include <cstdio> // 或者是 #include <stdio.h>
using namespace std;
int main() {printf("Hello,World!\n");return 0;
}
这其实是为了兼容 C 语言的写法,C 语言使用 printf 和 scanf 进行输入输出,它们并不是流, 你不能在这里使用 endl。我们会在之后对其进行补充说明,你大可不必担心这个教程会缺斤少两。默认情况下,cout cin 需要和它们进行同步(你没听错,其实 cout 和 printf 可以混搭,但不建议这么使用),这就导致了 cout 和 cin 的执行效率比它们慢,这就导致了某些人倾向于使用 printf 和 scanf 而不是 cin 和 cout,不过你可以不让它们的同步:
ios::sync_with_stdio(false);
你可以上网搜索到更多信息, 不过你要是学过如何使用 printf 和 scanf 也没关系——毕竟用哪个都可以
总结
cout是字符输出流,使用<<流操作符进行输出cin是字符输入流,使用>>流操作符进行输入endl是换行,仅可用于cout和cinprintf和scanf分别是 C 语言风格的输入输出,默认情况下cout和cin会与它们进行同步,使用ios::sync_with_stdio(false)关闭两者的同步- 下面的语句可以定义一个整型变量(存放整数的变量),它的变量名叫做
a:
int a;
变量的内容将在下一节涉及
练习
Debug
下面这段代码哪里出错了?
#include <iostream>
using namespace std;
int main() {cout << "Hello,World";<< endl;return 0;
}
查看答案
"Hello,World!" 后面多了一个分号,这个分号导致语句提前结束了。把它去掉就能正常工作了
#include <iostream>
using namespace std;
int main() {cout << "Hello,World"<< endl;return 0;
}
输入输出练习
编写程序,要求给出提示要求用户输入一个整数,然后把它原封不动地输出三次,就像这样:
输入一个整数:114514
你输入了114514
你输入了114514
你输入了114514
重要的事情说三遍
查看答案
#include <iostream>
using namespace std;
int main() {int num;cout << "输入一个整数:";cin >> num;cout << "你输入了" << num << endl<< "你输入了" << num << endl<< "你输入了" << num << endl<< "重要的事情说三遍" << endl;return 0;
}
Debug 2
这段代码这样写有没有问题?这会导致什么?(你可以复制这段代码并运行)
#include <iostream>
using namespace std;
int main() {ios::sync_with_stdio(false);cout << "Hello,";printf("World!");cout << endl;printf("Hello,");cout << "World!" << endl;return 0;
}
查看答案
先说问题:它在使用 ios::sync_with_stdio(false) 后混用了 cout 和 printf。 这会导致一个未定义行为(UB, Undefined Behavior)
什么是未定义行为?举个例子:你买了一个挖掘机,它应该被用来挖地,而你却试图用它来梳头发,站在挖掘机生产厂商的角度看,我应该在说明书上注明你应该怎样拿它梳头发吗?那肯定是不——因为拿挖掘机梳头发的人简直就是神经病或者说有点SM癖好
回到这里,你使用了 ios::sync_with_stdio(false) 关闭了 cout cin 和 printf scanf 的同步,然后你用混用它们你是不是故意找茬,C++ 标准的制定者没必要定义这会导致什么——毕竟你关闭了它们的同步,再混用,后果自负。所以具体会发生什么谁也不知道(实际上这里的混用往往会导致输出乱序)
实际上 C++ 标准定义了什么是未定义行为,为什么要这样?因为定义某些行为为未定义行为,可以给予一些编译器优化的自由。
未定义行为我们会在后面专门进行讨论
