LV100-运算符简介
一、运算符
1. 相关概念
C 语言中表示运算的符号称为运算符,运算的对象称为操作数。对一个操作数进行运算的运算符称为单目运算符,对两个操作数进行运算的运算符称为双目运算符,三目运算符是对三个操作数进行运算。用运算符和括号可以将操作数连接起来组成表达式。
2. 运算符与优先级
| 优先级 | 运算符 | 名称(含义) | 使用形式 | 结合规律 | 说明 |
| 1 | [] | 数组下标 | 数组名称[常量表达式] | 左→右 | —— |
| () | 圆括号 | (表达式) 函数名(形参表) | —— | ||
| . | 成员选择(对象) | 对象.成员名 | —— | ||
| -> | 成员选择(指针) | 对象指针->成员名 | —— | ||
| 2 | - | 负号运算符 | -表达式 | 左←右 | 单目运算符 |
| ~ | 按位取反运算符 | ~表达式 | |||
| ++ | 自增运算符 | ++变量名 变量名++ | |||
| -- | 自减运算符 | --变量名 变量名-- | |||
| * | 取值运算符(指针运算符) | *指针变量 | |||
| & | 取地址运算符 | &变量名 | |||
| ! | 逻辑非运算符 | !表达式 | |||
| (类型) | 强制类型转换 | (数据类型)表达式 | —— | ||
| sizeof | 长度运算符 | sizeof(表达式) | —— | ||
| 3 | * | 乘法运算符 | 表达式 * 表达式 | 左→右 | 双目运算符 |
| / | 除法运算符 | 表达式 / 表达式 | |||
| % | 求余运算符(取模) | 整型表达式 % 整型表达式 | |||
| 4 | + | 加法运算符 | 表达式 + 表达式 | 左→右 | 双目运算符 |
| - | 减法运算符 | 表达式 - 表达式 | |||
| 5 | << | 左移运算符 | 变量 << 表达式 | 左→右 | 双目运算符 |
| >> | 右移运算符 | 变量 >> 表达式 | |||
| 6 | > | 大于 | 表达式 > 表达式 | 左→右 | 双目运算符 |
| >= | 大于等于 | 表达式 >= 表达式 | |||
| < | 小于 | 表达式 < 表达式 | |||
| <= | 小于等于 | 表达式 <= 表达式 | |||
| 7 | == | 等于运算符 | 表达式 == 表达式 | 左→右 | 双目运算符 |
| !== | 不等于运算符 | 表达式 !== 表达式 | |||
| 8 | & | 按位与运算符 | 表达式 & 表达式 | 左→右 | 双目运算符 |
| 9 | ^ | 按位异或运算符 | 表达式 ^ 表达式 | 左→右 | 双目运算符 |
| 10 | | | 按位或运算符 | 表达式 | 表达式 | 左→右 | 双目运算符 |
| 11 | && | 逻辑与运算符 | 表达式 && 表达式 | 左→右 | 双目运算符 |
| 12 | || | 逻辑或运算符 | 表达式 || 表达式 | 左→右 | 双目运算符 |
| 13 | ? : | 条件运算符 | 表达式1 ? 表达式2 : 表达式3 | 左←右 | 三目运算符 |
| 14 | = | 赋值运算符 | 变量 = 表达式 | 左←右 | —— |
| /= | 除后赋值运算符 | 变量 /= 表达式 | —— | ||
| *= | 乘后赋值运算符 | 变量 *= 表达式 | —— | ||
| %= | 取模后赋值运算符 | 变量 %= 表达式 | —— | ||
| += | 加后赋值运算符 | 变量 += 表达式 | —— | ||
| -= | 减后赋值运算符 | 变量 -= 表达式 | —— | ||
| <<= | 左移后赋值运算符 | 变量 <<= 表达式 | —— | ||
| >>= | 右移后赋值运算符 | 变量 >>= 表达式 | —— | ||
| &= | 按位与后赋值运算符 | 变量 &= 表达式 | —— | ||
| ^= | 按位异或后赋值运算符 | 变量 ^= 表达式 | —— | ||
| |= | 按位或后赋值运算符 | 变量 |= 表达式 | —— | ||
| 15 | , | 逗号运算符 | 表达式1, 表达式2, …, 表达式n | 左→右 | —— |
【注意】
- 优先级数字越小,优先级越高。
- 同一优先级的运算符,运算次序由结合方向决定
- 通常情况下取模运算( mod )和求余( rem )运算的目标结果相同,在大多数的编程语言里,都用 % 符号表示取模或者求余运算。不过还是要十分注意当前环境下 % 运算符的具体意义,因为在有负数存在的情况下,两者的结果可能是不一样的。
二、位逻辑运算
1. 与运算
| A | B | A & B |
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 0 |
2. 或运算
| A | B | A | B |
| 1 | 1 | 1 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
3. 非运算
| A | !A |
| 1 | 0 |
| 0 | 1 |
4. 异或运算
| A | B | A ^ B |
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
5. 同或运算
| A | B | !(A ^ B) |
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 1 |
6. 逻辑运算应用
6.1 位清 0
有的时候我们需要将一个数据的某一位清 0 而又不希望影响其他位的数据,我们可以这样来写:
c
a = a & (~(1 << n)); /* 将 a 的第 n 位清 0 ,其他位保持不变,n 从 0 开始计算 */**【语句分析】**假设 a 为 32 位数据, n 为第 3 位,目的是将第 3 位清 0 ,而不影响其他位:
md
n : 3
(1 << n) : 00000000 00000000 00000000 00001000
(~(1 << n)) : 11111111 11111111 11111111 11110111
a : 11111111 11111111 11111111 11111111
a & (~(1 << n)) : 11111111 11111111 11111111 111101116.2 位置 1
有的时候我们需要将一个数据的某一位置 1 而又不希望影响其他位的数据,我们可以这样来写:
c
a = a | (1 << n); /* 将 a 的第 n 位置 1 ,其他位保持不变, n 从 0 开始计算 */**【语句分析】**假设 a 为 32 位数据, n 为第 3 位,目的是将第 3 位置 1 ,而不影响其他位:
md
n : 3
(1 << n) : 00000000 00000000 00000000 00001000
a : 00000000 00000000 00000000 00000000
a | (1 << n) : 00000000 00000000 00000000 000010006.3 应用实例
【问题】unsigned int a; 将a的第[7:4]位置为0101,其他位保持不变。
【分析过程】
md
unsigned int a : 11111111 00000000 00000000 10101111
/* 1.先清零 */
0xF : 00000000 00000000 00000000 00001111
(0xF << 4) : 00000000 00000000 00000000 11110000
~(0xF << 4) : 11111111 11111111 11111111 00001111
a : 11111111 00000000 00000000 10101111
a & (~(0xF << 4)) : 11111111 00000000 00000000 00001111
/* 2.再置位 */
0x5 : 00000000 00000000 00000000 00000101
(0x5 << 4) : 00000000 00000000 00000000 01010000
a : 11111111 00000000 00000000 00001111
a | (0x5 << 4) : 11111111 00000000 00000000 01011111
=> a = a & (~(0xF << 4)) | (0x5 << 4);