第四课 C++变量、表达式和运算符
——CSP-J程序阅读的第一关:看懂计算机到底在算什么
这一课非常重要。
因为 CSP-J 初赛里题目并不是让同学们“写程序”,而是给同学们一段程序:
然后问:
最后输出什么?
需要掌握:
计算机到底按照什么顺序执行?变量里面现在装的到底是什么?
所以这一课我们的目标不是背语法,而是建立一个最重要的能力:
看到 C++ 代码 → 能在脑子里模拟计算机的执行过程。
一、这一课到底要学什么?
本课分成8个知识模块:
什么是变量
什么是变量的值和地址
C++基本数据类型
常量
算术运算符
关系运算符
逻辑运算符
赋值、自增、自减和运算优先级
最后再进行:
CSP-J程序阅读专项训练
二、第一关:变量到底是什么?
先给孩子讲一个故事。
假设老师给每个同学一个盒子。
盒子上写着名字:
小明的盒子 小红的盒子 小刚的盒子盒子里面可以放东西。
比如:
小明的盒子 → 10 小红的盒子 → 20C++里的变量,就非常像这样的“盒子”。
1. 定义一个变量
int a;这句话是什么意思?
可以这样理解:
请计算机准备一个名字叫 a 的整数盒子。
此时:
a ┌───────┐ │ ??? │ └───────┘注意:
int是什么?
int是一种数据类型。
意思是:
这个盒子准备拿来存整数。
a是什么?
a是变量名。
所以:
int a;可以理解成:
建立一个名叫
a的整数变量。
三、给变量装东西
int a; a = 10;现在:
a ┌───────┐ │ 10 │ └───────┘这里:
a = 10;不是数学里面的:
a 等于 10
而应该理解成:
把 10 放进 a 这个盒子里。
这是C++初学者必须建立的概念。
四、C++里的=到底是什么?
这是 CSP-J 程序阅读的重点之一。
看到:
a = 10;一定不要读成:
a 等于 10
应该读成:
把右边计算出来的结果,放到左边。
所以:
a = 10;是:
10 ↓ ┌─────────────┐ │ a │ │ 10 │ └─────────────┘五、最重要的一个例子
看:
int a = 10; a = 20;第一次:
a → 10第二次:
a → 20所以最后:
a = 20六、变量最大的特点:它可以改变
例如:
int x = 5; x = 8; x = 20;变量x经历了:
5 → 8 → 20因此:
变量不是“永远不变的数字”,而是一个可以不断改变内容的盒子。
七、程序阅读最重要的工具:变量状态表
以后遇到这种题:
int a = 3; int b = 5; a = a + b; b = a + b;不要直接在脑子里面乱算。
我们画表。
| 步骤 | a | b |
|---|---|---|
| 开始 | 3 | 5 |
a=a+b | 8 | 5 |
b=a+b | 8 | 13 |
最后:
a = 8 b = 13这就是以后 CSP-J 程序阅读最重要的武器之一:
变量状态表
八、为什么a=a+1没有问题?
初学者第一次看到:
a = a + 1;经常会说:
“老师,这不可能啊!a怎么会等于a+1?”
因为孩子把它当成数学等式了。
其实 C++ 是:
先计算右边,再把结果放进左边。
假设:
a = 5;执行:
a = a + 1;先算右边:
a + 1 = 5 + 1 = 6然后:
a ← 6所以:
5 → 6九、一个非常重要的思维
以后看到:
a = a + 10;要自动翻译成:
a增加10。
看到:
a = a - 10;翻译成:
a减少10。
看到:
a = a * 2;翻译成:
a变成原来的2倍。
看到:
a = a / 2;翻译成:
a除以2。
十、C++最常见的数据类型
初赛程序阅读中首先要认识这些。
1.int
整数。
int age = 10;例如:
-100 0 1 20 10002.long long
用于存更大的整数。
long long x = 10000000000LL;初赛中看到:
long long首先知道:
它也是整数,只是能表示更大的范围。
3.double
小数。
double x = 3.14;例如:
3.14 0.5 -2.754.char
单个字符。
char c = 'A';注意:
'A'是字符。
而:
"A"是字符串。
这一点以后会专门讲。
5.bool
只有两个值:
true false也就是:
真 假十一、变量类型一定要记住
同学们记成:
| 类型 | 用来装什么 |
|---|---|
int | 整数 |
long long | 大整数 |
double | 小数 |
char | 一个字符 |
bool | 真/假 |
十二、运算符是什么?
运算符可以理解成:
告诉计算机“怎么计算”的符号。
例如:
+ - * / %就是最基本的算术运算符。
十三、加法+
int a = 3; int b = 5; int c = a + b;执行:
a = 3 b = 5 c = 3 + 5 = 8所以:
c = 8十四、减法-
int a = 10; int b = 3; int c = a - b;结果:
c = 7十五、乘法*
注意:
C++里乘法不是×。
而是:
*例如:
int a = 6; int b = 7; int c = a * b;结果:
42十六、除法/
这是 CSP-J 非常重要的考点。
看:
int a = 7; int b = 2; cout << a / b;有的同学会说:
3.5
错!
因为:
a b都是int。
所以:
7 / 2进行的是整数除法。
结果:
3小数部分被舍去。
十七、整数除法是初赛高频考核点
例如:
cout << 10 / 3;输出:
3cout << 20 / 6;输出:
3cout << 100 / 9;输出:
11所以:
两个整数相除,结果仍然是整数除法。
十八、余数%
%是:
取模 / 求余数
例如:
7 % 3因为:
7 = 3 × 2 + 1所以:
7 % 3 = 1再看几个
10 % 3 = 1 10 % 2 = 0 15 % 4 = 3 20 % 6 = 2十九、为什么%特别重要?
因为 CSP-J 初赛题目非常喜欢考核%。
例如:
int n = 12345; cout << n % 10;答案:
5因为:
12345 ÷ 10 余数5所以:
%10可以得到一个整数的个位数字。
再看:
n / 10对于整数n:
可以去掉个位。
例如:
12345 / 10 = 123于是:
n % 10和:
n / 10就成为以后处理数字非常重要的工具。
二十、一个经典程序:拆数字
int n = 12345; while(n > 0) { cout << n % 10; n = n / 10; }孩子可以手算:
| n | n%10 | n/10 |
|---|---|---|
| 12345 | 5 | 1234 |
| 1234 | 4 | 123 |
| 123 | 3 | 12 |
| 12 | 2 | 1 |
| 1 | 1 | 0 |
输出:
54321这就是一个经常考察的程序阅读题。
二十一、关系运算符
接下来进入第二大类运算符:
> < >= <= == !=它们的作用是:
比较两个东西的大小或者是否相等。
二十二、>大于
5 > 3结果:
true因为:
5比3大二十三、<小于
5 < 3结果:
false二十四、>=大于等于
5 >= 5结果:
true因为“等于”也算。
二十五、<=小于等于
5 <= 5也是:
true二十六、最容易错的:==
看:
a == b这是:
判断 a 和 b 是否相等。
而:
a = b是:
把 b 的值放进 a。
这两个一定不能混。
| 写法 | 含义 |
|---|---|
= | 赋值 |
== | 判断相等 |
这是 CSP-J 初赛的经典陷阱。
二十七、!=
a != b意思:
a 不等于 b。
例如:
5 != 3结果:
true而:
5 != 5结果:
false二十八、逻辑运算符
三个最重要:
&& || !可以把它们记成:
&& 并且 || 或者 ! 不是二十九、&&:并且
例如:
age >= 6 && age <= 12意思:
年龄大于等于6,并且年龄小于等于12。
两个条件必须同时成立。
真值表
| A | B | A&&B |
|---|---|---|
| 假 | 假 | 假 |
| 假 | 真 | 假 |
| 真 | 假 | 假 |
| 真 | 真 | 真 |
所以:
&&:全真才真。
三十、||:或者
例如:
x == 0 || y == 0意思:
x等于0,或者y等于0。
只要一个成立就可以。
| A | B | A||B |
|---|---|---|
| 假 | 假 | 假 |
| 假 | 真 | 真 |
| 真 | 假 | 真 |
| 真 | 真 | 真 |
记忆:
||:一个真就真。
三十一、!:逻辑非
!true结果:
false!false结果:
true就是:
把真假翻转。
三十二、把三个放到一起
例如:
int x = 8; cout << (x > 5 && x < 10);判断:
8 > 5 → true 8 < 10 → true所以:
true && true结果:
true三十三、C++中bool输出的一个注意点
例如:
bool a = true; cout << a;默认情况下通常输出:
1而:
bool a = false; cout << a;输出:
0所以程序阅读中如果看到:
cout << (5 > 3);一般会输出:
1而不是单词true。
三十四、自增++
这是程序阅读题的重点。
a++;意思:
a增加1。
例如:
int a = 5; a++;最后:
a = 6三十五、自减--
a--;意思:
a减少1。
例如:
int a = 5; a--;结果:
a = 4三十六、区分:a++和++a
这两个看起来很像:
a++和:
++a但在表达式中有区别。
a++
叫:
后置自增
意思:
先使用旧值,再加1。
例如:
int a = 5; int b = a++;执行:
b = 5 a = 6++a
叫:
前置自增
意思:
先加1,再使用新值。
例如:
int a = 5; int b = ++a;执行:
a = 6 b = 6三十七、用“取票”来理解
假设a=5。
b=a++
就像:
先把“5号票”给 b,
然后 a 变成6。
所以:
b=5 a=6b=++a
则像:
先把号码加到6,
再把6给 b。
所以:
a=6 b=6三十八、这是初赛必须会的
例如:
int a = 3; int b = a++; cout << a << " " << b;执行:
a=3 b=a++ ↓ b=3 a=4所以:
4 3再看:
int a = 3; int b = ++a; cout << a << " " << b;结果:
4 4三十九、赋值运算符
除了:
=还有:
+= -= *= /= %=例如:
a += 5;等价于:
a = a + 5;a -= 5;等价于:
a = a - 5;a *= 5;等价于:
a = a * 5;a /= 5;等价于:
a = a / 5;a %= 5;等价于:
a = a % 5;四十、运算符优先级
例如:
int x = 2 + 3 * 4;到底是多少?
不是:
(2+3)*4 =20而是:
2 + (3*4) =14因为:
乘除优先于加减。
四十一、建议孩子记住的基本优先级
先记这几个就够了:
() ↓ ++ -- ↓ * / % ↓ + - ↓ < <= > >= ↓ == != ↓ && ↓ || ↓ = += -= *= /=可以简单记成:
括号 → 自增 → 乘除模 → 加减 → 比较 → 逻辑 → 赋值
四十二、为什么一定要学括号?
因为:
a + b * c和:
(a + b) * c可能完全不同。
所以考试中如果不确定:
自己加括号!
例如:
a = b + c * d;可以在草稿纸上写成:
a = b + (c * d);马上清楚。
四十三、综合例题1:变量 + 运算符
看程序:
int a = 5; int b = 3; a = a + b; b = a - b; cout << a << " " << b;我们建立状态表:
| 执行 | a | b |
|---|---|---|
| 初始 | 5 | 3 |
a=a+b | 8 | 3 |
b=a-b | 8 | 5 |
所以:
8 5这个程序实际上完成了:
不借助第三个变量交换两个数。
四十四、综合例题2:整数除法 + 余数
int a = 17; cout << a / 5 << " "; cout << a % 5;因为:
17 = 5×3 + 2所以:
3 2四十五、综合例题3:优先级
int a = 3; int b = 4; int c = 5; int x = a + b * c;先:
b*c = 20再:
a+20 = 23所以:
x = 23四十六、综合例题4:逻辑运算
int x = 7; bool a = x > 5; bool b = x < 10; bool c = a && b;计算:
a = true b = true c = true所以:
c = true四十七、综合例题5:程序阅读
现在来一道真正的 CSP-J 风格小题。
int a = 2; int b = 3; int c = 4; a++; b = a * 2; c = b + a; a = c % 5; cout << a << " " << b << " " << c;不要急着算。
建立表格。
| 操作 | a | b | c |
|---|---|---|---|
| 初始 | 2 | 3 | 4 |
a++ | 3 | 3 | 4 |
b=a*2 | 3 | 6 | 4 |
c=b+a | 3 | 6 | 9 |
a=c%5 | 4 | 6 | 9 |
答案:
4 6 9四十八、程序阅读的黄金法则
从今天开始,给孩子建立这五条规则:
规则1:不要凭感觉看程序
一定要:
一步一步执行。
规则2:遇到变量就记录
例如:
int a,b,c;马上在草稿纸上:
a= b= c=规则3:看到赋值,先算右边
例如:
a = b + c * 2;先算:
b+c*2再把结果放到:
a规则4:看到%一定停一下
问自己:
这里是在求余数吗?
规则5:看到++,问自己
这是前置还是后置?
四十九、这一课容易错的10个地方
| 易错点 | 正确理解 |
|---|---|
= | 赋值 |
== | 判断相等 |
a=a+1 | a增加1 |
/ | 整数相除时取整数部分 |
% | 求余数 |
a++ | 先使用,再加1 |
++a | 先加1,再使用 |
&& | 并且 |
| || | 或 |
! | 否 |
五十、CSP-J初赛必须掌握的“运算符地图”
最后建议同学们把下面这张表掌握。
C++运算符 │ ├── 算术 │ ├── + │ ├── - │ ├── * │ ├── / │ └── % │ ├── 关系 │ ├── > │ ├── < │ ├── >= │ ├── <= │ ├── == │ └── != │ ├── 逻辑 │ ├── && │ ├── || │ └── ! │ ├── 自增自减 │ ├── ++ │ └── -- │ └── 赋值 ├── = ├── += ├── -= ├── *= ├── /= └── %=五十一、课后练习:第一组——基础计算
题1
int a = 10; int b = 3; cout << a / b << " "; cout << a % b;输出什么?
题2
int a = 5; a = a + 3; a = a * 2; a = a - 4;最后a是多少?
题3
int a = 5; int b = a++; cout << a << " " << b;输出什么?
题4
int a = 5; int b = ++a; cout << a << " " << b;输出什么?
题5
int x = 3 + 4 * 5;x是多少?
五十二、第二组——程序阅读
题6
int a = 7; int b = 4; a = a + b; b = a - b; a = a - b; cout << a << " " << b;输出什么?
题7
int n = 123; int a = n % 10; n = n / 10; int b = n % 10; cout << a << " " << b;输出什么?
题8
int a = 2; int b = 5; bool x = a < b; bool y = a == b; bool z = x && !y; cout << z;输出什么?
五十三、第三组——CSP-J综合
题9
int a = 3; int b = 4; int c = 5; a = b++; c = ++a; b = c % 3; cout << a << " " << b << " " << c;要求:
不要直接心算,必须画变量状态表。
题10
int n = 2026; int a = n % 10; n /= 10; int b = n % 10; n /= 10; int c = n % 10; cout << a + b + c;问:
程序输出什么?
五十四、这一课要达到的目标
这一课最重要的是培养三个能力:
第一能力:认识变量
看到:
int x = 10;脑子里马上出现:
x → 10第二能力:理解表达式
看到:
x = a + b * 2;能够自动翻译成:
先算 b×2 再加 a 最后放进 x第三能力:模拟程序
看到:
a++; b = a * 2; c = b % 3;能够在纸上画:
a b c 开始 5 2 0 a++ 6 2 0 b=a*2 6 12 0 c=b%3 6 12 0这三个能力建立起来之后,下一课“条件、循环与程序模拟”就会顺畅很多。