C语言中的运算符非常丰富,按照功能可分为算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、条件运算符、逗号运算符等。
1.算术运算符
算术运算符
运算符 | 名称或含义 | 操作数要求 | 结合方向 | 说明 |
+ | 加法 | 二元 | 从左到右 | 双目运算符 |
- | 减法 | 二元 | 从左到右 | 双目运算符 |
* | 乘法 | 二元 | 从左到右 | 双目运算符 |
/ | 除法 | 二元 | 从左到右 | 双目运算符 |
% | 求余(取模) | 二元 | 从左到右 | 双目运算符 |
++ | 自增运算符 | 一元 | 从右向左 | 单目运算符 |
-- | 自减运算符 | 一元 | 从右向左 | 单目运算符 |
+ | 正号 | 一元 | 从右向左 | 单目运算符 |
- | 负号 | 一元 | 从右向左 | 单目运算符 |
其中%运算符是算术运算的重点,一般运用于将某个数值控制在一定的范围。
例:将随机一个数控制在范围5以内。
// 设置随机数因子
srand(time(NULL));
// 产生随机数
int ret = rand() % 5; // 将随机数控制在0 - 4
printf("%d\n",ret);
同时,也可以利用余数判断数值的奇偶。
if(num %2 = 0)
//偶数
else
//奇数
自增运算符(++)和自减运算符(--)是两个比较特殊的单目运算符,放在操作数的前置位和后置位效果不同,让我们举个例来看一下。
int a = 10;
int c = ++a; //此时a先自加1,变成11,然后在赋值给c,c为11
int d = a++; //此时a先赋值给d,再自加1,所以d为10,a为11
int e = --a; //此时a先自减1,变成9,然后再赋值给e,e为9
int f = a--; //此时a先赋值给f,再自减1,所以d为10,a为9
//注:c、d、e、f是独立书写运算的,若一起写则a的值会受到影响。
2.赋值运算符
运算符 | 名称或含义 | 操作数要求 | 结合方向 | 说明 |
= | 给变量赋值 | 二元(左侧必须为变量) | 从右向左 | -------- |
运算符 | 含义或名称 | 操作数要求 | 结合方向 | 实例 |
+= | 将右边的操作数加左边的操作数赋 值给左边的操作数 | 二元 | 从右向左 | a+=b 结果:a=a+b |
-= | 将左边的操作数减右边的操作数赋 值给左边的操作数 | 二元 | 从右向左 | a-=b 结果:a=a-b |
*= | 将右边的操作数乘左边的操作数赋 值给左边的操作数 | 二元 | 从右向左 | a*=b 结果:a=a*b |
/= | 将左边的操作数除右边的操作数赋 值给左边的操作数 | 二元 | 从右向左 | a/=b 结果:a=a/b |
%= | 求两个操作数的余赋值给左边的操作数 | 二元 | 从右向左 | a%=b 结果:a=a%b |
<<= | 左移且赋值运算符 | 二元 | 从右向左 | a<<=1 结果:a=a<<1 |
>>= | 右移且赋值运算符 | 二元 | 从右向左 | a>>1 结果:a=>>1 |
&= | 按位与且赋值运算符 | 二元 | 从右向左 | a&=2 结果:a=a&2 |
^= | 按位异或且赋值运算符 | 二元 | 从右向左 | a^=2 结果:a=a^2 |
注意:符合赋值运算符右侧的表达式是一个运算整体,不能将它们分开。例如,y*=x+1表示的是
y=y*(x+1),而不是y=y*x+1
3.关系运算符
运算符 | 含义或名称 | 结合方向 | 操作数要求 | 说明 |
== | 等于 | 从左到右 | 二元 | 双目运算符 |
!= | 不等于 | 从左到右 | 二元 | 双目运算符 |
> | 大于 | 从左到右 | 二元 | 双目运算符 |
< | 小于 | 从左到右 | 二元 | 双目运算符 |
>= | 大于等于 | 从左到右 | 二元 | 双目运算符 |
<= | 小于等于 | 从左到右 | 二元 | 双目运算符 |
4.逻辑运算符
运算符 | 含义或名称 | 结合方向 | 操作数要求 | 说明 |
&& | 与 | 从左到右 | 二元 | 双目运算符 |
|| | 或 | 从左到右 | 二元 | 双目运算符 |
! | 非 | 从右到左 | 一元 | 单目运算符 |
逻辑与(&&):将两个表达式串联起来,当两个表达式都为真时,结果才为真。
逻辑或 (||):将两个表达式并联起来,当两个表达式都为假时,结果才为假。
逻辑反(!):将逻辑真变为逻辑假,将逻辑假变为逻辑真。
注意:C语言为惰性语言,在逻辑运算与中,若左边的表达式为假,则右边的表达式将不被执行。
在逻辑运算或中,若左边的表示为真,则右边的表达式将不被执行。
5.位运算符
运算符 | 含义或名称 | 结合方向 | 操作数要求 | 说明 |
~ | 按位取反 | 从右到左 | 一元 | 单目运算符 |
<< | 左移 | 从左到右 | 二元 | 双目运算符 |
>> | 右移 | 从左到右 | 二元 | 双目运算符 |
| | 按位或 | 从左到右 | 二元 | 双目运算符 |
& | 按位与 | 从左到右 | 二元 | 双目运算符 |
^ | 按位异或 | 从左到右 | 二元 | 双目运算符 |
~(按位取反):按位取反操作会翻转其每一位。运算规则:0变为1,1变为0。
<<(左移):
(无符号) 二进制位向左移动,左边符号位丢弃,右边补齐0。运算规律:向左移动几位,就是乘以2的几次幂。
(有符号)将负数的原码转为补码,将补码进行左移,将左移后的补码再转为原码。
>>(右移):
(有符号)二进制位向右移动,使用符号位进行补位。运算规律:向右移动几位,就是除以2的几次幂(但注意这是按位运算,不完全等同于算术除法)。正数左补0,负数左补1。
(无符号)无论符号位是0还是1,都补0。
|(按位或):参加运算的两个对象,按二进制位进行“或”运算。运算规则:同0为0,有1为1。
&(按位与):参加运算的两个数据,按二进制位进行“与”运算。运算规则:同1为一,其余为0。
^(按位异或):参与运算的两个数据,按二进制位进行“异或”运算。运算规则:相同为0,不同为1。
6.条件运算符
运算符 | 含义或名称 | 结合方向 | 操作数要求 | 说明 |
?: | 条件运算符 | 从右到左 | 三元 | 三目运算符 |
具体来说,三元运算符的语法如下:
其结果必须是一个布尔值(真或假)。
值1
:如果条件为真,则选择这个值作为整个三元运算符的结果。值2
:如果条件为假,则选择这个值作为整个三元运算符的结果。- 例如 exp1?exp2:exp3 如果exp1位真,则执行exp2,不执行exp3;如果exp1位假,则执行exp3,不执行exp2。
7.逗号运算符
运算符 | 含义或名称 | 结合方向 | 操作数要求 | 说明 |
, | 逗号运算符 | 从左想右 | 二元或多元 | ------ |
具体使用:表达式1,表达式2,……,表达式n
先求表达式1的值,再求表达式2的值,依次求表达式……的值,最后再求表达式n的值。表达式n的值为整个逗号表达式的值。
8.其它运算符
(1)sizeof()运算符,单目运算,结合方向是从右至左。主要功能是计算数据类型所占的字节。使用格式为:sizeof(变量名|数据类型标识符|表达式)
(2)()运算符,结合方向是从左至右。主要功能是改变表达式中其它运算符的优先顺序。
(3)[]运算符,结合方向是从左至右。主要功能是表示数组元素下标。
(4)&运算符,取地址运算符,结合方向是从右至左。主要用于取普通变量的地址,不能用于表达式或常量。
(5)*运算符,指针运算符,结合方向是从右至左。主要功能是取指针地址所对应的存储单元的内容。
(6)(类型说明符),强制类型转换运算符,结合方向是从右至左。主要功能是将运算对象转换为括号中说明的类型。
(7)->运算符,结合方向是从左至右。主要功能是通过结构指针引用结构成员。
(8).运算符,结合方向是从左至右。主要功能是通过结构变量引用结构体成员。
9.运算符优先级别
(此图为借鉴)
注:当运算符优先级一样时,参考结合方向。