单片机的c语言中的位操作用法(3)
时间:2025-07-14
时间:2025-07-14
郭天祥老师讲述:单片机的c语言中的位操作用法
如下例:
a=0xff; //a=0b11111111
a=~a; //a=0b00000000
1.对小于0的有符号整型变量取相反数
d=-1;
//d为有符号整型变量,赋值为-1,内存表示为0b 11111111 11111111
d=~d+1; //取d的相反数,d=1,内存表示0b 00000000 00000001
此例运用了负整型数在内存以补码方式来存储的这一原理来实现的。负数的补码方式是这样的:负
数的绝对值的内存表示取反加1,就为此负数的内存表示。如-23如果为八位有符号整
型数,则其绝对值23的内存表示为0b00010111,对其取反则为0b11101000,再加1为
0b11101001,即为0XE9,与Keil仿真结果是相吻合的:
2.增强可移植性
关于“增强可移植性”用以下实例来讲解:
假如在一种单片机中unsigned char类型是八个位(1个字节),那么一个此类型的
变量a=0x67,对其最低位清零。则可以用以下方法:
a=0x67; //a=0b 0110 0111
a=a&0xfe; //a=0b 0110 0110
上面的程序似乎没有什么问题,使用0xfe这一因子就可以实现一个unsigned char型的变量最低位清零。
但如果在另一种单片机中的unsigned char类型被定义为16个位(两个字节),那么
这种方法就会出错,如下:
b=0x6767; //假设b为另一种单片机中的unsigned char 类型变量,值为0b 0110
0111 0110 0111
b=b&0xfe; //如果此时因子仍为0xfe的话,则结果就为0b 0000 0000 0110 0110 即
0x0066,而与0x6766不相吻合
上例中的问题就是因为不同环境中的数据类型差异所造成的,即程序的可移植性不好。对于这种情况可
以采用如下方法来解决:
a=0x67; //a=0b 0110 0111
a=a&~1; //在不同的环境中~1将自动匹配运算因子,实现最后一位清零 a=0x66
其中~1为 0b 11111110
b=0x6767; //a=0b 0110 0111 0110 0111
b=a&~1; //~1=0b 1111 1111 1111 1110,b=0b 0110 0111 0110 0110 ,即0x6766
5)左移运算符(<<)
左移运算符用来将一个数的各位全部向左移若干位。如:
a=a<<2
表示将a的各位左移2位,右边补0。如果a=34(0x22或0b00100010),左移2位得0b10001000,即十进制的
136。高位在左移后溢出,不起作用。
从上例可以看到,a被左移2位后,由34变为了136,是原来的4倍。而如果左移1
位,就为0b01000100,即十进制的68,是原来的2倍,很显然,左移N位,就等于乘
以了2N。但一结论只适用于左移时被溢出的高位中不包含‘1’的情况。比如:
a=64; //a=0b 0100 0000
a=a<<2; //a=0b 0000 0000
其实可以这样来想,a为unsigned char型变量,值为64,左移2位后等于乘以了4,即64X4=256,而此种
类型的变量在表达256时,就成为了0x00,产生了一个进位,即溢出了一个‘1’。
在作乘以2N这种操作时,如果使用左移,将比用乘法快得多。因此在程序中适应