【从结果走向C语言】操作符全解
C语言的操作符非常丰富,掌握它们是写出高效、简洁代码的基础。本篇从实际使用角度系统梳理C语言所有常用操作符,包含优先级、结合性、陷阱和最佳实践。
1. 操作符优先级与结合性总览(最重要)
优先级从高到低排列(记住口诀:单目算术 关系逻辑 赋值逗号):
| 优先级 | 操作符 | 结合性 | 类别 |
|---|---|---|---|
| 1 | () [] -> . | 左→右 | 后缀 |
| 2 | ++ -- + - ! ~ * & (类型) sizeof | 右→左 | 单目 |
| 3 | * / % | 左→右 | 乘除 |
| 4 | + - | 左→右 | 加减 |
| 5 | << >> | 左→右 | 位移 |
| 6 | < <= > >= | 左→右 | 关系 |
| 7 | == != | 左→右 | 相等 |
| 8 | & | 左→右 | 按位与 |
| 9 | ^ | 左→右 | 按位异或 |
| 10 | | | 左→右 | 按位或 |
| 11 | && | 左→右 | 逻辑与 |
| 12 | || | 左→右 | 逻辑或 |
| 13 | ?: | 右→左 | 条件 |
| 14 | = += -= *= /= %= &= ^= |= <<= >>= | 右→左 | 赋值 |
| 15 | , | 左→右 | 逗号 |
建议:优先级不确定时,用小括号明确意图。
2. 各类型操作符详解
2.1 算术操作符
+ - * / %
%(取模):只能用于整数,符号与被除数一致(C99标准)/:整数相除结果取整(舍弃小数部分)
int a = 5, b = 2;
printf("%d\n", a / b); // 2
printf("%d\n", a % b); // 1
2.2 自增自减(最容易出错)
++a; // 前置:先加后用
a++; // 后置:先用后加
经典陷阱:
int i = 1;
printf("%d %d %d\n", i++, ++i, i++); // 未定义行为!不要这样写
推荐:一行只使用一次自增/自减。
2.3 关系与逻辑操作符
- 关系:
==!=><>=<= - 逻辑:
&&||!
短路特性(非常重要):
if (p != NULL && p->data > 10) // p为NULL时不会访问p->data
...
if (a || b) // a为真时b不会被计算
2.4 赋值操作符
= += -= *= /= %= &= |= ^= <<= >>=
链式赋值:
a = b = c = 0; // 从右向左结合
2.5 位操作符(嵌入式、底层开发必备)
| 操作符 | 含义 | 常见用途 |
|---|---|---|
& | 按位与 | 清零、取某位 |
| | 按位或 | 置位 |
^ | 按位异或 | 翻转某位、交换两数 |
~ | 按位取反 | – |
<< | 左移 | 乘2的快速运算 |
>> | 右移 | 除2,有符号右移为算术移位 |
经典技巧:
// 判断奇偶
if (n & 1) // 奇数
// 置第k位为1
n |= (1 << k);
// 清第k位为0
n &= ~(1 << k);
// 交换两数(不使用临时变量)
a ^= b; b ^= a; a ^= b;
2.6 条件(三目)操作符
条件 ? 表达式1 : 表达式2
int max = a > b ? a : b;
// 嵌套示例(不推荐过深)
char* str = score >= 90 ? "优秀" : score >= 60 ? "及格" : "不及格";
2.7 sizeof 操作符
sizeof(类型) 或 sizeof(变量) // 单位:字节
注意:
- 对数组名使用时返回整个数组大小
- 对指针使用时返回指针本身大小(32位=4,64位=8)
2.8 逗号操作符
表达式1, 表达式2, 表达式3; // 整个表达式值为最后一个表达式的值
常用在for循环中:
for (i=0, j=100; i < j; i++, j--)
2.9 指针与成员操作符
*:取值(解引用)&:取地址.:结构体成员访问->:通过指针访问结构体成员
3. 优先级经典陷阱与正确写法
// 错误示例
if (a & b == 0) // 实际是 a & (b == 0)
// 正确写法
if ((a & b) == 0)
// 另一个常见错误
a = b = c + d; // 正确:先算c+d,再赋值
推荐原则:
- 复杂表达式必须加括号
- 位操作、逻辑混合时一定要括号
4. 总结口诀(便于记忆)
- 算术:加减乘除模
- 关系:大于小于等于不等
- 逻辑:与或非(短路)
- 位运算:与或异或取反移位
- 赋值:从右到左结合
- 自增自减:一行只用一次
练习题(建议立即动手):
- 用位运算实现判断一个数是否是2的整数次幂
- 不使用第三变量交换两个整数的值(两种方法)
- 实现一个宏
#define MAX(a,b)求两个数的最大值(考虑副作用)
需要我继续写下一讲吗?
- 下一讲预告:《指针与数组的爱恨情仇》
- 或者深入讲解:位运算实战 / 运算符重载思想在C中的模拟 / 未定义行为(UB)与操作符
告诉我你的需求,我继续为你写!