目录
一、运算符的优先级
所谓优先级,就是当多个运算符出现在同一个表达式中时,先执行哪个运算符。C语言中大部分运算符的优先级和数学中是一样的。如果搞不清可以加括号,括号的优先级是最高的,括号中的表达式会优先执行。
所谓结合性,就是当一个表达式中出现多个优先级相同的运算符时,先执行哪个运算符:先执行左边的叫左结合性,先执行右边的叫右结合性。
一个运算符需要 n 个操作数(要计算的数据)就称为 n 目运算符。
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合性 | 说明 |
1 | [ ] | 数组下标 | 数组名[常量表达式] | 左到右 |
|
| () | 圆括号 | (表达式)/函数名(形参表) |
|
|
| . | 成员选择(对象) | 对象.成员名 |
|
|
| -> | 成员选择(指针) | 对象指针->成员名 |
|
|
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
| (类型) | 强制类型转换 | (数据类型)表达式 |
|
|
| ++ | 自增运算符 | ++变量名/变量名++ |
| 单目运算符 |
| -- | 自减运算符 | --变量名/变量名-- |
| 单目运算符 |
| * | 取值运算符 | *指针变量 |
| 单目运算符 |
| & | 取地址运算符 | &变量名 |
| 单目运算符 |
| ! | 逻辑非运算符 | !表达式 |
| 单目运算符 |
| ~ | 按位取反运算符 | ~表达式 |
| 单目运算符 |
| sizeof | 长度运算符 | sizeof(表达式) |
|
|
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
| * | 乘 | 表达式*表达式 |
| 双目运算符 |
| % | 余数(取模) | 整型表达式/整型表达式 |
| 双目运算符 |
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
| - | 减 | 表达式-表达式 |
| 双目运算符 |
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
| >> | 右移 | 变量>>表达式 |
| 双目运算符 |
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
| >= | 大于等于 | 表达式>=表达式 |
| 双目运算符 |
| < | 小于 | 表达式<表达式 |
| 双目运算符 |
| <= | 小于等于 | 表达式<=表达式 |
| 双目运算符 |
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
| != | 不等于 | 表达式!= 表达式 |
| 双目运算符 |
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 |
|
| /= | 除后赋值 | 变量/=表达式 |
|
|
| *= | 乘后赋值 | 变量*=表达式 |
|
|
| %= | 取模后赋值 | 变量%=表达式 |
|
|
| += | 加后赋值 | 变量+=表达式 |
|
|
| -= | 减后赋值 | 变量-=表达式 |
|
|
| <<= | 左移后赋值 | 变量<<=表达式 |
|
|
| >>= | 右移后赋值 | 变量>>=表达式 |
|
|
| &= | 按位与后赋值 | 变量&=表达式 |
|
|
| ^= | 按位异或后赋值 | 变量^=表达式 |
|
|
| |= | 按位或后赋值 | 变量|=表达式 |
|
|
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | 从左向右顺序运算 |
二、算数运算符
| 数学 | C语言 |
加法 | + | + |
减法 | - | - |
乘法 | × | * |
除法 | ÷ | / |
取余 | 无 | % |
对除法的说明
当除数和被除数都是整数时,运算结果也是整数;如果不能整除,就直接丢掉小数部分,只保留整数部分。
一旦除数和被除数中有一个是小数,那么运算结果也是小数,并且是 double 类型的小数。
除数不能为 0,这需在进行算术运算前进行判断。编译器对“除数为 0”这个错误一般无能为力,很多情况下,编译器在编译阶段根本无法计算出除数的值,不能进行有效预测,只能等到程序运行后才能发现错误,而程序一旦在运行阶段出现任何错误,只能有一个结果,那就是崩溃,并被操作系统终止运行。
对取余运算的说明
C语言中的取余运算只能针对整数。
余数可以是正数也可以是负数,结果的符号由 % 左边的整数决定:
算术运算的简写
在C语言中,对变量本身进行运算可以有简写形式。
若用 # 来表示算术运算符,那么 a = a # b可以简写为:a #= b。
注意:a #= b 仅是一种简写形式,不会影响程序的执行效率。
三、自增自减
一个整数类型的变量自身加 1 可以写成 a++;或者 ++a;
相应的,也有a--和--a,它们叫做自减,表示自身减 1。
++和--分别称为自增运算符和自减运算符,它们在循环结构中使用很频繁。
自增自减完成后,会用新值替换旧值,将新值保存在当前变量中。
自增自减的结果必须得有变量来接收,所以自增自减只能针对变量,不能针对数字。
值得注意的是,++ 在变量前面和后面是有区别的:
++ 在前面叫做前自增。前自增先进行自增运算,再进行其他操作。
++ 在后面叫做后自增。后自增先进行其他操作,再进行自增运算。
自减(--)也一样,有前自减和后自减之分。
四、关系运算符
关系运算符(Relational Operators):专门用在判断条件中,让程序决定下一步的操作
关系运算符在使用时,它的的两边都会有一个变量、数据或表达式,关系运算符的作用就是判明这两个式子的大小关系。注意是判明大小关系而不是其他关系。
关系运算符 | 含 义 | 数学中的表示 |
< | 小于 | < |
<= | 小于或等于 | ≤ |
> | 大于 | > |
>= | 大于或等于 | ≥ |
== | 等于 | = |
!= | 不等于 | ≠ |
关系运算符都是双目运算符,其结合性均为左结合。
优先级:<、<=、>、>=的优先级相同,高于==和!=,==和!=的优先级相同。
关系运算符的优先级低于算术运算符,高于赋值运算符。
关系运算符的运算结果只有 0 或 1。当条件成立时结果为 1,条件不成立结果为 0。我们将运算结果 1 称为“真”,表示条件成立,将 0 称为“假”,表示条件不成立。
五、逻辑运算符
逻辑操作符是用来进行逻辑判断的,一般在if、for、while语句里面使用,来进行是否应该进行某种操作(进行逻辑判断)。
运算符 | 说明 | 结合性 | 说明 |
&& | 与运算,双目,对应数学中的“且” | 左结合 | 两个表达式都为真时结果才为真,否则为假 |
|| | 或运算,双目,对应数学中的“或” | 左结合 | 两个表达式都为假时结果才为假,否则为假 |
! | 非运算,单目,对应数学中的“非” | 右结合 | 表达式为真时结果为假,表达式为假时结果为真 |
优先级:赋值运算符(=) < &&和|| < 关系运算符 < 算术运算符 < 非(!)
六、位运算
所谓位运算,就是对一个比特(Bit)位进行操作。
计算过程:先将操作数化为二进制形式存储,然后对所有二进制位进行位运算,得到一个二进制数,再将结果化为十进制。
运算符 | & | | | ^ | ~ | << | >> |
说明 | 按位与 | 按位或 | 按位异或 | 取反 | 左移 | 右移 |
按位与(&)
一个比特(Bit)位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。
例: -9 & 5 的结果为 5
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
& 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
按位或(|)
参与|运算的两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。
按位或运算可以用来将某些位置 1,或者保留某些位。
例:把 n 的高 16 位置 1,保留低 16 位,可以进行n | 0XFFFF0000运算
0XFFFF0000 在内存中的存储形式: 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000
按位异或(^)
参与^运算两个二进制位不同时结果为 1,相同时结果为 0。
按位异或运算可以用来将某些二进制位反转。例如要把 n 的高 16 位反转,保留低 16 位,可以进行n ^ 0XFFFF0000运算(0XFFFF0000 在内存中的存储形式为 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000)。
例:-9 ^ 5的结果是 -14
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
^ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101 (5 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0010 (-14 在内存中的存储)
取反(~)
取反运算符~为单目运算符,右结合性,作用是对参与运算的二进制位取反。
例:~-9的结果为 8
~ 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1000 (9 在内存中的存储)
左移(<<)
左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补0。
如果数据较小,被丢弃的高位不包含 1,那么左移 n 位相当于乘以 2 的 n 次方。
例:(-9)<<3的结果为 -72
<< 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1011 1000 (-72 在内存中的存储)
右移(>>)
右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1。
如果被丢弃的低位不包含 1,那么右移 n 位相当于除以 2 的 n 次方(但被移除的位中经常会包含 1)。
例:(-9)>>3的结果为 -2
>> 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 1110 (-2 在内存中的存储)