小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2025-11-29 / 0 阅读
0
0

C语言运算符优先级详解

运算符优先级表(从高到低)

优先级 运算符 描述 结合性
1 () [] -> . 函数调用、数组下标、结构成员 左→右
2 ! ~ ++ -- + - * & (type) sizeof 单目运算符(负号、正号、解引用、取地址等) 右→左
3 * / % 乘、除、取模 左→右
4 + - 加、减 左→右
5 << >> 位左移、右移 左→右
6 < <= > >= 关系运算符 左→右
7 == != 相等性判断 左→右
8 & 位与 左→右
9 ^ 位异或 左→右
10 位或
11 && 逻辑与 左→右
12
13 ?: 三元条件运算符 右→左
14 = += -= *= /= %= &= ^= = <<= >>= 赋值运算符
15 , 逗号运算符 左→右


10道高难度运算符优先级题目

题目1:混合运算

int a = 5, b = 3, c = 2;
int result = ++a * b-- + c << 2 & 0xFF | ~a ^ b;

问题:result的值是多少?请详细分析计算过程。

⚠️ 指出错误:此表达式存在多个潜在问题:

  1. 运算符优先级复杂,实际求值顺序应为:(((++a * b--) + c) << 2) & 0xFF | ((~a) ^ b),极易产生误解
  2. b--作为后缀运算符,在表达式中使用的仍是原值(3),但副作用会影响后续表达式中的b
  3. ~a的类型提升问题:如果int是32位,a会对整个32位取反,可能不是预期结果

题目2:指针与位运算

int x = 10, y = 20;
int *p = &x;
int result = *p++ + (*p & y) << 1 | sizeof(*p) ? x : y;

问题:result的值是多少?p指向什么位置?

⚠️ 指出错误:第一行存在严重问题:

  1. *p++是"先取指针p指向的值,然后指针p自增",等价于 *(p++),不是 (*p)++
  2. *p++执行后,p指向了x的下一个int内存位置(&x + sizeof(int)),这通常是未定义行为(访问未分配的内存)
  3. 后续 *p访问的是未知内存,可能导致程序崩溃

题目3:三元运算符嵌套

int a = 1, b = 2, c = 3, d = 4;
int result = a > b ? c < d ? a : b : c > d ? c : d;
result += a++ * --b + c-- % d++;

问题:最终result和各个变量的值是多少?


题目4:逗号表达式与赋值

int a = 5, b = 10, c = 15;
int result = (a += 2, b -= 3, c *= 2), a = b = c, a ^ b | c;

问题:分析表达式的执行顺序和最终结果。


题目5:复杂位运算

unsigned int flags = 0x0F;
int mask = 0x03;
int shift = 2;
int result = ~flags & mask << shift | (flags >> shift) & ~mask;
result ^= (flags & mask) ? 0xFF : 0x00;

问题:计算result的十六进制值。


题目6:指针运算优先级

int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr;
int result = *++ptr + ++*ptr * (*ptr)--;

问题:result的值是多少?数组内容发生了什么变化?

❌ 严重错误:此表达式包含未定义行为(Undefined Behavior):

  1. *++ptr修改ptr,++*ptr修改ptr指向的值,(*ptr)--再次修改ptr指向的值
  2. 根据C标准6.5条款:一个对象在同一条语句中被多次修改且没有序列点分隔,属于未定义行为
  3. 不同编译器可能产生完全不同的结果,不应在实际代码中使用

题目7:类型转换与运算

int a = 10;
double b = 3.5;
char c = 'A';
int result = (int)(b + 0.5) * a++ + c % a << 2;

问题:分析类型转换过程和最终结果。


题目8:逻辑运算短路

int a = 0, b = 5, c = 10;
int result = a++ && ++b || c--;
result = result ? b * c : a + b + c;

问题:哪些表达式被执行?最终结果是多少?


题目9:复合赋值运算

int x = 8, y = 4, z = 2;
x |= y &= z ^= x >>= 1;

问题:逐步分析运算过程,给出最终x, y, z的值。


题目10:综合难题

int a = 1, b = 2, c = 3, d = 4;
int *p = &a, *q = &b;
int result = (*p)++ + --(*q) * sizeof(p) > (p == &a) ? 
             (a > b ? c : d) << 2 : 
             (c < d ? a : b) >> 1;
result &= ~0x03 | 0x01;

问题:详细分析整个表达式的计算过程和最终结果。


答案解析要点

  1. 题目1:注意++a(前增)和b--(后减)的区别,位运算符优先级
  2. 题目2:p++是指针后增,不是值后增
  3. 题目3:三元运算符右结合性,注意副作用
  4. 题目4:逗号运算符返回最后一个表达式的值
  5. 题目5:位运算的优先级低于移位运算
  6. 题目6:指针运算的副作用和顺序点 (题目本身存在未定义行为)
  7. 题目7:类型转换和字符的ASCII值
  8. 题目8:逻辑运算符的短路特性
  9. 题目9:复合赋值从右向左结合
  10. 题目10:综合考察指针、三元、位运算等

⚠️ 重要提醒:部分题目(特别是题目6)包含未定义行为,仅用于考察知识点,严禁在生产代码中使用。实际编程中应遵循KISS原则,避免复杂的表达式组合。


评论