C语言笔记之二进制

1. 位运算

  1. 按位运算
No. 操作符 功能
1 & 按位与
2 | 按位或
3 ~ 按位取反
4 ^ 按位异或
  1. 运算规则
A B A & B A | B A ^ B
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
  1. 示例

(1)按位与
让某一位或某些位为0

int n = 0xFFFF;
n = n & 0x0010;

截取二进制数中的一段值。

int n = 0xFFab;
n = n & 0x00FF;

(2)按位或
让某一位或某些位为1

int n = 0x0000;
n = n | 0x0010;

拼接两个二进制数。

int a = 0xab00;
int b = 0x0012;
int c = a|b;

(3)按位取反
得到全部为1的数字~0

int n = ~0;// 等同于0xFFFF

使数字的部分清零x& ~7

int n = 0xFFFF;
n = n & ~7;

(4)按位异或
两个相等数异或结果为0

int n = 0x1234;
n = n^n;

对同一个变量两次异或,变会原值。

int a = 0x1234;
int b = 0x1357;
a = a^b;
a = a^b;

逻辑运算与按位运算
1.逻辑运算结果只有01两种值,按位运算有多种值。
2.逻辑运算相当于把所有的非零值都变成1,再按位运算。

2. 移位运算

No. 操作符 功能
1 << 左移
2 >> 右移
  1. 左移
    i<<j表示i中所有位向左移动j个位置,右边填入0
    所有小于int的类型,移位以int大小执行,结果为int
  2. 右移
    i>>j表示i中所有位向右移动j个位置,
    对于unsigned类型,左边填入0;对于signed类型,左边填入符号位。
    所有小于int的类型,移位以int大小执行,结果为int
  3. 位移运算与乘除运算
    位移运算与乘除运算运算有如下对应关系:
No. 位移运算 乘除运算
1 x<<1 x*2
2 x>>1 x/2
3 x<<n x*pow(2,n)
4 x>>n x/pow(2,n)
5 x<<=1 x*=2
6 x>>=1 x/=2
7 x<<=n x*=pow(2,n)
8 x>>=n x/=pow(2,n)

3. 位域

3.1 位域是什么?

位域是又称作位段,是把一个字节中的二进位划分为几个不同的区域。

3.2 位域有什么用?

节省空间,有些信息不需要占用一个完整的字节。

3.3 位域怎么用?

  1. 定义位域
    定义位域与结构定义相仿。

–语法

struct 位域结构名{ 
    类型 位域名:位域长度;
};

为了保证位域的可以移植性,成员类型通常为unsigned intint,C99可以使用bool

–示例

struct Byte{
  unsigned int b1:1;
  unsigned int b2:1;
  unsigned int b3:1;
  unsigned int b4:1;
  unsigned int b5:1;
  unsigned int b6:1;
  unsigned int b7:1;
  unsigned int b8:1;
 };
  1. 位域变量
    定义和使用位域变量与结构体相同。每个域有一个域名,允许在程序中按域名进行操作。
void printByte(struct Byte a){
  printf("%d",a.b1);
  printf("%d",a.b2);
  printf("%d",a.b3);
  printf("%d",a.b4);
  printf("%d",a.b5);
  printf("%d",a.b6);
  printf("%d",a.b7);
  printf("%d\n",a.b8);
}
int main () {
struct Byte a;
printByte(a);
struct Byte b = {1,0,1,0,1,0,1,0,};
printByte(b);
return 0;
}
  1. 位域大小
printf("sizeof(Byte) = %ld\n",sizeof(Byte));
struct Byte{
    unsigned char b1:1;
    unsigned char b2:1;
    unsigned char b3:1;
    unsigned char b4:1;
    unsigned char b5:1;
    unsigned char b6:1;
    unsigned char b7:1;
    unsigned char b8:1;
};

位域的存储由编译器实现决定。编译器规定存储单元大小(8位、16位、32位)。 编译器会把位域逐个放入存储单元,位域之间没有间隙,直到存储单元放不下下一个位域,然后从下个存储单元继续存放。也有编译器跨存储单元存放。存放顺序也是编译器决定。
整个结构体的总大小为最宽基本类型成员大小的整数倍。

发布了48 篇原创文章 · 获赞 5 · 访问量 2391

猜你喜欢

转载自blog.csdn.net/weixin_44718794/article/details/103965363
今日推荐