操作符难点详解

原码、反码、补码

补码怎么来的借鉴b站视频
对于无符号数(unsigned)来说,没有符号位,所有位都是有效位。
以下是有符号数的情况。
整数的二进制表示形式有三种:原码、反码、补码。

正数:原码 = 反码 = 补码。
负数则需要计算。

符号位(最高位)0为正数,1为负数。
1.原码:直接写出二进制序列。
以一个字节为例:在这里插入图片描述
2.但我们发现原码正负相加不正确。2+(-2)=-4,这显然不对啊。

在这里插入图片描述
所以,我们通过绝对值相同的正负数相加等于0得到了负数的补码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
负数的反码:原码的符号位不变,其他位按位取反。
负数的补码:反码的二进制+1.
在这里插入图片描述

原码还可以直接通过补码除了符号位以外取反 再加1得出。

加1取反把加的1变成0,相当于减1,之后加上1就行

P.S.

  • 0可以当成无符号数(都是0)。
  • 内存中存的是补码的二进制序列
  • 整数计算时用的也是补码

移位操作符(都是对补码进行操作,原数不会变)

1. 左移操作符:<<

  • 左边丢弃,右边补0
  • 原数不会变
  • 相当于×2(不要越界)

以int类型的2和-2为例(32bit位)
2 <<1==4
在这里插入图片描述
-2 <<1 == -4
在这里插入图片描述-w150

2.右移操作符:>>

右移分为逻辑右移和算术右移:(大部分编译器是算术右移)

  • 逻辑右移,最高位直接补0,右边丢弃。
  • 算术右移,最高位补原符号位,右边丢弃。

原数不会变
相当于÷2(不要越界)

⚠警告
对于移位操作符,不要移动负数位

int num=10;
num>>-1;//error

位操作符(都是对补码进行操作

种类

1.按位与(&):

2.按位或(|)

3.按位异或(^)

1.两个相同的数异或的结果一定为0。(a^a== 0)
2.任何数与0异或都等于它自己。(a^0== a)
3.异或满足交换律;

用法

(1)不能创建临时变量,实现两个数的交换:

方法一(缺点:当 a 和 b 很大时,把 a+b 的结果放在 a 中,会导致int类型存放不下溢出而发生截断,从而损失精度。)
在这里插入图片描述
方法二 根据按位异或(^)的性质(可读性差,效率低,一般都是用创建临时变量的方法)
在这里插入图片描述
相当于a变成了中间变量。

(2)指定二进制位置,把0变成1再改回去

(3)求整数在内存中二进制的1的个数

方法一(利用十进制与二进制的转换)
在这里插入图片描述

  • 这种方法其实是有问题的,它不能求负数二进制中1的个数。(负数%2不可能==1)
  • 但是可以一开始就用无符号整型来接收或者隐式类型转换,这样所有位都是有效位,负数的补码变成原码,求的是很大正数二进制中1的个数
    1.无符号整型来接收
    在这里插入图片描述
    2.隐式类型转换
    在这里插入图片描述
    3.强制类型转换(错误的案例)只有强制类型转换的n才变成无符号类型,原本的n没变。
    在这里插入图片描述
    方法二(右移操作符:>>加上按位与:&)
  • 一个整数按位与(&)上一个1得到的结果就是该数最低二进制位所代表的数。
  • 右移操作符(>>)可以让一个数的任意二进制位来到最低位。

    方法三(效率最高,最推荐)

    无论正负,减1相当于补码减1,然后与原数按位与。每次循环去掉最低位的那个1。
  • 前面提到过移位操作符的操作数不会变(不是>>=),所以方法二的n不会变。
  • 这个效率最高(有多少1执行几次循环),但会改变原数(所以可以封装成函数用形参来计算)

逻辑操作符

  • 逻辑与(&&)
  • 逻辑或(||)

注意:逻辑操作符在特定情况下会发生"短路"。
当条件1 && 条件2&&条件3……,若条件1为假时,此时整个逻辑表达式直接为假,条件2以及之后的条件将不会被执行。
当条件1 || 条件2 || 条件3……,若条件1为真时,此时整个逻辑表达式直接为真,条件2以及之后的条件将不会被执行。

德·摩根定理
x && y 和 ! ( ! x || ! y )相等
x || y 和 ! ( ! x && ! y )相等

接下来看例题

在这里插入图片描述a++是后置++,先使用后++,所以表达式为假,后面不执行,i为0。


++b为真,后面不执行。i的值不为任何操作数的值,为真是1,为假是0。

sizeof

  • 计算类型或类型创建的变量占用内存的大小,单位是字节
  • sizeof计算的结果是size_t类型

size_t是无符号整型
对size_t类型的数据进行打印,可以使用%zd

  • sizeof后面括号中不是类型的时候,括号可以省略。这说明sizeof不是函数。
  • 所得出的值在编译期确定

在这里插入图片描述
在这里插入图片描述
++没有被执行。

逗号运算符 ( , )

逗号运算符 ( , )是C语言运算符中优先级最低的一种运算符,结合顺序是从左至右,用来顺序求值(最后一个逗号后面表达式的值作为整个表达式的值)
举例说明

在这里插入图片描述
逗号运算符的优先级低于赋值运算符,所以c先被赋值,a>b为假,表达式为0,所以c被赋值成0。

括号的优先级高于赋值运算符,所以先算括号内的表达式,此时计算结果为最后一个表达式的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值