C语言有着丰富多样的功能,与之对应也有着多种多样的操作符和表达式。
一.算数操作符
+ - * / %
这五个操作符中属“%”最为特殊,它的两个操作数都必须是整数,它的运算结果是整除之后的余数。其余的四个操作数的对象可以是整数也可以是浮点数。
对于“/”这个操作符如果两个操作数都是整数的话就执行整数除法,如果其中任意一个是浮点数就执行浮点数除法的操作。
二.移位操作符
移位操作符有两个:<<(左移)和 >>(右移)
所有的数在计算机内存中都以补码存储,根据CPU一次处理数据的能力分为32位,64位......无论是左移还是右移都是移动它所存储的补码。
1.<< 左移操作符
移位规则:左边抛弃,右边补零。
例:12在内存中的存储的格式为
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
12 << 1
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
我们可以很清楚的发现原来的“12”已经变成了“24”,左移一位就相当于乘2。
⚠️移位操作的结果如果没被赋值那么它自身的值并没有变化。
2.>>右移操作符
C语言中对右移操作符的移位规则并没有明确规定。分为逻辑右移和算数右移两种不同的规定。
<1>逻辑右移:左边补零,右边直接丢弃,
<2>算数右移:左边用原该值的符号位代替,右边丢弃。
例:我们用-1来举例说明右移,-1的存储格式为:
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
逻辑右移:-1 >> 1
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
算数右移:-1 >> 1
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
通过这个例子大家可以很清楚的看到算数右移和逻辑右移的区别,逻辑右移把-1从一个负数变成了一个正数,这显然是不对的,所以我们建议大家采取算数右移的方法。
⚠️移位运算不允许移动负数位。
三.位操作符
位操作符有三种:&(按位与),|(按位或)和^(按位异或)三种。
位操作数的对象必须是整数。
四.赋值操作符
赋值操作符在之前的程序代码中经常出现,其操作符有:=、+=等。
注意在连续赋值时,应从右往左赋值。
五.单目操作符
单目操作符有:!(逻辑反操作、非)、&(取地址符)、sizeof(求长度)、~(按位取反)、++、--、*、(类型)等。
⚠️ 需要注意的是:
1. &是取地址符,%p打印地址。
2. sizeof()是操作符,不是函数!
3. ++/--的前置和后置
4. *在这里是间接访问操作符,主要和指针相关。
5. (类型)为强制类型转换操作符。
六.关系操作符
关系操作符主要是:==、>=、<=。
主要出现在条件的比较判断上,如:if语句、for循环等。
七.逻辑操作符
&& (逻辑与) || (逻辑非)
八.条件操作符
exp1 ? exp2 : exp3
九.逗号表达式
exp1 , exp2 , exp3 , ········ expN
所谓逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左到右依次执行。整个表达式的结果是最后一个表达式的结果。
十.下表引用,函数调用和结构成员
[ ] 数组下标引用操作符;
( ) 函数调用操作符。