c语言小课堂-运算优先级

c语言小课堂-运算优先级
TANG JIAMEI今天我们来聊聊C语言中一个看似不起眼,实则举足轻重的概念——运算优先级。它就像代码世界的“交通规则”,决定了表达式中各个运算符的执行顺序,理解它,能让你的程序按照你预想的路径运行,避免“交通事故”!
一、知识点讲解
1. 运算优先级:它“是什么”?
在C语言中,一个表达式可能包含多个运算符,比如加减乘除、赋值、逻辑运算等等。当这些运算符同时出现时,计算机如何知道先计算哪个,后计算哪个呢?这就是“运算优先级”要解决的问题。
简单来说,运算优先级就是C语言为各种运算符预设的执行顺序规则。优先级高的运算符会先于优先级低的运算符执行。如果优先级相同,那么就按照“结合性”来决定执行顺序(通常是从左到右,但也有例外,比如赋值运算符是从右到左)。
我们可以把C语言的运算符想象成一支军队,每个士兵(运算符)都有自己的军衔(优先级)。军衔高的士兵自然拥有更高的指挥权,会优先执行任务。当军衔相同的时候,就看军队的行军方向(结合性)了。
2. 何时用?为什么用?
何时用?
只要你的C语言表达式中出现两个或两个以上的运算符,你就需要考虑运算优先级。无论是在编写简单的数学计算,还是复杂的条件判断、位操作,运算优先级的知识都必不可少。
为什么用?
- 确保计算结果的正确性: 没有优先级,
2 + 3 * 4可能会被错误地计算成(2 + 3) * 4 = 20,而不是正确的2 + (3 * 4) = 14。运算优先级保证了表达式按照数学上的常规逻辑进行求值。 - 提高代码可读性: 虽然可以通过括号来强制改变运算顺序,但了解优先级可以让你在不滥用括号的情况下,写出更清晰、更符合直觉的代码。
- 避免隐藏的bug: 许多新手程序员在编写复杂表达式时,由于不熟悉优先级而引入难以发现的逻辑错误。例如,
if (a > 0 && b < 10)和if (a > 0 || b < 10)中,&&和||的优先级就决定了它们的求值顺序。
与关联知识点的联系与区别:
运算优先级与“结合性”是紧密相关的两个概念。当两个运算符优先级相同时,结合性就登场了。
| 特性 | 运算优先级 | 结合性 |
|---|---|---|
| 定义 | 决定不同运算符的执行顺序 | 决定相同优先级运算符的执行顺序 |
| 规则 | 优先级高的先执行 | 从左到右或从右到左 |
| 示例 | * 优先于 +,所以 a + b * c 先算 b * c |
+ 从左到右结合,所以 a + b + c 先算 a + b |
3. 怎么用?
C语言的运算符种类繁多,它们的优先级也各不相同。记住所有运算符的优先级可能有些困难,但掌握一些核心原则和常见运算符的优先级就足够了。
核心原则:
- 括号
()优先级最高: 任何被括号括起来的表达式都会首先被计算。这是你强制改变运算顺序的利器。 - 单目运算符通常高于双目运算符: 例如,
!(逻辑非)、++(自增)、--(自减) 的优先级通常高于+、-、*、/。 - 算术运算符高于关系运算符,关系运算符高于逻辑运算符:
* / %(乘除模) >+ -(加减)+ ->< > <= >=(关系运算符)< > <= >=>== !=(相等性运算符)== !=>&&(逻辑与)&&>||(逻辑或)
- 赋值运算符优先级最低: 几乎所有其他运算符都比赋值运算符
=的优先级高。
常见运算符优先级(从高到低,不完全列表):
| 优先级 | 运算符 | 结合性 | 描述 |
|---|---|---|---|
| 1 | () [] . -> ++ -- (后缀) |
左到右 | 圆括号、数组下标、结构体成员访问、后置自增/减 |
| 2 | ++ -- (前缀) ! ~ + - * & sizeof |
右到左 | 前置自增/减、逻辑非、按位取反、正负号、解引用、取地址、求字节数 |
| 3 | * / % |
左到右 | 乘、除、取模 |
| 4 | + - |
左到右 | 加、减 |
| 5 | << >> |
左到右 | 左移、右移 |
| 6 | < <= > >= |
左到右 | 关系运算符 |
| 7 | == != |
左到右 | 相等性运算符 |
| 8 | & |
左到右 | 按位与 |
| 9 | ^ |
左到右 | 按位异或 |
| 10 | ` | ` | 左到右 |
| 11 | && |
左到右 | 逻辑与 |
| 12 | ` | ` | |
| 13 | ? : |
右到左 | 三目运算符 |
| 14 | = += -= *= /= % = 等 |
右到左 | 赋值运算符及复合赋值运算符 |
| 15 | , |
左到右 | 逗号运算符 |
示例:
1 |
|
小贴士:
当你对某个表达式的优先级不确定时,最稳妥、最清晰的做法就是使用括号 () 来明确指定运算顺序。这不仅能避免错误,还能大大提高代码的可读性,让未来的你(或你的同事)一眼就能明白你的意图。
二、典型习题
选择题:
下面C语言表达式int x = 10, y = 5, z = 2; int result = x + y * z - 1;的result的值是多少?- A. 19
- B. 29
- C. 14
- D. 12
判断题:
表达式a = b > c ? b : c;中,>运算符的优先级高于? :三目运算符。- A. 正确
- B. 错误
填空题:
请问表达式! (5 > 3 && 2 < 1)的最终结果是______(填写0或1)。编程题:
编写一个C语言程序,计算表达式(10 + 20) * 3 / 2 - 5 % 2的结果,并打印出来。要求在表达式中不使用任何多余的括号(即只使用必要的括号来确保优先级)。编程题(进阶):
编写一个C语言程序,声明三个整型变量a,b,c,并分别初始化为7,3,5。
然后,计算以下表达式的值,并打印结果。请分析表达式中运算符的优先级和结合性。int final_result = a++ * b - c / 2 + ! (a > b && c < 10);
三、习题讲解
1. 选择题:
下面C语言表达式 int x = 10, y = 5, z = 2; int result = x + y * z - 1; 的 result 的值是多少?
- A. 19
- B. 29
- C. 14
- D. 12
答案:A
解析:
根据C语言的运算优先级规则:
- 乘法
*的优先级高于加法+和减法-。
所以,首先计算y * z,即5 * 2 = 10。 - 表达式变为
result = x + 10 - 1; - 加法
+和减法-优先级相同,它们是左结合的,所以从左到右依次计算。- 先计算
x + 10,即10 + 10 = 20。 - 再计算
20 - 1,即19。
因此,result的值为19。
- 先计算
2. 判断题:
表达式 a = b > c ? b : c; 中,> 运算符的优先级高于 ? : 三目运算符。
- A. 正确
- B. 错误
答案:A
解析:
根据C语言的运算符优先级表,关系运算符 > 的优先级(第6级)高于三目运算符 ? :(第13级)。
这意味着在 b > c ? b : c 这个表达式中,会首先计算 b > c 这个关系表达式,得到一个布尔结果(真或假),然后根据这个结果再执行三目运算符的条件选择。
所以,该说法是正确的。
3. 填空题:
请问表达式 ! (5 > 3 && 2 < 1) 的最终结果是 ______(填写0或1)。
答案:1
解析:
- 括号内的运算优先:
(5 > 3 && 2 < 1) - 关系运算符优先于逻辑运算符:
5 > 3:结果为真 (1)。2 < 1:结果为假 (0)。
- 逻辑与
&&运算:真 && 假(即1 && 0):结果为假 (0)。
- 逻辑非
!运算:! 假(即! 0):结果为真 (1)。
因此,最终结果是1。
4. 编程题:
编写一个C语言程序,计算表达式 (10 + 20) * 3 / 2 - 5 % 2 的结果,并打印出来。要求在表达式中不使用任何多余的括号(即只使用必要的括号来确保优先级)。
1 |
|
运行结果:
1 | 表达式 (10 + 20) * 3 / 2 - 5 % 2 的结果是: 44 |
解析:
(10 + 20)首先计算,得到30。30 * 3计算,得到90。90 / 2计算,得到45。5 % 2计算,得到1(5除以2的余数)。- 最后
45 - 1计算,得到44。
5. 编程题(进阶):
编写一个C语言程序,声明三个整型变量 a, b, c,并分别初始化为 7, 3, 5。
然后,计算以下表达式的值,并打印结果。请分析表达式中运算符的优先级和结合性。int final_result = a++ * b - c / 2 + ! (a > b && c < 10);
1 |
|
运行结果:
1 | a = 7, b = 3, c = 5 |
解析:
这个表达式综合了多种运算符,是考察优先级和结合性的好例子。
a++(后置自增):a的当前值7用于表达式的* b部分,然后a立即变为8。所以a++ * b实际是7 * 3 = 21。c / 2(整数除法):5 / 2 = 2。! (a > b && c < 10):- 括号
()优先级最高。 - 在括号内,
>和<(关系运算符) 优先级高于&&(逻辑与)。 a > b:此时a已经更新为8,所以8 > 3为真 (1)。c < 10:5 < 10为真 (1)。&&:1 && 1为真 (1)。- 最后,
!(逻辑非) 优先级高于括号内的运算结果。! (1)为假 (0)。
- 括号
- 整个表达式现在简化为
21 - 2 + 0。 -和+优先级相同,从左到右结合。21 - 2 = 19。19 + 0 = 19。
所以final_result的最终值是19。
程序中的每一行代码,如同生命中的每一个决定,都有其先后的秩序。懂得运算的优先级,就如同明白了生命中何事当先,何事当后,如此,方能让那看似杂乱的逻辑,也流淌出清晰而准确的脉络。




