返回 课程

信奥AC之路-1级

0% 完成
0/0 步骤
  1. 第1课 开发环境与基础输出
    5 主题|小节
  2. 第2课 算术运算符
    7 主题|小节
  3. 第3课 printf与运算输出
    7 主题|小节
  4. 第4课 数的进制与拆位
    6 主题|小节
  5. 第5课 变量与基础运算
    17 主题|小节
  6. 第6课 常量与取整运算
    8 主题|小节
  7. 第7课 关系运算
    8 主题|小节
  8. 第8课 逻辑运算
    9 主题|小节
  9. 第9课 输入与计算进阶
    10 主题|小节
  10. 第10课 if语句及双分支语句
    8 主题|小节
  11. 第11课 if语句及双分支进阶
    11 主题|小节
  12. 第12课 三目运算
    9 主题|小节
  13. 第13课 多分支、多if和switch语句
    11 主题|小节
  14. 第14课 循环(基本输出)
    7 主题|小节
  15. 第15课 循环(While+If)
    8 主题|小节
  16. 第16课 循环(计数、求和、求乘积)
    10 主题|小节
  17. 第17课 循环进阶(While+)
    8 主题|小节
  18. 第18课 do-while及while其他用法
    8 主题|小节
  19. 第19课 For循环基础
    9 主题|小节
  20. 第20课 For循环进阶
    8 主题|小节
课 8, 主题|小节 3
进行中

8.2 运算优先级详解

2025年9月22日
课 进展
0% 完成

“小朋友们,”我拍拍手说,”现在我们来学习一个非常重要的知识点:运算的优先级!就像数学中先乘除后加减一样,逻辑运算也有它的计算顺序。”

8.2.1 基本优先级规则

// 1. 算术运算符的优先级最高
printf("%dn", 3 + 4 > 5);    // 先计算3+4,再比较结果是否大于5

// 2. 关系运算符优先级次之
printf("%dn", 3 > 4 && 5 < 6);    // 先计算比较,再进行逻辑与

// 3. 逻辑运算符优先级最低,其中:
// !(非)> &&(与)> ||(或)
printf("%dn", !0 && 1 || 0);    // 先算!0,再算与,最后算或

[图片:展示运算符优先级的层次结构]

8.2.2 复杂表达式的求值

// 示例1:包含所有类型运算符的表达式
printf("%dn", 3 + 4 > 5 && 10 - 6 < 5);
// 计算步骤:
// 1. 3 + 4 = 7,  10 - 6 = 4
// 2. 7 > 5 = 1,  4 < 5 = 1
// 3. 1 && 1 = 1

// 示例2:多重逻辑运算
printf("%dn", !0 && 1 || 0 && !1);
// 计算步骤:
// 1. !0 = 1,  !1 = 0
// 2. 1 && 1 = 1,  0 && 0 = 0
// 3. 1 || 0 = 1

[图片:用树形结构展示复杂表达式的计算过程]

练习题:

  1. 选择题:表达式”3 + 4 > 5 && 2″的计算顺序是:
    A. ((3 + 4) > 5) && 2
    B. 3 + (4 > 5) && 2
    C. 3 + 4 > (5 && 2)
    D. (3 + 4) > (5 && 2)

正确答案:A
解析:先进行算术运算3+4,然后进行关系运算>5,最后进行逻辑运算&&2。

  1. 判断题:在表达式”!a && b”中,!运算符的优先级高于&&。

正确答案:√
解析:在逻辑运算符中,!(非)的优先级最高,所以会先计算!a。

8.2.3 使用括号改变优先级

// 示例1:基本的优先级改变
printf("===基本括号使用===n");
// 不使用括号:先计算3+4,再比较大于5,最后与2做逻辑与
printf("3 + 4 > 5 && 2 = %dn", 3 + 4 > 5 && 2);     // 输出:1
// 使用括号:先计算4>5&&2,再加3
printf("3 + (4 > 5 && 2) = %dn", 3 + (4 > 5 && 2)); // 输出:3

