大端小端的判断

大端字节序(big-endian)是一种将数据高有效位存放在低内存地址的方式,而数据低有效位存放在高内存地址。

如图是大端机多字节字节序:

如果是带位域的话,比如一个占一字节的结构体:

struct S{
	unsigned char x1 : 2,
                  x2 : 6;
};
struct S s = {s.x1 = 0x0, s.x2 = 0xA };

对于大端机,S的两个位域成员x1和x2都位于内存A所对应的一个字节,并且x1位于该字节的高2比特位,x2位于低6比特位。

对于大端机结构体中位域成员定义的顺序,就是内存中该地址字节中位域的实际存放顺序。

如图,大端机位域的字节序:

小端字节序:是一种将数据低有效位存放在低内存地址的方式,而数据高有效位存放于高内存地址。

图和上面的大端字节序的图是相反的,这里省略。

判断大端还是小端:

#include <stdio.h>
int main(){
	union{
		int n;
		char ch;
	} data;
	data.n = 0x00000001; //也可以直接写作 data.n = 1;
	if(data.ch == 1){
		printf("Little-endian\n");
	}
	else{
		printf("Big-endian\n");
	}
	return 0;
}

共用体的各个成员是共用一段内存的。1 是数据的低位,如果 1 被存储在 data 的低字节,就是小端模式,这个时候 data.ch 的值也是 1。如果 1 被存储在 data 的高字节,就是大端模式,这个时候 data.ch 的值就是 0。

位域的字节序:

#include<stdio.h>
#include<stdlib.h>

struct S{
	unsigned char x1 : 2,
                  x2 : 6;
};

int main()
{
	unsigned char var;
	struct S *p;
	struct S s = {s.x1 = 0x0, s.x2 = 0xA };
	p = &s;

	printf("s.x1 = 0x%x\n", s.x1);
	printf("s.x2 = 0x%x\n", s.x2);
	printf("s = 0x%x\n", *(char*)p);

	var = *(char*)p >> 2;
	printf("v = 0x%x\n", var);

	return 0;
}

结果也是满足小端字节序。00 001010在内存中是001010 00,所以是0x28

猜你喜欢

转载自blog.csdn.net/qq_22080999/article/details/81705608