共计 6063 个字符,预计需要花费 16 分钟才能阅读完成。
小引
上期 ,我们探讨了Hello World 程序,还记得 代码 吗?
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "Hello World";
return 0;
}
今天的故事,要从这一则对话开始……
“操作系统小姐,这个程序是怎么处理用户的 输入 的呀?”
“嗯……在这个常见的 C++ 程序里,输入的处理一般是用 cout
的反义:cin
”
“那……具体是怎么处理的捏?(。・ω・。)”
初学 cin
首先,允许我放上今天的一小段代码:
#include <bits/stdc++.h>
using namespace std;
int a;
int main() {
cin >> a;
cout << a;
return 0;
}
首先呢,我们看到了两个 神奇的地方:
- 1、
int a
- 2、
cin >> a
关于int a
这个代码做什么还记得吧?(不会这都不记得了吧?⊂(~(エ)~)⊃)定义一个 整数变量 ,名字叫a
,古怪的地方在于 它写在函数外面啊!
“操作系统小姐,为什么变量的定义能写在 函数外面 啊?”
“是可以的呀~而且这么做更加 规范一点 呢,你看啊,代码看起来就 顺眼多了 ,而且 编译器小姐 看到这样写,会帮你把定义在函数外面的变量 自动初始化成 0 哦~”
“那其他语句能写在外面吗?”
“你试试?(^(エ)^)”
#include <bits/stdc++.h>
using namespace std;
cout << "Hello World";
int main() {
return 0;
}
“编译器小姐,帮我编译看看~”
test.cpp:6:1: error: unknown type name 'cout'
6 | cout << "Hello World";
| ^
test.cpp:6:6: error: expected unqualified-id
6 | cout << "Hello World";
| ^
2 errors generated.
你看,这不就被打回来了?(操作系统小姐真会坑人ヾ (T(エ)T ヽ))如果有兴趣的话,可以去 翻译一下报错信息,简而言之,就是:
“我已经收到程序啦,现在开始编译……”
“写在外面的语句呢……那就当变量定义解析好了,哎?这个名为 cout
的变量类型 怎么没见过呢 ,这个<<
又是什么?这真的是变量定义吗?肯定是搞错了。打回去,重来。꒰。•`ェ´•。꒱۶(随手拿起另一份程序继续工作)”
除了这个,还有一点:定义在 函数
外面的 变量
会被自动初始化成 0
,换句话说, 定义在 函数
里的 变量
不会被自动初始化成 0
,在写程序的时候要 注意 哦。不然,你的变量里就是一个 随机值。

小秘密:实践是最好的老师,不要害怕代码报错。
关于cin
>> a
这就是今天的 重头戏 之一了:输入
。
总体来说,非常简单 ,举个例子:用户输入1 2 3
时,我们使用代码(省略了 代码格式和变量定义):
cin >> a >> b >> c;
就可以把 1
存到 a
里,把 2
存到 b
里,把 3
存到 c
里,至于 <<
嘛……都看懂 cout
的>>
了,难道还不懂吗?不就是表示 值的传递方向 嘛。你总不能强行从 a
、b
、c
那里 抢过来给 cin
吧,总是 让a
、b
、c
去接受 cin
里的东西嘛……
当然,这是 单行输入,那多行呢?比如:
1
2
3
很简单,还是:cin >> a >> b >> c;
。
由此可见,C++ 中 cin
分割用户输入数据的方式是 空格
和 换行
。
那让我们来写一个 A+B Problem 吧。
#include <bits/stdc++.h>
using namespace std;
int a, b;
int main() {
cin >> a >> b;
cout << a + b;
return 0;
}
但是……有的题目输入格式 很狡猾,是这样的:
输入格式:
共 n+1 行,第一行,一个整数 n,表示接下来输入的整数个数。
接下来 n 行,每行一个整数 $a1,a2,⋯,a_n$,表示需要四舍五入的整数。
那么肯定先是:cin >> n;
(我定义变量 没写 哦),那接下来呢?接下来,有请:
循环结构
程序总会处理 大量的重复任务 ,比如: 输入 100 个数,求和
。怎么办?手打 100 个cin?
操作系统小姐:“真有人这么傻?”
#include <bits/stdc++.h>
using namespace std;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76, a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91, a92, a93, a94, a95, a96, a97, a98, a99, a100;
int main() {
cin >> a1 >> a2 >> a3 >> a4 >> a5 >> a6 >> a7 >> a8 >> a9 >> a10 >> a11 >> a12 >> a13 >> a14 >> a15 >> a16 >> a17 >> a18 >> a19 >> a20 >> a21 >> a22 >> a23 >> a24 >> a25 >> a26 >> a27 >> a28 >> a29 >> a30 >> a31 >> a32 >> a33 >> a34 >> a35 >> a36 >> a37 >> a38 >> a39 >> a40 >> a41 >> a42 >> a43 >> a44 >> a45 >> a46 >> a47 >> a48 >> a49 >> a50 >> a51 >> a52 >> a53 >> a54 >> a55 >> a56 >> a57 >> a58 >> a59 >> a60 >> a61 >> a62 >> a63 >> a64 >> a65 >> a66 >> a67 >> a68 >> a69 >> a70 >> a71 >> a72 >> a73 >> a74 >> a75 >> a76 >> a77 >> a78 >> a79 >> a80 >> a81 >> a82 >> a83 >> a84 >> a85 >> a86 >> a87 >> a88 >> a89 >> a90 >> a91 >> a92 >> a93 >> a94 >> a95 >> a96 >> a97 >> a98 >> a99 >> a100;
cout << a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50 + a51 + a52 + a53 + a54 + a55 + a56 + a57 + a58 + a59 + a60 + a61 + a62 + a63 + a64 + a65 + a66 + a67 + a68 + a69 + a70 + a71 + a72 + a73 + a74 + a75 + a76 + a77 + a78 + a79 + a80 + a81 + a82 + a83 + a84 + a85 + a86 + a87 + a88 + a89 + a90 + a91 + a92 + a93 + a94 + a95 + a96 + a97 + a98 + a99 + a100;
return 0;
}
操作系统小姐:“好吧,看来是我高估写这篇教程的人了。”
喂!我这是演示,演示 好嘛?(气呼呼)
操作系统小姐:“我懂的,我懂的,掩饰,掩饰……”
哼,这家伙说话怎么奇奇怪怪的?算了,不管啦,我们继续上课。要方便一点,我们就要先弄懂 while 循环
。
While 循环
while 循环
的结构非常简单,例如:
while ( 条件 ) {
语句
}
条件 是什么哩?当每一次执行 whileu 循环里面的语句 之前 ,操作系统小姐会先帮你 检查一遍条件是否成立 ,一旦不成立,就会 跳出循环,也就是直接从:
while ( 条件 ) {
语句 1 <-- 执行到这里,执行完了,判断条件,发现不成立
}
语句 2
到:
while ( 条件 ) {
语句 1
}
语句 2 <-- 执行到这里
懂了吗?比如:
int a = 1;
while (a <= 100) {
cout << a << endl; // 我是注释妹妹哦,不会被执行的,我来解释一下程序姐姐里这行里的 endl 是输出换行的意思哦
a++;
}
cout << "我搞定啦!";
这段代码,首先定义了变量 a
为 1,然后进入 while 循环,先判断一遍条件成不成立,嗯……1 <= 100,成立!(不要管 1 不可能等于 100
,你就说1 <= 100
对不对嘛),执行:输出 1(变量 a)和换行,把 a 加上 1,变成了2
。
接下来就是枯燥的 重复过程 了,那么当 a = 101
的时候:
“操作系统小姐!我想执行 cout << 101 << endl;
了,i 你看看行不行?”
“不可以哦,101 > 100 啦,不满足条件呢,直接 跳出 while 循环 吧。”
于是,程序在输出了 100
后,不会输出 101
了,而是执行:cout << "我搞定啦!";
,那么输出就长这样:
1
2
3
4
5
... 这里实在太多啦!我就省略了(呼呼)(^_^)
100
我搞定啦!
懂了?但……这么写有点 烦不是吗?
“主播主播,你的 while 循环
虽然很 好用 ,但还是太吃操作了,有没有 更简单又强势 的代码呢?”
“有的兄弟,有的。那就是……”
For 循环
经过了一些困难,我们发现我们的 while 循环可以拆成三部分:
- 开始前的初始化语句,即
int a = 1;
- 条件,即
a <= 100
- 执行的东西,也就是大括号里的一堆
如何更简单?For 循环
!
for (int a = 1; a <= 100;) {
cout << a << endl;
a++;
}
cout << "我搞定啦!";
这段代码和上面的的运行效果是 一模一样 的,所以 For 循环
的改进点只是我们能吧 初始化语句 也放进括号里?还要多加;
?
“喂!别这么看不起人家好吗?我还可以这样:for (int a = 1; a <= 100; a++)
”
是的,你可以吧 一条单独的语句
(通常是 关于条件里变量的改变语句 ,又称 迭代语句 )也写进 括号 里,但是要注意顺序。那么问题来了:
什么是 单独的语句?
定义是这样的:凡是 C++
里能写在 同一个分号前 的,都是单独的语句。比如:int a = 1;
就是单独的语句,int a = 1; a++;
就不是。那么 a++, b++;
是吗?写在一个分号里呀,当然 是的 !简而言之,就是这个语句里只有一个会被执行的;
,当然, 字符串里不被当作语句执行的 当然不能算这样的 ;
,如:string a = ";";
也是一条 单独的语句。
反推一下,int a = 1;
所在的地方,不也就是 一条单独的语句吗?,那我这么写可以吗:int a = 1, b = 2;
当然可以!不信你 自己试试?
总结一下,For 循环
的结构:
for ( 初始化语句(在 For 循环开始前执行)(单独的语句); 条件语句; 迭代语句(单独的语句)) {
语句
}
应用
那么对于一开始的输入问题有头绪了吗?(不管程序逻辑)
int n;
cin >> n;
while (n > 0) { // n 会从输入的值变到 1 为止(当 n = 0 时就不会执行),也就是循环 n 次
int tmp;
cin >> tmp;
n--;
}
亦可:
int n;
cin >> n;
while (n--) { // n-- 是先返回 n 的值,再把 n 减一,比如 n =3,n-- 就会返回 3,然后把 n 的值改为 2,所以当 n = 0 时就不会执行,n 的值还是 n~1,也就是循环 n 次
int tmp;
cin >> tmp;
}
还可:
int n;
cin >> n;
for (int i=1; i <= n; i++) { // i 的取值范围为 1~n,也就是循环 n 次
int tmp;
cin >> tmp;
}
可见,For 循环
和While 循环
是可以 互相转换 的。(代码多样性(=`ω´=))
分支结构
刚才有一个词被反复提及,你们注意到了吗?那就是————当……时
,简而言之,就是 判断
。
很明显,程序的运行会用到 判断,不然我们写什么程序?怎么用呢?
if ( 条件 ) {
语句
}
这个就是分支结构,也是 C++
中的 判断语句 ,意思是:如果 条件
成立,那么 执行 语句
,否则 跳过 括号里的语句
。
举例:
if (3 > 2) {
cout << "好!";
}
cout << "嗯!";
结果为:
好!嗯!
if (2 >= 9) {
cout << "好!";
}
cout << "嗯!";
结果为:
嗯!
懂了?那么上强度!
for (int i=1; i <= 10; i++) {
if (i > 9) {
cout << i;
}
else {
cout << "";
}
}
输出什么?首先,i 的范围是 1~10
,也就是 遍历 1~10
的整数 ,如果一个数 大于 9 ,那么就输出它。else
是否则 ,也就是如果 不满足条件 ,就执行 否则
里面的东西,而这个否则里输出的东西是一个 空的字符串,等于不输出。那么很明显,程序输出:
10
一些碎碎念
搞定啦,讲完了?其实还有一些琐事想 念叨 ,就是,嗯……不要 折磨自己的眼睛,怎么说呢?有人的代码长这样:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
if (n == 1)
{
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
for(int i=1;i <10; i++)
{
cout << i << " ";
}
}
别的不说,隔着屏幕我都觉得 混乱,这就是代码可读性的定义了,如果上面的代码长下面这样:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
if (n == 1) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
for (int i=1; i < 10; i++) {
cout << i << " ";
}
return 0;
}
这不是瞬间 好懂多了 ?所以, 养成自己的码风(代码风格)很重要,起码要让自己看得舒服,不然要是程序输出的不正确,恐怕就会出现下面的对话:
“操作系统小姐,我的程序到底错在哪儿啊?为什么我看不出来?”
“我也看不出来啊”
“编译器小姐,来救救我吧……”
“我救不了你,我还得专心工作呢。”(真是个 工作狂)
但是,这种情况也不是完全没有整治的方法,前人早就想到了,就有了一种工具:代码格式化工具 ,我们大家普遍用的编辑器Dev-cpp
有内置 ,只不过用起来有些麻烦,具体看 这篇文章。
还有,要养成 写代码的思路 ,要学会 拆解问题,比如这个问题我可以先输入什么,对于这样的单个输入,我可以怎么处理,处理完后怎么办,全都处理完后怎么办,最后处理什么,输出什么……
关于自己在 家里 写代码,需要一个 代码编辑器 (比如Dev-cpp
这种),这样的编辑器其实 很多 ,出名的有:VSCode
、Jetbrains IDE
、Dev-cpp
……选择的关键其实在于 用着数不舒服 、 功能吸不吸引你 ,像我使用的是VSCode
和Nvim
,就是看中了 代码补全 、 高度自定义 和快捷键 操作。但这并不代表适合所有人,因为 各有缺点 ,VSCode
需要占用 较大存储空间 ,Nvim
配置起来 很麻烦,并不是所有人都能接受。
结语
本章到这里也就 结束 了,接下来我们要讲的就是:存储数据
!让我们,下期再见,拜拜~(ノ◕ヮ◕)ノ*:・゚✧