
第四课 C++变量、表达式和运算符
------CSP-J程序阅读的第一关:看懂计算机到底在算什么
这一课非常重要。
因为 CSP-J 初赛里题目并不是让同学们"写程序",而是给同学们一段程序:
然后问:
最后输出什么?
需要掌握:
计算机到底按照什么顺序执行?变量里面现在装的到底是什么?
所以这一课我们的目标不是背语法,而是建立一个最重要的能力:
看到 C++ 代码 → 能在脑子里模拟计算机的执行过程。
一、这一课到底要学什么?
本课分成 8个知识模块:
-
什么是变量
-
什么是变量的值和地址
-
C++基本数据类型
-
常量
-
算术运算符
-
关系运算符
-
逻辑运算符
-
赋值、自增、自减和运算优先级
最后再进行:
CSP-J程序阅读专项训练
二、第一关:变量到底是什么?
先给孩子讲一个故事。
假设老师给每个同学一个盒子。
盒子上写着名字:
小明的盒子
小红的盒子
小刚的盒子
盒子里面可以放东西。
比如:
小明的盒子 → 10
小红的盒子 → 20
C++里的变量,就非常像这样的"盒子"。
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
1000
2. long long
用于存更大的整数。
long long x = 10000000000LL;
初赛中看到:
long long
首先知道:
它也是整数,只是能表示更大的范围。
3. double
小数。
double x = 3.14;
例如:
3.14
0.5
-2.75
4. 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;
输出:
3
cout << 20 / 6;
输出:
3
cout << 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=6
b=++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
这三个能力建立起来之后,下一课"条件、循环与程序模拟"就会顺畅很多。