运算符与表达式 | Operators and Expressions
一、回顾与引入
在前面的章节中,我们已经学会了:
- 声明变量并给变量赋值
- 使用
printf()输出变量的值 - 使用
scanf()获取用户输入
在上一章的练习中,我们计算了圆的面积和周长:
float circumference = 2 * pi * radius; // 使用了乘法运算符 *
float area = pi * radius * radius; // 使用了乘法运算符 *
我们还在BMI计算中使用了除法:
float height_in_meters = height / 100.0; // 使用了除法运算符 /
在上面两个例子中,我们频繁使用了如+、-、*、/等等各种简单运算符,今天我们要专门系统学习C语言中的各种运算符,让程序能够进行更复杂的数学计算和逻辑判断。
二、什么是运算符和表达式?
运算符(Operator)
运算符是用来对数据进行操作的符号,比如:
+表示加法-表示减法*表示乘法/表示除法
表达式(Expression)
表达式是由操作数(变量、常量)和运算符组成的式子,比如:
3 + 5 // 简单表达式
a * b + c // 复合表达式
a >= b // 逻辑判断表达式 *本章会讲
表达式的值
每个表达式都有一个值,例如对于3 + 5这个表达式,它的值为8。这个值可以:
- 直接使用:
printf("%d", 3 + 5); // 输出8 - 赋值给变量:
int result = 3 + 5; - 作为其他表达式的一部分:
int x = (3 + 5) * 2;
三、算术运算符
算术运算符用于进行数学计算,这是我们最常用的运算符。
基本算术运算符
| 运算符 | 名称 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | 5 + 3 |
8 |
- |
减法 | 5 - 3 |
2 |
* |
乘法 | 5 * 3 |
15 |
/ |
除法 | 10 / 3 |
3(整数除法) |
/ |
除法 | 10.0 / 3.0 |
3.33333(小数除法) |
% |
取模(求余) | 10 % 3 |
1 |
必要地,这里对除法和取模运算做出说明:
除法
在C语言中,除法分为整除除法和小数除法。我们通过下面两个例子来简单认识:
//Division_Types.c
#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("10 / 3 = ", a / b); // 结果:3
}
//Division_Types.c
#include <stdio.h>
int main() {
float a = 10.0, b = 3.0;
printf("10.0 / 3.0 = ", a / b); // 结果:3.33333
}
我们会发现,同样是除法运算符/,作整除除法还是小数除法取决于除数和被除数的数据类型。它们遵循以下关键规则:
- 两个整数相除 → 结果是整数(舍去小数部分)
- 只要有一个浮点数参与 → 结果是浮点数
这也就解释了为什么10 / 3结果是3而10.0 / 3.0结果是3.33333。
这是因为在直接使用10、3.0等数字参与表达式计算,而不像上面的例子中使用一个具有明确数据类型的变量时,10、3等不带小数点的数算作整型int,而10.0、3.0等带小数点的数算作浮点型float。
还要值得一提的是,在赋值语句中,作整除除法还是小数除法与被赋值变量的数据类型无关。什么意思?
float result = 10 / 3;
即使这里result变量是浮点型,但10 / 3本身得到整数3。在赋值后,result确实是一个小数,但最终的值是3.0。
取模
取模(mod)又叫求余,是带余除法的一部分。取模是针对两个整数的计算。它得到的是除法的余数。例如,因为10 ÷ 3 = 3 余 1:
所以10 % 3的值是1。
示例程序:基本算术运算
//Basic_Arithmetic.c
#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("a = %d, b = %d\n", a, b);
printf("a + b = %d\n", a + b); // 加法
printf("a - b = %d\n", a - b); // 减法
printf("a * b = %d\n", a * b); // 乘法
printf("a / b = %d\n", a / b); // 整数除法
printf("a %% b = %d\n", a % b); // 取模运算
// 还记得为什么输出%时,要写作%%么?答案在第1.3节的特殊字符与转义字符那一栏
return 0;
}
运行结果:
a = 10, b = 3
a + b = 13
a - b = 7
a * b = 30
a / b = 3
a % b = 1
四、赋值运算符
基本赋值运算符 =
我们已经很熟悉基本的赋值运算符了:
int x = 10; // 将10赋值给x
在程序设计时,我们可能会遇到下面的情况,例如我们有一个变量x:
int x = 100;
假设我们想把变量x存储的值变为原来的两倍,并且仍然存储在变量x里。我们可以这样写:
x = x * 2;
这个操作不难理解,叫做乘法赋值。特点是程序会先取出 x 的值,乘上 2,再把结果存回 x。
此外,类似还有加法赋值、减法赋值、除法赋值、取模赋值等等。
例如:
x = x + 1; // x 由 100 变为 101
x = x - 3; // x 由 100 变为 97
x = x / 5; // x 由 100 变为 20
x = x % 3; // x 由 100 变为 1
复合赋值运算符
为了简化常见的自操作,C语言提供了复合赋值运算符:
| 运算符 | 等价写法 | 示例 | 含义 |
|---|---|---|---|
x += y |
x = x + y |
x += 5 |
x自增5 |
x -= y |
x = x - y |
x -= 3 |
x自减3 |
x *= y |
x = x * y |
x *= 2 |
x乘以2 |
x /= y |
x = x / y |
x /= 4 |
x除以4 |
x %= y |
x = x % y |
x %= 3 |
x对3取模 |
示例程序:复合赋值运算符
//Compound_Assignment.c
#include <stdio.h>
int main() {
int score = 100;
printf("初始分数: %d\n", score);
score += 10; // score = score + 10
printf("加分后: %d\n", score);
score -= 5; // score = score - 5
printf("扣分后: %d\n", score);
score *= 2; // score = score * 2
printf("翻倍后: %d\n", score);
score /= 3; // score = score / 3
printf("除以3后: %d\n", score);
score %= 10; // score = score % 10
printf("对10取模后: %d\n", score);
return 0;
}
运行结果:
初始分数: 100
加分后: 110
扣分后: 105
翻倍后: 210
除以3后: 70
对10取模后: 0
五、自增自减运算符
在我们刚才的例子里,我们了解到加法赋值和减法赋值。而在实际运用中,x = x + 1和x = x - 1很常见。
因此,C语言提供了自增(++)和自减(--)运算符。它们是非常特殊的运算符,用于将变量的值增加或减少1。
基本语法
自增(++)和自减(--)语法很简单。例如对于变量x,x++;或++x;即可完成自增;x--;和--x;即可完成自减。
根据自增运算符++和自减运算符--在变量x的前后位置不同,又分为前缀自增/自减(如++x;)和后缀自增/自减(如x--;)。
int x = 5;
x++; // 后缀自增,x变成6
++x; // 前缀自增,x变成7
x--; // 后缀自减,x变成6
--x; // 前缀自减,x变成5
在单独使用自增自减,即像上面的例子中一样,++x;等自增语句独立成行的时候,前缀和后缀不存在区别,都表示例如x = x + 1;。但当自增自减属于某一语句的一部分时,它们有些微的区别:
前缀 vs 后缀的区别
//Increment_Decrement.c
#include <stdio.h>
int main() {
int x = 5;
int y = x++; // 后缀自增,此时先将变量x的值5赋值给变量y,再将变量x自增为6。
// 此时 x = 6, y = 5
int a = 5;
int b = ++a; // 前缀自增,此时先将变量a自增为6,再将变量a的值6赋值给变量b。
// 此时 a = 6, b = 6
return 0;
}
六、比较运算符
我们在前文讲解表达式时,举例曾提到逻辑判断表达式:
a >= b // 逻辑判断表达式 *本章会讲
我们在前文也提到
每个表达式都有一个值
那么逻辑判断表达式的值应该是什么?名为“判断”,它不应该是像3、100这样的数。事实上,逻辑判断表达式的值只能是1(代表真,有时也写作true)或0(代表假,有时也写作false),用来表示这个逻辑判断表达式的内容是对的还是错的。
例如,3 > 2的值是1(真),而-1 > 3的值是0(假)。
比较运算符用于比较两个值的大小关系,是组成逻辑判断表达式的常见运算符。
比较运算符表
| 运算符 | 名称 | 示例 | 含义 |
|---|---|---|---|
== |
等于 | a == b |
a等于b |
!= |
不等于 | a != b |
a不等于b |
> |
大于 | a > b |
a大于b |
< |
小于 | a < b |
a小于b |
>= |
大于等于 | a >= b |
a大于等于b |
<= |
小于等于 | a <= b |
a小于等于b |
示例程序:比较运算符
//Comparison_Operators.c
#include <stdio.h>
int main() {
int a = 10;
int b = 5;
printf("\n=== 比较结果 ===\n");
printf("10 == 5 结果: %d\n", a == b);
printf("10 != 5 结果: %d\n", a != b);
printf("10 > 5 结果: %d\n", a > b);
printf("10 < 5 结果: %d\n", a < b);
printf("10 >= 5 结果: %d\n", a >= b);
printf("10 <= 5 结果: %d\n", a <= b);
return 0;
}
运行示例:
=== 比较结果 ===
10 == 5 结果: 0
10 != 5 结果: 1
10 > 5 结果: 1
10 < 5 结果: 0
10 >= 5 结果: 1
10 <= 5 结果: 0
常见错误:赋值与比较
在C语言中,=是赋值运算符,用于赋值语句。例如x = 5;。==是比较运算符,用于比较两个变量是否相等。例如3 == 2的值是0(假),'A' == 'A'的值为1(真)。
此外值得一提的是,即使是赋值表达式x = 5也有它对应的值。这个值也只能是1(真)或0(假),表示赋值是否成功。因此通常情况下,赋值表达式的值一般都为1。这会在下一节提到判断语句的时候再次提到。
七、逻辑运算符
除了比较运算符,我们通常在逻辑处理中还伴随复杂条件。例如:
今天温度在18~22度之间
假设今天的的温度由变量t存储,这个自然语言表述的逻辑判断表达式,相当于是指“既要”t >= 18.0,“又要”t <= 22.0。
我们在日常生活里常常遇到“而且”、“或者”、“不是”等逻辑关联词。它们正对应着三大逻辑运算符:与&&、或||、非!。
逻辑运算符用于组合多个条件,在编写复杂判断时非常有用。
逻辑运算符表
| 运算符 | 名称 | 示例 | 含义 |
|---|---|---|---|
&& |
逻辑与 | a && b |
a和b都为真时,结果为真 |
|| |
逻辑或 | a || b |
a或b有一个为真时,结果为真 |
! |
逻辑非 | !a |
a为假时结果为真,a为真时结果为假 |
真值表
A |
B |
A && B |
A || B |
!A |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 |
在上面的例子中,“今天温度在18~22度之间”相当于t >= 18.0 && t <= 22.0,即温度t在同时满足大于等于18.0摄氏度和小于等于22.0摄氏度这两个简单条件时,这个表达式的值才为1(真),否则为0(假)。
八、运算符的优先级和结合性
当表达式中有多个运算符时,需要了解它们的执行顺序。
优先级表(从高到低,初学阶段了解即可)
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1 | () |
左到右 |
| 2 | ! ++ -- |
右到左 |
| 3 | * / % |
左到右 |
| 4 | + - |
左到右 |
| 5 | < <= > >= |
左到右 |
| 6 | == != |
左到右 |
| 7 | && |
左到右 |
| 8 | || |
左到右 |
| 9 | = += -= *= /= %= |
右到左 |
示例:优先级的重要性
//Precedence_Examples.c
#include <stdio.h>
int main() {
int a = 2, b = 3, c = 4;
printf("a = %d, b = %d, c = %d\n", a, b, c);
// 乘法优先于加法
printf("a + b * c = %d\n", a + b * c); // 等价于 a + (b * c) = 2 + 12 = 14
printf("(a + b) * c = %d\n", (a + b) * c); // (2 + 3) * 4 = 20
// 比较运算符优先于逻辑运算符
printf("a < b && b < c = %d\n", a < b && b < c); // (2 < 3) && (3 < 4) = 1 && 1 = 1
// 赋值运算符优先级最低
int result = a + b * c; // 先计算 a + b * c,再赋值给result
printf("result = %d\n", result);
return 0;
}
使用括号明确意图
即使了解优先级,也建议使用括号来明确表达意图:
// 不推荐:依赖优先级规则
int result1 = a + b * c / d - e;
// 推荐:使用括号明确意图
int result2 = a + ((b * c) / d) - e;
九、动手练习
练习:温度转换器
编写程序实现摄氏度和华氏度之间的转换:
- 摄氏度转华氏度:F = C × 9/5 + 32
- 华氏度转摄氏度:C = (F - 32) × 5/9
下一章预告: 掌握了运算符后,我们将学习条件语句(if-else),让程序能够根据不同的条件执行不同的操作,实现真正的智能判断!



Comments | NOTHING