当前位置:首页 > c语言位运算
位运算
一、基本概念:
1、概念:C语言提供了对二进制数中的某个位或某几位进行操作的运算符,称为位运算。
2、特点:不再将数据作为一个整体进行运算,而是对数据中的某个或某几个二进制位进行的运算。
3、用途:可直接用于编写系统程序,常用在检测和控制领域。 4、无符号数适用于只有正数和0的场合。(可表示范围:0~2) 5、有符号纯整数的二进制表示有3种形式:(原码、反码、补码) (1)原码:如果用n位二进制表示一个数,用最高位表示符号,最高位为1表示负数,最高位为0表示正数,剩下的n-1位表示数值,数值部分用其绝对值表示,这种表示方法称为原码。
n-1n-1
二进制原码的表示范围:-2 例:十进制55D转换为二进制为:0011 0111B。 十进制-55D转换为二进制为:1011 0111B。 (2)反码:用n位二进制表示数据,仍然用最高位表示符号,1表示负,0表示正,剩下的n-1为表示数值(正数不做任何变换,保持不变,负数符号位不变其余各位按位取反(0变为1,1变为0)),这种表示方法称为反码。(表示的数据范围与原码相同) 例:十进制55D转换为二进制为:0011 0111B 十进制-55D转换为二进制为:1100 1000B。 (3)补码:利用有模运算表示数据的一种方式。 n 如果用n位二进制表示数据,则系统的模是2。 n-1n-1 对任意一个范围在-2≤x<2的数X,其补码表示为: n [X]补=2+X。 例:十进制55D转换为二进制为:1 0000 0000+0011 0111=0011 0111B 十进制-55D转换为二进制为:1 0000 0000-0011 0111=1100 1000B n-1 二、位运算 逻辑位运算符 移位位运算符 符号 含义 符号 含义 按位取反(单目) ~ << 左移(双目) & 按位与(双目) | 按位或(双目) >> 右移(双目) 按位异或(双目) ∧ 1、按位与的作用: (1)全部清零:将一个需要全部清零的数与零做按位与运算。 1 例: 0101 0101 & 0000 0000 0000 0000 (2)部分清零:将一个需要部分清零数与掩码(需要清零的位取 0,其它位取1)做按位与运算。 例: 0101 0101 & 1110 1111 0100 0101 (3)取出数中指定的某些位:将一个需要取出指定位上的数与掩码 (需要取出数据的位是1,不需要取出数据的位是0)做按位与运算。 例:将0101 0101的后4位取出。 0101 0101 & 0000 1111 0000 0101 2、按位异或位运算:相同为0,相异为1。 可将其用在一些特殊场合: (1)翻转:将需要翻转的数一另一个二进制数(需要翻转位是1,不需要翻转位是0)进行按位异或运算。 例:将0101 0101的后4位进行翻转。 0101 0101 ∧ 0000 1111 0101 1010 (2)不用临时变量实现2个变量的交换。 例: x = x∧y; y = y∧x; x = x∧y;(即可完成交换) 3、左移位运算: 一般形式: 运算数 << n 功能:将运算数中的二进制位全部左移n位,n是无符号整数。 注:高端左移后,自动丢弃,低端补0。 例:原数为0000 0100(4D),0000 0100<<1后为:0000 1000(8D)。 4、右移位运算: 一般形式: 运算数 >> n 功能:将运算数中的二进制位全部右移n位,n是无符号整数。 注:低端右移后,自动舍弃,高端补1或补0。 对于符号问题应注意: (1)无符号数右移运算时高端补零。 2 1正数:右移运算高端补0。 (2)有符号数:○ 2负数:右移运算高端补0或补1,(具体补什么, ○ 取决于具体的计算机系统。有的系统补0,称为“逻辑右移”,有的系统补1,称为“算术右移”)。 5、位运算赋值运算符 位运算赋值运算符及其含义 位运算赋值运算符 含义 举例 等价于 &= 位与赋值 a&=b a=a&b |= 位或赋值 a|=b a=a|b ∧= 位异或赋值 a∧=b a=a∧b >>= 右移赋值 a>>=b a=a>>b <<= 左移赋值 a<<=b a=a< (2)移位运算符的优先级低于算术运算符,好于关系运算符; (3)按位与、按位或、按位异或运算符的优先级低于关系运算符,高于逻辑运算符; (4)位运算赋值运算符的优先级较低,与算术赋值运算符相同。 三、位段 1、基本概念:将一个字节中的不同的二进制为划分为几个不同的区域,看作不同的数据,代表不同的数据。通常用在控制领域。 2、位段的定义 一般形式: struct 位段类型明 { type 位段名1:长度1; type 位段名2:长度2; ?? type 位段名n:长度n; }; 例: struct exam1 { unsigned int a:4; /*占4位*/ unsigned int a:2; /*占2位*/ } 3、使用:与结构体的用法基本相同。 1位段成员的类型必须指定为unsigned int型。 注:○ 3 2若某一位段要从另一存储单元(字)单独开始存放,应这样定○ 义:Struct packed_data { unsigned a:1; unsigned b:2; unsigned :0; unsigned c:3; /* 在Turbo C中表示c从第3个字节开始存放 */ }; 3可以定义无名字段。 ○ Struct packed_data { unsigned a:1; unsigned :2; /* 表示这两位空间不用 */ unsigned b:3; unsigned c:4; }; 4一个位段必须存储在同一存储单元(字)中,不能跨越两个单元。○ 如果第一个字不能容纳下一个位段,则该空间不用,而从下一个字开始存放。 5位段的长度不能大于存储单元(字)的长度,也不能定义位段数○组。 6位段可以用整型格式符(%d,%u,%o,%x)进行输出。 ○ 如:printf(“%d,%d,%d”,data.a,data.b,data.c); 7位段可以在数值表达式中引用,它会被系统自动地转换成整型数○ 据来处理。 如:data.a + 5/data.b 是合法的。 附录:(优先级1最高,优先级15最低,运算时,优先级高的先运算) 附如表下 运算关系 优先级 1 运算符 () 括号运算 特征 结合性 初等运算 从左向右 4 [] -> . sizeof() ~ ! * 2 & (type) + - ++ -- * / % + - << >> < <= > >= == != & ∧ | && || ?: = (+,-,*,/,%,&,|,∧,>>,<<)= 数组下标 指向结构成员运算 取结构成员运算 取数据或类型字节运算 位非运算 逻辑非运算 取指针所指对内容运算 取地址运算 强制类型转换 正号 负号 自加 自减 乘法运算 除法运算 求余运算(整数) 加法运算 减法运算 向左移位运算 向右移位运算 小于 小于或等于 大于 大于或等于 等于 不等于 位于运算 位异或运算 位或运算 逻辑与运算 逻辑运算 条件运算 赋值 运算赋值 逗号运算 单目运算 从右向左 3 4 5 双目运算(算术运算) 双目运算(移位运算) 从左向右 从左向右 6 双目运算(关系运算) 从左向右 7 8 9 10 11 12 13 14 15 双目运算(位运算) 从左向右 双目运算从左向右 (逻辑运算) , 三目运算 从右向左 双目运算(赋值运从右向左 算) 从左向右 5
共分享92篇相关文档