当前课程知识点:C++语言程序设计基础 > 第2章 C++简单程序设计(一) > 运算与表达式 > Sizeof运算、位运算
Sizeof运算、位运算
l 语法形式
sizeof (类型名)
或 sizeof 表达式
l 结果值:
“类型名”所指定的类型,或“表达式”的结果类型所占的字节数。
l 例:
sizeof(short)
sizeof x
l 运算规则
将两个运算量的每一个位进行逻辑与操作
l 举例:计算3 & 5
l 用途:
n 将某一位置0,其他位不变。
例如:将char型变量a的最低位置0: a = a & 0xfe; ;(0xfe:1111 1110)
n 取指定位。
例如:有char c; int a; 取出a的低字节,置于c中:c=a & 0xff; (0xff:1111 1111)
l 运算规则
n 将两个运算量的每一个位进行逻辑或操作
l 举例:计算3 | 5
l 用途:
n 将某些位置1,其他位不变。
例如:将 int 型变量 a 的低字节置 1 :
a = a | 0xff;
l 运算规则
n 两个操作数进行异或:
若对应位相同,则结果该位为 0,
若对应位不同,则结果该位为 1,
l 举例:计算071^052
l 用途举例:使特定位翻转(与0异或保持原值,与1异或取反)
例如:要使 01111010 低四位翻转:
位运算——取反(~)
l 运算规则
n 单目运算符,对一个二进制数按位取反。
l 例:
025:0000000000010101
~025:1111111111101010
n 左移运算(<<)
左移后,低位补0,高位舍弃。
n 右移运算(>>)
右移后:
低位:舍弃
高位:
无符号数:补0
有符号数:补“符号位”
大家好
欢迎继续学习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++提供给我们的
可以用的运算
到底用它来实现什么算法
达到什么目的
那根据我们写程序的时候
算法设计的需求来选用
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)