// 示例2:多层括号的使用
printf("n===多层括号===n");
// 最外层括号分组:(!0 && 1)计算后为1,(0 && !1)计算后为0,最后进行或运算
printf("(!0 && 1) || (0 && !1) = %dn", (!0 && 1) || (0 && !1));    // 输出:1
// 步骤解析:
// 1. !0 = 1
// 2. !1 = 0
// 3. (1 && 1) = 1
// 4. (0 && 0) = 0
// 5. 1 || 0 = 1

// 示例3:括号改变逻辑非的作用范围
printf("n===逻辑非的范围===n");
// 不使用括号:!仅作用于0
printf("!0 || 1 && 0 = %dn", !0 || 1 && 0);         // 输出:1
// 使用括号:!作用于整个表达式
printf("!(0 || 1 && 0) = %dn", !(0 || 1 && 0));     // 输出:0
// 步骤解析:
// 不使用括号时:
// 1. !0 = 1
// 2. 1 && 0 = 0
// 3. 1 || 0 = 1
// 使用括号时:
// 1. 1 && 0 = 0
// 2. 0 || 0 = 0
// 3. !0 = 1

// 示例4:复杂表达式中的括号使用
printf("n===复杂表达式括号===n");
// 表达式1:优先计算括号内的逻辑运算
printf("(5 > 3 && 2 < 4) || !(1 && 0) = %dn", (5 > 3 && 2 < 4) || !(1 && 0));    // 输出:1
// 步骤解析:
// 1. 5 > 3 = 1
// 2. 2 < 4 = 1
// 3. 1 && 1 = 1
// 4. 1 && 0 = 0
// 5. !0 = 1
// 6. 1 || 1 = 1

// 表达式2:展示不同括号位置的影响
printf("3 * (2 + 1) > 8 && 4 = %dn", 3 * (2 + 1) > 8 && 4);        // 输出:0
printf("3 * 2 + 1 > 8 && 4 = %dn", 3 * 2 + 1 > 8 && 4);           // 输出:0
// 步骤解析:
// 带括号:
// 1. 2 + 1 = 3
// 2. 3 * 3 = 9
// 3. 9 > 8 = 1
// 4. 1 && 4 = 1
// 不带括号:
// 1. 3 * 2 = 6
// 2. 6 + 1 = 7
// 3. 7 > 8 = 0
// 4. 0 && 4 = 0

// 示例5:条件组合中的括号
printf("n===条件组合===n");
// 判断一个数是否在区间[1,10]内
printf("(5 > 1) && (5 < 10) = %dn", (5 > 1) && (5 < 10));          // 输出:1
// 判断一个数是否不在区间[1,10]内
printf("!((5 > 1) && (5 < 10)) = %dn", !((5 > 1) && (5 < 10)));    // 输出:0

[图片:用树形结构展示不同括号位置对表达式求值顺序的影响]

练习题:

  1. 选择题:表达式”!(3 > 2 || 4 < 1)”的计算结果是:
    A. 1
    B. 0
    C. 3
    D. 4

正确答案:B
解析:

  1. 3 > 2 结果为1

  2. 4 < 1 结果为0

  3. 1 || 0 结果为1

  4. !1 结果为0

  5. 判断题:表达式”(3 + 4 > 5) && 2″与”3 + (4 > 5 && 2)”的结果相同。

正确答案:×
解析:第一个表达式先计算3+4,再比较结果是否大于5,最后与2做逻辑与;第二个表达式先计算4>5&&2,结果为0,再与3相加。两者计算顺序不同,结果也不同。

8.2.4 运算符优先级总结

运算符优先级从高到低依次为:

  1. 括号运算符 ()
  2. 单目运算符:逻辑非(!), 正负号(+/-), 自增自减(++/–)
  3. 算术运算符:
    • 乘(*), 除(/), 取模(%)
    • 加(+), 减(-)
  4. 关系运算符:
    • 大于(>), 小于(<), 大于等于(>=), 小于等于(<=)
    • 等于(==), 不等于(!=)
  5. 逻辑运算符:
    • 逻辑与(&&)
    • 逻辑或(||)

示例:

