目录一操作符的分类二原码反码补码1定义2特点3原码反码和补码之间的转化三移位操作符 )四位操作符(,|,^~)1按位与2|按位或3,^按位异或4~按位取反五逗号表达式六函数调用和下标访问1下标引用操作符 [ ]2函数调用操作符 七结构成员访问操作符1结构体八操作符的属性优先级结合性九表达式求值1整型提升2算术转换十例题分析1求一个整数的二进制中1的个数2,改变二进制中的某一位3判断一个数是否为2的次方数十一表达式分析1表达式12表达式23表达式34表达式45表达式一操作符的分类1算术操作符-*/%2移位操作符 3位操作符|^~4赋值操作符-*/%|^5单目操作符!--*-~sizeof(类型6逻辑操作符||7关系操作符!8条件操作符9逗号表达式10下标引用[ ]11函数调用( )12结构成员访问. 、-二原码反码补码1定义整数的二进制表示方式有三种原码反码补码这三种表示方法的二进制序列都由两部分构成符号位和数值位。其中二进制序列的第一位代表符号‘0’表示正‘1’表示负。剩下的位数为数值位。特殊0的原码反码补码都为00000000000000000000000000000000原码一个整数的32位二进制序列例如-3的原码10000000000000000000000000000011反码将原码的数值位全部取反得到的二进制序列例如-3的反码111111111111111111111111111111111100补码将反码1得到的二进制序列例如-3的补码1111111111111111111111111111111111012特点正整数的原码反码补码都相同负整数的三者都不同补充整形数据在内存中存放的是对应的补码3原码反码和补码之间的转化三移位操作符 )1的移位规则左抛弃一位右边补零2的移位规则1逻辑右移右边抛弃左边补零无符号整型2算术右移右边抛弃左边保留原来该位置的数字有符号整型算术右移多位时左边依次保留原来的数字。注意两者都是对整数的补码进行操作生成补码返回值为原码对应的数字错误形式不能移位一个负数例如a- 1 (这种形式是错误的四位操作符(,|,^~)使用注意都是只能对整数的补码进行操作生成补码对所有的补码二进制位进行操作包括符号位1按位与使用按照两个中有一个为0结果就为0两个都为1才为1的规则生成一个新的补码2|按位或使用按照两个中有一个为1结果就为1两个都为0才为0的规则生成一个新的补码展示3,^按位异或使用相同为0相异为1展示运用不引入外部变量实现两个整形的值的交换4~按位取反使用对补码的每一位进行取反展示五逗号表达式语法(exp1exp2exp3……expN)从头到尾依次执行执行的结果为最后一个表达式的结果例子六函数调用和下标访问1下标引用操作符 [ ]操作数一个数组名一个索引值下标2函数调用操作符 第一个操作数是函数名第二个操作数是函数的参数函数调用至少有一个操作数函数名七结构成员访问操作符1结构体结构体是一种自定义的数据类型可以自己创建适合的类型结构是一些值的集合这些值称为成员变量。结构中的每个成员可以是不同类型的变量例如标量数组指针结构体结构体的声明 struct tag{member-list;}variable-list;}; //分号不能省略member-list为成员链表结构体的嵌套八操作符的属性优先级结合性在一个表达式中会有各种各样的操作符这些操作符会有运算顺序其运算顺序就与优先级和结合性有关。优先级运算符的运算优先级结合性当运算符的优先级相同时就要看运算符的结合性一般结合性按照从左到右的顺序进行运算少数按照从右到左顺序例如赋值运算符。主要优先级全部优先级九表达式求值1整型提升表达式中的char类型和short类型的字节大小小于int类型在进行运算时要先转换为普通整形再进行运算这种转换被称为整型提升。补充通用CPU难以实现两个8比特位即1字节直接运算所以要先转化为int类型才能更好计算。整型提升的规则1有符号类型的提升按照二进制的最高位的符号位来提升。2无符号类型的提升高位直接补零。例注意char和short类型是否有符号是不确定的在VS编译器中都默认为有符号的类型。2算术转换当char和double类型相遇时先将char整型提升为int再将char算术转换为double转换先后1,long double2,double3,float4,unsigned long int5,long int7,unsigned int8,int当下面的遇到上面的下面的需要先转化为上面的再进行运算十例题分析1求一个整数的二进制中1的个数分析类比求一个整数的每一位先对10取余数再除以10.依次循环。例如13 二进制最后几位为110113 %26……113/26 6的二进制为1106%23……06/23 3的二进制为113%21……13/21 1的二进制为11%20 不进入循环1/20 结束注意unsigned表示无符号整形可以让-1对应的二进制转化为一个非常大的数的二进制。实现求负数二进制中1的个数第二种求法分析13二进制最后几位0011011的最后几位000001 两者后得到1此时对13的二进制向右移1位去除最右边一位的数再次比对判读是否为一第三种求法分析n(n-1)表达式每次能将二进制中最右侧的1去掉例如 n:1110 n-1:1101 n(n-1):11002,改变二进制中的某一位3判断一个数是否为2的次方数分析n(n-1)可以去掉二进制中的一个1十一表达式分析1表达式1a*bc*de*f这个表达式的执行顺序可以是:1a*b 2,c*d 3,e*f 4, 5,也可以是1a*b 2,c*d 3, 4,e*f 5这两种表达式的运算顺序有所不同当a,b,c,d,e,f为表达式时里面的值相互关联执行顺序就非常关键不同的执行顺序会导致变量的值发生改变。2表达式2c --c;这个表达式是先c--在将c的值相加还是先算c再算c--然后相加结果不得而知这样的写法会引起歧义。3表达式3int i 10;i i-- - --i * ( i -3) * i i这样写在不同的编译器里的执行结果是不同的会引起歧义。4表达式4通过运算优先级只能确定运算顺序但不能确定函数调用的优先级会引起歧义。5表达式5int i 1;int ret (i) (i) (i);是先算两个i再相加再算一个i再相加还是先算三个(i)再相加在不同的编译器中的执行结果不同会引起歧义。总结即使有了运算符的优先级和结合性仍然无法保证运算的优先顺序此时就可能出现错误所以我们要尽量少写复杂的运算代码将代码的运算步骤进行拆分更能保证运算的准确性。