大家好
欢迎继续学习C++语言程序设计
这一节我给大家介绍
Sizeof运算和位运算
Sizeof运算是什么呢
是求一个变量或者一种数据类型
它所占的字节数的
那么大家可能会有疑问
我自己定一个变量
我知道它是Short类型
难道我还不知道它多少字节吗
干吗用Sizeof运算去求呢
一个原因是因为有些类型
在C++标准中并没有规定
它确切的一定占多少字节
比如说int类型 double类型
它跟每个实现系统相关
那这个时候我们用sizeof
计算一下这个具体的类型
到底占多少字节就比较方便
另外我们在后续章节中
还会给大家介绍自定义类型
比如说我们自定义一个类
这个类里面有很多数据成员
那么总的来说
整个这个类的对象
会占多少字节呢
有同学说那不管它占
有多少个数据成员
我们就一个一个地数
去加它的字节数也能算出来呀
那么建议大家不要这样
为什么呢
因为有些类里面
会隐含跟你生成一些你没有定义
但它也有存在的数据成员
这样
你看到你定义了几个数据成员
你去加它多少字节不一定准确
所以C++跟我们提供的
这个Sizeof运算非常有用
它可以计算出一种类型的字节数
一个变量
或者一个对象的字节数
另外还有一个非常有特色的运算
就是位运算
我们知道高级语言
它处理数据
基本上应该是以字节为单位的
什么语言处理数据以位为单位呢
那就是机器语言 汇编语言
它是属于层次比较低的语言
但是当初C语言诞生的时候
它的目的
是为了要能够写操作系统的
所以我们知道C语言
是高级语言里面级别最低的
最接近机器语言的
甚至于有的专家管它叫中级语
所以在C语言中呢
就很有特色的一个功能
就是按位去处理信息
所以我们有位运算符
C++把C语言的这个位运算
也继承过来了
所以今天也要给大家介绍
怎么样按位来处理数据
现在我们来看
这个Sizeof运算符
这是一个计算一下
某种类型或者某个变量
某个对象
它占多少个字节的这样一个运算
它的语法形式就是Sizeof
后面加一个括号
然后括号里面可以写类型名
这个就像函数调用一样
但它不是函数
它是一个运算符
或者我们在Sizeof后面
也可以写变量名
表达式都可以
它既可以根据类型名去计算
这个类型占多少存储空间
也可以根据表达式
或者是变量去计算
它们占的存储空间是多少字节
下面我们来看这个离子
Sizeof（short）
如果short类型是两个字节
那么它得出来就是2
sizeof x 那看在当前
这个系统里面变量x
它所属的类型是占多少字节的
那么得出来就会是那个字节数
在C++中呢
很有意思的一组运算
就是位运算
这个是与其他高级语言
不同的地方
我们可以按位来处理数据
我们先看按位与运算
按位与运算的规则呢
是将两个运算的量
按位来对应
每一个位一一对应进行与操作
我们通过这个例子
就可以比较清楚了
假设我们用八位二进制来存放
整数3和整数5
那么我们来看把这两个数
对齐写在这儿
每一位对应来进行与操作
只有当两个位
对应位都是1的时候
结果的对应位是1
对应的两个数的对应位
如果有一个0
结果的对应位就是0
这种按位操作有什么用途呢
当我们编写
底层的硬件接口程序的时候
或者说我们写程序
要存储一些状态
一些标记的时候是很有用的
这里举一个简单的例子
大家来看
如果要将一个数的某一位置0
其他的位不变
我们可以用按位与操作来实现
比如说将字符性变量
a的最低位置0
那我们可以将a跟这个
16进制的fe去作按位与
16进制的fe呢
就是八个二进制位
高位七位都是1 最低位是0
那这样进行按位与以后
1跟谁去作按位与
结果的对应位
原来是0还是0 原来是1还是1
0去跟谁去作按位与
结果的对应位
那么就一定变成0了
所以我们跟这个16进制的fe
去作按位与的话
那么原来变量
它的最低位置0了
这样的话再把它复置回a里面
我们就达到了将a的最低位
置0的这样的效果
还可以用这个达到
取出指定位的效果
我们看这个例子
那么有字符型的变量c
还有int类型的变量a
我们要取出a的最低字节
放到c里面去
这样我们就将a与十六进制的ff
作按位与
那么十六进制的ff呢
它是低八位全是1
高位全是0
那么这样的数跟a去作按位与
结果就保持了a的低八位的原值
a的高位值在结果中
全部变成了0
然后把这样的结果复置给c
那么就是取出了a的最低位
最低八位复到c里面了
跟按位与类型的
还有按位或操作
也是两个数的对应二进制位
一一对应进行运算
进行什么呢 或运算
那么对应位进行或
它的效果是什么呢
如果两个数的对应位都是1
结果是1
一个0 一个1结果也是1
只有两个数的对应位
都是0的时候 结果才为0
我们看看这个例子
我们还是将二进制
单字节二进制3和5进行按位运算
这回是按位或
我们可以看到1和1作按位或
结果为1
1和0作按位或结果为1
0和1作按位或结果也是1
只有0和0作按位或的时候
结果才是0
所以它可以用来将
变量中的某些位置1 其他位不变
比如说我们可以
用这样的按位或操作
让a跟十六进制的ff作按位或
这样就将变量a的低字节
最低八位全部置1了
而它的高位由于是跟0作按位或
所以原值不变
把这个结果值再复置回a里面去
就把a变量里面的内容
最低八位全部设置为1了
按位1或运算
也是一个很有意思的运算
我们通过这个例子
来体会它的效果是什么
好 我们来看这里
我们用八进制的7 1
跟八进制的5 2作按位异或
那我们从结果看到了
对应位不同的时候
结果这一位就是1
不管谁是0 谁是1
只要对应位不同
结果对应位就是1
如果两个数对应位是相同的
不管同为0 还是同为1
那么结果就是0
所以对应位相同 结果该位为0
对应位不同 结果该位为1
这就是异或的作用
那么异或可以用来做什么呢
我们可以用异或操作
使得一个变量里面的指定翻转
我们来看这个例子
比如说我们要使这个二进制数
0 1 1 1 1 0 1 0
它的低四位翻转
那我们就用一个低四位全1
高四位全0的这样一个数
去跟我们要翻转的这个数
去做按位异或
大家看1跟某个位
进行按位异或的话
原来是0就变成1了
原来是1就变0了
0跟某个数作按位异或的话
它原来是1还是1
原来是0还是0 保持不变
所以我们可以用这样的方式
去指定将变量中的某些位翻转
还有一个操作呢是按位取反
这个规则比较简单
就是变量中原来的二进制位
如果是1
经过按位取反都变成0了
如果原来是0的
那经过按位取反就都变成1了
各个位都许翻转
在C++中还有这个移位操作
移位呢又分左移和右移
就是将二进制数据的位数
移动的一个位置
比如说左移运算
那么我们就要考虑了
高位移出去了怎么办呢
左移运算 高位移出去就扔掉
那低位补什么呢 低位补0
那右移运算呢
低位移出去以后 就舍弃
那么高位补什么
这就分算术右移和逻辑右移了
对于无符号数来说呢 高位补0
对于有符号数来说呢
高位补符号位
也就是原来是1表示负数
那么右移以后呢还补1
原来是高位是0表示正数
右移以后还补0
这样的算术右移呢
实际上相当于除以2的效果
那么左以相当于数值
乘以2的效果
那如果说在左移的时候
原来高位是1 移出去舍弃了
再顶上来的这一位是0
那大家就会有疑问了
既然左移有乘以2的效果
那么正负总不会变吧
原来是负的 还得是负
原来是正的 还得是正吧
怎么乘以2 正负还会变呢
如果你发现左移一位
这个数的正负变了
那么实际上就是在乘以2的效果
这个含义下
它溢出了 太大了 表示不下了
当然大多数时候呢
我们用左移 右移
不是用它来做
这个高效率的乘法 除法
大多数时候呢
我们是因为在变量里面
存储了一些标记
可能在有些运算的时候呢
需要这些标记移一下位
总而言之呢
这是C++提供给我们的
可以用的运算
到底用它来实现什么算法
达到什么目的
那根据我们写程序的时候
算法设计的需求来选用