位运算是按照二进制位进行底层运算的操作;利用C语言来完成硬件的底层操作;
位运算及位运算符
一个字节 由八个 二进制位组成;字节的最右边一位为最低位,最左边一位为最高位;
与运算
// 编写程序,按位运算求“与”运算结果,验证十六进制9A6E8957和FF按照“与”运算的 结果
#include "stdio.h"
void main(){
long int a,b,c; // long int has 4 bytes?
a=6;
b=5;
c=a&b;// one & represents wei operation
printf("a=%d,b=%d,c=%d\n",a,b,c);
a=0x9A6E8957;
b=0xff;
c=a&b; // sixteen yunsuan
printf("sixteen jinzhi:\n");
printf("a=%x,b=%x,c=%x\n",a,b,c);
}
或运算,异或运算,按位取反运算,位移运算;
*** 位移运算,移出即溢出**
复合赋值运算符,即与“=”组成一块;
需要掌握:数据正数和负数的原码,反码和补码是如何表示的;
位段的结构体定义
位段定义的一般形式为:
struct 位段结构名{
类型说明符 位段名1:位段长度
类型说明符 位段名2:位段长度
类型说明符 位段名3:位段长度
…
类型说明符 位段名n: 位段长度
};
结构体成员必须定义为unsigned或者int 型;
位段的引用
使用位段结构体变量名引用位段成员
一般引用形式为:
位段结构体变量名.位段名
**若是使用指向位段结构体变量的指针,引用位段成员则使用分量运算符“->”,引用位段结构体变量的位段成员;
// 位段结构体的定义与引用
include "stdio.h"
void main(){
struct cell{
unsigned int a:2; //长度两个二进制位
unsigned int b:1;
unsigned int :5; // 无名位段5位不用
unsigned int c:4;
}bits,*pb;
//赋值给各位段最大值
bits.a=3; // 对应转换成二进制
bits.b=1;
bits.c=15;
printf("Decimal: a=%d,b=%d,c=%d\n",bits.a,bits.b,bits.c);
printf("Hexadecimal: a=%x,b=%x,c=%x\n",bits.a,bits.b,bits.c);
pb=&bits;// 结构体变量首地址赋值给pb
// 给各位段赋值超出位段长度最大值的数
pb->a=6;
pb->b=2;
pb->c=16;
printf("Decimal: a=%d,b=%d,c=%d\n",pb->a,pb->b,pb->c);
printf("Hexadecimal: a=%x,b=%x,c=%x\n",pb->a,pb->b,pb->c);
}
掌握:位段是如何定义和使用的;
如何处理一个位段跨长度字节的问题;
使用指向位段结构体变量的指针操作,指向和引用位段成员;
位运算的实际案例
// 编写程序,一个数的二进制码取出字右0位端开始的3-6位二进制数据
程序源码:按照上述的算法编写下面程序
// 编写程序,一个数的二进制码取出字右0位端开始的3-6位二进制数据
void main(){
unsigned int a=0x6A,b=0,c; // get the answer to a;
a>>3; // 使之在右对齐
b=~((~b)<<4); // 这个是得到最右边全是1
c=a&b; // 即求位“与”运算
printf("a=%d,b=%d,c=%d\n",a,b,c);
printf("a=%x,b=%x,c=%x\n",a,b,c);
}