c语⾔中按位或赋值给变量,[转载]C语⾔位运算符在单⽚机上的
应⽤
C语⾔位运算符
学过汇编的朋友都知道汇编对位的处理能⼒是很强的,但是C语⾔也能对运算对象进⾏按位操作,从⽽使C语⾔也能具有⼀定的对
硬件直接进⾏操作的能⼒。位运算符的作⽤是按位对变量进⾏运算,但是并不改变参与运算的变量的值。如果要求按位改变变量的值,则要利⽤相应的赋值运算。还
有就是位运算符是不能⽤来对浮点型数据进⾏操作的。C51中共有6种位运算符。
位运算⼀般的表达形式如下:
变量1 位运算符 变量2
位运算符也有优先级,从⾼到低依次是:"~"(按位取反)→"<
→">>"(右移)
→"&"(按位与)→"^"(按位异或)→"|"(按位或)
表7-1是位逻辑运算符的真值表,X表⽰变量1,Y表⽰变量2
X Y ~X ~Y X&Y X|Y X^Y
0 0 1 1 0 0 0
0 1 1 0 0 1 1
1 0 0 1 0 1 1
1 1 0 0 1 1 0
表7-1 按位取反,与,或和异或的逻辑真值表
利⽤以前建⽴起来的实验板,我们来做个实验验证⼀下位运算是否真是不改变参与变量的值,同时学习位运算的表达形式。程序很简单,⽤P1⼝做运算变量,
P1.0-P1.7对应P1变量的最低位到最⾼位,通过连接在P1⼝上的LED我们便可以直观看到每个位运算后变量是否有改变或如何改变。程序如下:
#include
void main(void)
{
unsigned int a;
unsigned int b;
unsigned char temp; //临时变量
P1 = 0xAA; //点亮D1,D3,D5,D7 P1⼝的⼆进制为10101010,为0时点亮LED
for (a=0;a<1000;a++)
for (b=0;b<1000;b++); //延时
temp = P1 & 0x7;
//单纯的写P1|0x7是没有意义的,因为没有变量被影响,不会被编译
/
/执⾏P1|0x7后结果存⼊temp,这时改变的是temp,但P1不会被影响。
//这时LED没有变化,仍然是D1,D3,D5,D7亮
for (a=0;a<1000;a++)
for (b=0;b<1000;b++); //延时
P1 = 0xFF; //熄灭LED
for (a=0;a<1000;a++)
for (b=0;b<1000;b++); //延时
P1 = 0xAA; //点亮D1,D3,D5,D7 P1⼝的⼆进制为10101010,为0时点亮LED
for (a=0;a<1000;a++)
for (b=0;b<1000;b++); //延时
c语言如何去学P1 = P1 & 0x7; //这时LED会变得只有D2灭
/
/因为之前P1=0xAA=10101010
//与0x7位与 0x7=00000111
//结果存⼊P1 P1=00000010 //位为O时点亮LED,电路看第三课
for (a=0;a<1000;a++)
for (b=0;b<1000;b++); //延时
P1 = 0xFF; //熄灭LED
while(1);
//⼤家可以根据上⾯的程序去做位或,左移,取反等等。
}
复合赋值运算符
复合赋值运算符就是在赋值运算符"="的前⾯加上其他运算符。以下是C语⾔中的复合赋值运算符:
+= 加法赋值 >>= 右移位赋值
-= 减法赋值 &= 逻辑与赋值
*= 乘法赋值 |= 逻辑或赋值
/= 除法赋值 ^= 逻辑异或赋值
%= 取模赋值 -= 逻辑⾮赋值
<<= 左移位赋值
复合运算的⼀般形式为:
变量 复合赋值运算符 表达式
其含义就是变量与表达式先进⾏运算符所要求的运算,再把运算结果赋值给参与运算的变量。其实这是C语⾔中⼀种简化程序的⼀种⽅法,凡是⼆⽬运算都可以⽤复合赋值运算符去简化表达。例如:
a+=56等价于a=a+56
y/=x+9 等价于 y=y/(x+9)
很明显采⽤复合赋值运算符会降低程序的可读性,但这样却可以使程序代码简单化,并能提⾼编译的效率。对于初学C语⾔的朋友在编程时最好还是根据⾃⼰的理解⼒和习惯去使⽤程序表达的⽅式,不要⼀味追求程序代码的短⼩。
逗号运算符
如果你有编程的经验,那么对逗号的作⽤也不会陌⽣了。如在VB中"Dim
a,b,c"的逗号就是把多个变量定义为同⼀类型的变量,在C也⼀样,如 "int
a,b,c",这些例⼦说明逗号⽤于分隔表达式⽤。但在C语⾔中逗号还是⼀种特殊的运算符,也就是逗号运算符,可以⽤它将两个或多个表达式连接
起来,形成逗号表达式。逗号表达式的⼀般形式为:
表达式1,表达式2,表达式3……表达式n
这样⽤逗号运算符组成的表达
式在程序运⾏时,是从左到右计算出各个表达式的值,⽽整个⽤逗号运算符组成的表达式的值等于最右边表达式的值,就是"表达式n"的值。在实际的应⽤中,⼤
部分情况下,使⽤逗号表达式的⽬的只是为了分别得到名个表达式的值,⽽并不⼀定要得到和使⽤整个逗号表达式的值。要注意的还有,并不是在程序的任何位置出
现的逗号,都可以认为是逗号运算符。如函数中的参数,同类型变量的定义中的逗号只是⽤来间隔之⽤⽽不是逗号运算符。
条件运算符
上⾯我们说过C语⾔中有⼀个三⽬运算符,它就是"?:"条件运算符,它要求有三个运算对象。它可以把三个表达式连接构成⼀个条件表达式。条件表达式的⼀般形式如下:
逻辑表达式? 表达式1 : 表达式2
条件运算符的作⽤简单来说就是根据逻辑表达式的值选择使⽤表达式的值。当逻辑表达式的值为真时(⾮0值)时,整个表达式的值为表达式1的值;当逻辑表
达式的值为假(值为0)时,整个表达式的值为表达式2的值。要注意的是条件表达式中逻辑表达式的类型可以与表达式1和表达式2的类型不⼀样。下⾯是⼀个逻
辑表达式的例⼦。
如有a=1,b=2这时我们要求是取ab两数中的较⼩的值放⼊min变量中,也许你会这样写:
if (a
min = a;
else
min = b; //这⼀段的意思是当a< P>
⽤条件运算符去构成条件表达式就变得简单明了了:
min = (a
很明显它的结果和含意都和上⾯的⼀段程序是⼀样的,但是代码却⽐上⼀段程序少很多,编译的效率也相对要⾼,但有着和复合赋值表达式⼀样的缺点就是可读
性相对效差。在实际应⽤时根据⾃⼰要习惯使⽤,就我⾃⼰来说我喜欢使⽤较为好读的⽅式和加上适当的注解,这样可以有助于程序的调试和编写,也便于⽇后的修
改读写。
指针和地址运算符
在第四课我们学习数据类型时,学习过指针类型,知道它是⼀种存放指向另⼀个数据的地址的变量类型。指针
是C语⾔中⼀个⼗分重要的概念,也是学习C语⾔中的⼀个难点。对于指针将会在第九课中做详细的讲解。在这⾥我们先来了解⼀下C语⾔中提供的两个专门⽤于指
针和地址的运算符:
* 取内容
& 取地址
取内容和地址的⼀般形式分别为:
变量 = * 指针变量
指针变量 = & ⽬标变量
取内容运算是将指针变量所指向的⽬标变量的值赋给左边的变量;取地址运算是将⽬标变量的地址赋
给左边的变量。要注意的是:指针变量中只能存放地址(也就是指针型数据),⼀般情况下不要将⾮指针类型的数据赋值给⼀个指针变量。
下⾯来看⼀个例⼦,并⽤⼀个图表和实例去简单理解指针的⽤法和含义。
设有两个unsigned int 变量 ABC处CBA 存放在0x0028,0x002A中
另有⼀个指针变量 portA 存放在0x002C中
那么我们写这样⼀段程序去看看*,&的运算结果
unsigned int data ABC _at_ 0x0028;
unsigned int data CBA _at_ 0x002A;
unsigned int data *Port _at_ 0x002C;
#include
#include
void main(void)
{
SCON = 0x50; //串⼝⽅式1,允许接收
TMOD = 0x20; //定时器1定时⽅式2
TH1 = 0xE8; //11.0592MHz 1200波特率
TL1 = 0xE8;
TI = 1;
TR1 = 1; //启动定时器
ABC = 10; //设初值
CBA = 20;
Port = &CBA; //取CBA的地址放到指针变量Port
*Port = 100; //更改指针变量Port所指向的地址的内容
printf("1: CBA=%dn",CBA); //显⽰此时CBA的值
Port = &ABC; //取ABC的地址放到指针变量Port
CBA = *Port; //把当前Port所指的地址的内容赋给变量CBA
printf("2: CBA=%dn",CBA); //显⽰此时CBA的值
printf(" ABC=%dn",ABC); //显⽰ABC的值
}
程序初始时
值 地址 说明
0x00 0x002DH
0x00 0x002CH
0x00 0x002BH
0x00 0x002AH
0x0A 0x0029H
0x00 0x0028H
执⾏ABC =
10;向ABC所指的地址0x28H写⼊10(0xA),因ABC是int类型要占⽤0x28H和0x29H两个字节的内存空间,低位字节会放⼊⾼地址中,所以0x28H中放⼊0x00,0x29H中放⼊0x0A
值 地址 说明
0x00 0x002DH
0x00 0x002CH
0x00 0x002BH
0x00 0x002AH
0x0A 0x0029H ABC为int类型占⽤两字节
0x00 0x0028H
执⾏CBA = 20;原理和上⼀句⼀样
值 地址 说明
0x00 0x002DH
0x00 0x002CH
0x14 0x002BH CBA为int类型占⽤两字节
0x00 0x002AH
0x0A 0x0029H ABC为int类型占⽤两字节
0x00 0x0028H
执⾏Port = &CBA; 取CBA的⾸地址放到指针变量Port
值 地址 说明
0x00 0x002DH
0x2A 0x002CH CBA的⾸地址存⼊Port
0x14 0x002BH
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论