int a = 3, b = 4, c = 5, d = 2;

// 1. 括号运算符优先级最高
printf("===括号优先级===n");
printf("直接运算:%dn", a + b * c);        // 23 (先乘后加)
printf("加括号后:%dn", (a + b) * c);      // 35 (括号改变运算顺序)

// 2. 单目运算符优先级
printf("n===单目运算符优先级===n");
printf("直接运算:%dn", !a + b);           // 4 (先求!a=0,再加b)
printf("加括号后:%dn", !(a + b));         // 0 (先算括号内a+b,再求非)

// 3. 算术运算符优先级
printf("n===算术运算符优先级===n");
printf("直接运算:%dn", a + b * c);        // 23 (先乘后加)
printf("加括号后:%dn", ((a + b) * c));    // 35 (先加后乘)

// 4. 关系运算符优先级
printf("n===关系运算符优先级===n");
printf("直接运算:%dn", a + b > c + d);    // 1 (先算a+b和c+d,再比较)
printf("加括号后:%dn", (a + b) > (c + d)); // 1 (结果相同,括号更清晰)

// 5. 混合优先级运算
printf("n===混合优先级运算===n");
// 直接运算:从高到低优先级依次计算
printf("直接运算:%dn", !a + b * c && d > a || c < b);
// 加括号后:完全展示运算优先级
printf("加括号后:%dn", ((((!a) + (b * c)) && (d > a)) || (c < b)));

// 步骤解析:
// 1. !a = 0                        (单目运算)
// 2. b * c = 20                    (算术运算-乘法)
// 3. 0 + 20 = 20                   (算术运算-加法)
// 4. d > a = 0  (2 > 3 = 0)       (关系运算)
// 5. c < b = 0  (5 < 4 = 0)       (关系运算)
// 6. 20 && 0 = 0                   (逻辑与)
// 7. 0 || 0 = 0                    (逻辑或)

// 6. 逻辑运算符组合
printf("n===逻辑运算符组合===n");
printf("直接运算:%dn", a > b && c > d || a < d);
printf("加括号后:%dn", ((a > b) && (c > d)) || (a < d));

// 7. 带有变量赋值的复杂运算
printf("n===复杂运算===n");
int result = (a + b) * c && !(d > a) || c > (b + d);
printf("复杂运算结果:%dn", result);
// 计算步骤:
// 1. (a + b) = 7
// 2. 7 * c = 35
// 3. (d > a) = 0
// 4. !(0) = 1
// 5. (b + d) = 6
// 6. c > 6 = 0
// 7. 35 && 1 = 1
// 8. 1 || 0 = 1

练习题:

  1. 选择题:表达式!2 + 3 * 4 && 5 > 2的运算顺序是:
    A. ((!2) + (3 * 4)) && (5 > 2)
    B. ((!2) + 3) * (4 && (5 > 2))
    C. (!2) + ((3 * 4) && (5 > 2))
    D. ((!2) + 3) * 4 && (5 > 2)

正确答案:A
解析:根据运算符优先级,!运算最先进行,然后是乘法,接着是加法,然后是关系运算,最后是逻辑与运算。

  1. 选择题:以下哪个表达式的运算结果与其他三个不同?
    A. !(1 + 2 > 3)
    B. 1 + 2 <= 3
    C. !((1 + 2) > 3)
    D. !(1 + (2 > 3))

正确答案:D
解析:
A和C完全等价,结果为1
B等价于A和C,结果为1
D中2>3先计算为0,然后1+0=1,最后!1=0

  1. 判断题:在表达式3 + 4 > 5 && 2中,加法运算的优先级高于关系运算。

正确答案:√
解析:算术运算符的优先级高于关系运算符,所以先计算3+4=7,然后判断7>5,最后进行&&运算。

  1. 判断题:在没有括号的情况下,表达式a && b || c && d的运算顺序是从左到右的。

正确答案:√
解析:&&和||具有相同的优先级时,按照从左到右的顺序计算。所以先计算a&&b得到一个结果,再计算c&&d得到一个结果,最后将两个结果进行||运算。