? 第一章 C语言概述
? 第二章 数据类型、运算符与表达式
? 第三章 最简单的 C程序设计
? 第四章 逻辑运算和判断选取控制
? 第五章 循环控制
? 第六章 数组
? 第八章 编译预处理
? 第九章 指针
? 第十章 结构体与共用体
? 第十二章 文件的基本操作
? 第十三章 位运算
§ 13- 1位运算概述
? 计算机的特点,数据是以二进制数表示的;
机器指令由二进制数组成的。
二进制数, 0,1
? C语言的 特点, 具有高级语言和低级语言的功能。
低级语言功能的表现,
调用系统功能的函数;
读写 I/O端口的函数;
直接对数据的位或字节进行操作 (只限
于 char型和 int型数据 )。
调用 BIOS中的各中断函数;
? 本章主要介绍位运算。
? C语言中的位操作运算符,
共有 6个,分别如下,
1,~ 作用:按位取反
如, a=10011010
则,~a=01100101
2,<< 作用:按位左移
如, a=10011010
则,a<<2=01101000
3,>> 作用:按位右移
如,a=10011010,b=01010011
则,a>>2=11100110 (a为有符号数 )
4,& 作用:按位与 (1&1=1,1&0=0,0&0=0)
如,a=10011010
则,a&b=00010010
b=01010011
b>>2=00010100 (b为无符号数 )
5,| 作用:按位或 (1|1=1,1|0=1,0|0=0)
6,∧ 作用:按位异或 (1∧ 1=0,1∧ 0=1,0∧ 0=0)
如, a=10011010
则,a∧ b=11001001
b=01010011
如, a=10011010
则,a|b=11011011
b=01010011
§ 13- 2,位运算符的使用方法
? 位运算符分为两类,
1,只有一个变量参与运算,~,<<,>>
2,有两个变量参与运算,&,|,∧
? 位运算时,通常采用的是八进制或十六进制数。
例, main( )
{unsigned int a=0;
printf("%x,%u\n",~a,~a);
}
运行结果,ffff,65535
实际上,a=0000 0000 0000 0000 ?0
~a=1111 1111 1111 1111 ?65535 (十六进制,ffff)
若,a=0000 0000 0000 0001 ?1
则,~a=1111 1111 1111 1110 ?65534 (十六进制,fffe)
2,按位左移,<<
表达式,变量名 <<位数
作用, 把变量名所代表的数中各个位全部左称
若干位,右边空出的位补零。
如,a<<2
a<<3
例,main( )
{ int a=8; (二进制数,00001000)
int b= ?8;
printf("%d\n",a<<2);
printf("%d\n",b<<2);
}
运行结果,32
?32
分析,
a<<2= 0000100000
丢失 补入
结果,左移一位相当于原来的数乘 2。 (条件是
左移不出溢出 )
若,int a=28;
则,a<<2=112
a= 00001000
3,按位右移,>>
表达式,变量名 >>位数
作用,把变量所代表的数中的各个位全部右
移若干位,左边空出的位补 0或补 1。
? 补 0的情况, ? unsigned int 型或 char型的变量;
? int 型的正数。
? 补 1的情况,int 型的负数
如, int a=64 ( 01000000 )
则,a>>2=16 (0001000000 )
补入 丢失
? 称为逻辑右移
如, int a= ?64 (11000000 )
则,a>>2=[a]补码 >>2
=([a]反码 +1)>>2
=(10111111+1)>>2
=(11000000)>>2
=1111000000 ?称为算术右移
补入 丢失
? 若 a≥0,则 a>>x相当于 a整除 2x
? 若 a<0,则 a>>x的结果分两种情况
? 若 a%2x=0,则 a>>x相当于 a整除 2x
? 若 a%2x?0,则 a>>x相当于 (a/ 2x)+1
结论,
4,按位与,& (有零为零 )
? 若有 int a=60,b=10;
即,(a)2=00111100
(b)2=00001010
则,(a&b)2=00001000
(a&b)10=8
? 若有 int a= ?60,b=10;
即,(a)补 = 11000011+1
(b)2= 00001010
则,a&b=0
= 11000100
若 int a= ?60,b=6;
答案,a&b=4
因为, (a)补 = 11000100
则 a&b=?
(b)2= 00000110
所以, (a&b)2=00000100
想一想,
5,按位或,| (有 1为 1)
? 若有 int a=60,b=10;
即,(a)2= 00111100
(b)2= 00001010
则,(a|b)2=00111110
(a|b)10=62
? 若有 int a= ?60,b=10;
即,(a)2= 11000011+1
(b)2= 00001010
则,(a|b)2=11001110
= 11000100
? 还原,10110001+1=10110010
则,(a|b)10= ?50
若 int a= ? 127,b=126;
答案,a|b= ?1
? (a)2=11111111
则 a|b=?
(b)2= 01111110
则,(a|b)2= 11111111
(a)补 = 10000000+1 =10000001
? 还原,10000000+1
? 10000001
? (a|b)2= ?1
想一想,
6,按位异式,? (相同为零 )
? 若有 int a=60,b=10;
即,(a)2=00111100
(b)2=00001010
则,(a?b)2=00110110
(a?b)10=54
? 若 int a= ?60,b=10;
则,(a)补 = 11000011
(b)2= 00001010
(a?b)2= 11001110
? 还原,10110001+1=10110010
则,(a?b)10= ?50