逻辑运算符的“与”运算。
单片机任何数字的底层运算都是以二进制的形式进行,前面讲的加减乘除也不例外。只不过加减乘除是生活常用的运算,任意给两个十进制的数据让单片机运算,我们都可以凭借既有的生活经验通过口算或者笔算来计算出结果,不需要刻意模拟单片机底层的二进制运算。但是本节讲的“与”运算却不行,它是为二进制而生的,若想使用它,必先把参与运算的数据双双转换成二进制格式的数据,你才能分析“与”运算的含义和规律。“与”运算是以位来进行运算的,位就是代表二进制中的每一位,每一个位只能是0或者1。两个数的“与”运算就是两个数被展开成二进制后的“与”运算。
“与”运算的运算符号是“&”。运算规律是:两个位进行“与”运算,只有两个位都同时是1运算结果才能等于1,,否则,只要其中有一位是0,运算结果都是0.比如:
0&0等于0。
0&1等于0。
1&0等于0。
1&1等于1。
注意,上述的0和1都是指二进制的0和1。
现在举一个完整的例子来分析“与”运算的规律。有两个unsigned char类型的十进制数分别是12和9,求12&9的结果是多少?分析步骤如下:
第一步:先把参与运算的两个数以二进制的格式展开。十进制转二进制的方法请参考前面第13,14,15节的内容。
十进制12的二进制格式是:00001100。
十进制9的二进制格式是:00001001。
第二步:二进制数右对齐,按每一位进行“与”运算。
00001100
&00001001
结果是 00001000。
第三步:把二进制的00001000转换成十六进制是:0x08。转换成十进制是8。所以12&9的结果是8。
上述举的例子只能分析“与”运算的规律,并没有看出“与”运算的意义所在。“与”运算有啥用途呢?其实用途很多,最常见的用途是可以指定一个变量的某位清零,其它位保持不变。比如一个unsigned char类型的变量b,数据长度一共是8位,从右往左:
想让第0位清零,其它位保持不变,只需跟十六进制的0xfe相“与”:b=b&0xfe。
想让第1位清零,其它位保持不变,只需跟十六进制的0xfd相“与”:b=b&0xfd。
想让第2位清零,其它位保持不变,只需跟十六进制的0xfb相“与”:b=b&0xfb。
想让第3位清零,其它位保持不变,只需跟十六进制的0xf7相“与”:b=b&0xf7。
想让第4位清零,其它位保持不变,只需跟十六进制的0xef相“与”:b=b&0xef。
想让第5位清零,其它位保持不变,只需跟十六进制的0xdf相“与”:b=b&0xdf。
想让第6位清零,其它位保持不变,只需跟十六进制的0xbf相“与”:b=b&0xbf。
想让第7位清零,其它位保持不变,只需跟十六进制的0x7f相“与”:b=b&0x7f。
根据上述规律,假设b原来等于十进制的85(十六进制是0x55,二进制是01010101),要想把此数据的第0位清零,只需b=b&0xfe。最终b的运算结果是十进制是84(十六进制是0x54,二进制是01010100)。
现在编写一个程序来练习刚才讲到的内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:
void main() //主程序
{
/*---C语言学习区域的开始---------------------------------------------------------------------------*/
unsigned char a;
unsigned char b=85; //十六进制是0x55,二进制是01010101。
a=12&9;
b=b&0xfe;
GuiWdData0=a; //把a这个变量放到窗口变量0里面显示
GuiWdData1=b; //把b这个变量放到窗口变量1里面显示
/*---C语言学习区域的结束---------------------------------------------------------------------------*/
while(1)
{
initial();
key_service();
display_service();
}
}
复制代码
查看运算结果的方法。如何在坚鸿51学习板上观察变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。按下S9按键不松手就可以切换到十六进制的显示界面,松开手后会自动切换到十进制的界面。16个LED灯显示的就是当前变量的二进制数,亮代表1,灭代表0。上坚鸿51学习板观察程序执行的结果如下:
变量a为8(十六进制是0x08,二进制是00001000)。
变量b为84(十六进制是0x54,二进制是01010100)。
下节预告:逻辑运算符的“或”运算。
(未完待续)转载
|