编程知识_字节序_位操作

1. 字节序

额外的小知识
1Tbyte=1024Gbyte,
1Gbyte=1024Mbyte,
1Mbyte=1024Kbyte,(1Mb=1024x1024个字节)
1Kbyte=1024byte, (1KB=1024个字节)
1byte=8bit(一个字节由8个二进制位组成)
int i;int类型占4个字节就是4x8=32个bit位(最大可表示的数为2^31-1=2147483647)
double i;double类型占8个字节就是8*8=64个bit位(最大可表示的数为2^63-1)
另外:我们常看到的是int i = 0xff,也就是说0x后面只有两位ff,这种是省略了ff前面的00 00 00六个零,也就是说原本int i = 0x000000ff,因为0xff=0x000000ff表达的意思是一样的,初学者要注意。

假设int a = 0x12345678;16进制数中每位数值占据4 bit;在内存中,是以8个bit作为1byte。因此0x12345678中每两位作为1byte, 其中0x78是低byte,0x12是高byte。
在内存中的存储方式有两种:

0x12345678的低位(0x78)存在低地址,即方式1,叫做小字节序(Little endian);
0x12345678的高位(0x12)存在低地址,即方式2,叫做大字节序(Big endian);

一般的arm芯片都是小字节序,有些处理器,可以置某个寄存器,让整个系统使用大字节序或小字节序。小字节序和大字节序我们又把它叫做大端模式和小端模式,其实变大的含义都是一样的。

2. 位操作

2.1 逻辑移位

在嵌入式开发中,我们只涉及逻辑移位:不关心符号位,都是补0
算术移位,需要分有符号型值和无符号型值:

  • 对于无符号型值,算术移位等同于逻辑移位。
  • 对于有符号型值 ,算术左移等同于逻辑左移;算术右移补的是符号位,正数补0,负数补1。

2.1.1 逻辑左移

int a = 0x123;  int b = a<<2;  // b=0x48C

2.1.2 逻辑右移

int a = 0x123;  int b = a>>2; // b=0x48

2.2 取反

unsigned int   a = 0x123;
unsigned int   b = ~a;   // b的每一位,都是a对应位的取反

2.3 位与

unsigned int a = 0x123;
unsigned int b = 0x456;
unsigned int c = a & b; // c等于a位与b,即:a,b的每一位进行与操作

两位相与,结果如下:

1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0

所以,上述C语言代码的结果如下图所示:

2.4 位或

unsigned int a = 0x123;
unsigned int b = 0x456;
unsigned int c = a | b; // c等于a位或b,即:a,b的每一位进行或操作

两位相或,结果如下:

1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0

所以,上述C语言代码的结果如下图所示:

2.5 置位

unsigned int a = 0x123;
unsigned int b = a | (1<<7) | (1<<8);  // 设置a的bit7, bit8, 赋给b

2.6 清位

unsigned int a = 0x123;
unsigned int b = a & ~((1<<7) | (1<<8));  // 清除a的bit7, bit8, 赋给b

2.7 把某几位设置为某值

比如要把bit7设置为1,把bit8清除为0,这可以分两步操作:先设置bit7,再清除bit8。还有一种情况:bit[8:7]= val, 不知道val的取值是多少,怎么办?先清除bit8、bit7,再或上val,代码如下:

unsigned int a = 0x123;
unsigned int b = a & ~(3<<7);  /* 清除bit7, bit8 */
b = b | (val << 7);            /* 设置bit7, bit8为val */

猜你喜欢

转载自blog.csdn.net/qq_39400113/article/details/109562520