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
。
程序中的每一行代码,如同生命中的每一个决定,都有其先后的秩序。懂得运算的优先级,就如同明白了生命中何事当先,何事当后,如此,方能让那看似杂乱的逻辑,也流淌出清晰而准确的脉络。