目录
前言
一、算术操作符
二、移位操作符
三、位操作符
四、赋值操作符
五、单目操作符
六、关系操作符
七、逻辑操作符
八、条件操作符
九、逗号表达式
十、下标引用、函数调用和结构成员
十一、表达式求值
前言
整形二进制有原码,反码,补码
原码:数字正负直接按照二进制书写的就是原码
反码:原码符号位不变,其它位按位取反
补码:反码+1
注意:正数原码、反码、补码相同,无符号数也一样
在内存中存储的是补码,在计算时,也是用的补码
打印的是原码
一、算术操作符
+ - * / %
用除法运算符( / ) 计算求浮点数时,/ 左右两个操作数至少有一个为浮点数
取模运算符(%)计算的结果是余数
注意:%运算符的两个操作数只能是整数!
二、移位操作符
<<(左移) >>(右移)
移位操作符移动的是二进制位,且是补码
<< 移位后,左边抛弃,右边补0
>> 分为逻辑右移与算术右移
逻辑右移:右边丢弃,左边补0
算术右移:右边丢弃,左边补原符号位
对于正数而言,两种移位没有区别
对于负数:
VS2019编译器上采用的是算术右移
注意:移位不能移负数位,标准未定义
三、位操作
& (按位与) | (按位或) ^(按位异或)
三者比较的都是二进制位,且是补码
&:同为1,才为1,否则为0
| :有1,就为1,否则为0
^ : 相同为0,相异为1
注意:他们的操作数必须是整数
四、赋值操作符
图中把3这个常量赋给变量a,就是赋值操作符的作用
但有些是不能被赋值的,比如常量
赋值操作符也能连续使用
建议:最好分开来写,代码清晰且易于调试
复合赋值符
+= *= /= <<= >>=等等 例如:a +=b 等价于 a = a+b
注意:区分=与等号(==),在if判断语句中容易出错
五、单目操作符
单目操作符:只有一个操作数的操作符
!(逻辑反操作) 、-(负值)、+(正值)、&(取地址)、sizeof(操作数的类型长度,以字节为单位)
~(对一个数的二进制进行按位取反)、--(分为前置、后置两种)、++(分为前置、后置两种)
*(解引用操作符)、(类型)(强制类型转换)
!:如a = 1,!a = 0,
规定:如a = 0,!a = 1;
- :
+ :不改变原值,常常可以省略
& :常常与指针配合使用
sizeof :计算的是变量所占内存空间或者数组所占内存空间的大小
数组名单独放在sizeof中时,代表的是整个数组
注意:sizeof内部的表达式不参与运算
~ :
前置-- 、++:先--或++,再使用
后置--、++:先使用,再--或++
*:对指针解引用
():
六、关系操作符
> >= < <= == !=
注意:字符串的比较不能用这些运算符,而要用相应的字符串函数
七、逻辑操作符
&&(逻辑与) ||(逻辑或)
&&:从左往右看,只要前面有一个为0,结果就为0,后面的就不再计算
|| : 从左往右看,只要前面有一个为真(非0),结果就为1,后面的就不再计算
注意区分& 与 &&,| 与 ||
八、条件操作符
又称三目操作符
格式:表达式1 ? 表达式2 : 表达式3
问号表示判断,:表示否则,如下图:可翻译为 if (a > b) c = a else c = b
九、逗号表达式
从左往右依次计算,整个表达式算出来的结果是最后一个表达式的结果
十、下标引用、函数调用和结构成员
下标引用[],操作数是数组名和一个索引值
例如:arr[3],arr是数组名,3是索引值
函数调用(),接受一个操作数或者多个操作数,第一个操作数是函数名,其余操作数是要传递给函数的参数
访问结构体成员的操作符
. : 结构体变量.成员
-> : 结构体变量->成员
十一、表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定的
整形提升:适用字符型和短整型
字符型和短整型所占空间只有1byte和2byte,存不下一个普通整形数据(int),就会发生截断
负数的整型提升:高位补1
正数的整型提升:高位补0
无符号数的整形提升:高位补0
对于char和short类型数据而言,只要参与了表达式计算,就会进行整形提升
算术转换:由低精度类型向高精度类型转换
例如:double和float计算时,float会向double类型转换,因为double精度更高
复杂表达式求值的三个影响因素:
操作符的优先级、结合性、是否控制求值顺序
在涉及计算时,有些是有歧义的
例如:表达式:c + --c,只知道++c的优先级比+高,但不知道是左边的c是获取值,还是右边的c计算之后获取值,就会出现1 + 0或者0 + 0两种情况,在VS2019下是后者
所以在用操作符计算时,要保证结果的唯一性,不能出现歧义