小端机大端机以及数据对齐

主机字节序

CPU支持的数据类型基础:8位,16位,32位,64位,128位

多字节数据的存储:0x12345678。

方案一:高字节数据存储在地址大的一端,低字节数据存储在地址小的一端(小端机Little-endian,Intel CPU采用本存储方案)。

地址: 1000H 1001H 1002H 1003H

数据: 0x78 0x56 0x34 0x12

方案二:高字节数据存储在地址小的一端,低字节数据存储在地址大的一端(大端机,有别的CPU采用本存储方案)。

地址: 1000H 1001H 1002H 1003H

数据: 0x12 0x34 0x56 0x78

判断当前计算机是大端机还是小端机。

/* 
 * 程序功能:判断当前计算机是大端机还是小端机。
 * 小端机:多字节数据的低位字节存放在地址小的字节中
 * 大端机:多字节数据的低位字节存放在地址大的字节中
 * 注意:Intel CPU系列采用的是小端方式存储多字节数据!
 */

//方法一:
int x = 0x12345678;
printf("%s\n", (*((char*)&x)) == 0x78 ? "小端机" : "大端机");
//把x的地址强转为char*类型,然后取这个指针所指的数据


//方法二:
union		//共用体是所有数据类型共享同一个存储单元
{
	int x;
	char c[4];
} u;
	
u.x = 0x12345678;	
printf("%s\n", u.c[0] == 0x78 ? "小端机" : "大端机");

共用体内存表示:

网络字节序:多字节数据,网络通信时是先发送高字节数据,还是先发送低字节数据。

h: host主机; n: network; s: short; l: long

htons:把unsigned short类型从主机序转换到网络序;

htonl 把unsigned long类型从主机序转换到网络序;

ntohs 把unsigned short类型从网络序转换到主机序;

ntohl 把unsigned long类型从网络序转换到主机序;

现在的互联网发送采用的是大端机字节序模式。

数据对齐(alignment):

CPU在存储数据和取数据时,要求2n字节的数据它存储的起始地址必须能被2n整除,然后CUP才能够有效地在一个CPU周期之内取出这个数据(高效),否则CPU得用多个CPU周期取数,然后拼接成你想要取的数(效率低)。

//示例一:
struct
{
	char c;//1
	short s;//2
	int x;	//4
	long l; //4
	float f;//4
	double d;//8
} u;//应该是23字节

printf("结构体大小为:%d字节!\n", sizeof(u));//输出却是24字节,因为存在内存对齐

printf("c的地址为:%p\n", &u.c);
printf("s的地址为:%p\n", &u.s);
printf("x的地址为:%p\n", &u.x);
printf("l的地址为:%p\n", &u.l);
printf("f的地址为:%p\n", &u.f);
printf("d的地址为:%p\n", &u.d);



//示例二:
struct
{
	short s;//2
	int x;//4
	char c;//1
	long l;//4
	float f;//4
	double d;//8
} u;//应该是23字节

printf("结构体大小为:%d字节!\n", sizeof(u));//却是32个字节

printf("s的地址为:%p\n", &u.s);
printf("x的地址为:%p\n", &u.x);
printf("c的地址为:%p\n", &u.c);
printf("l的地址为:%p\n", &u.l);
printf("f的地址为:%p\n", &u.f);
printf("d的地址为:%p\n", &u.d);

示例二图示(示例一类似):

没全部画完

所以再声明数据类型时,最好把占字节数小的放一起,大的放一起,可以节省空间。

Intel CPU支持的数据类型:

整数(无符号整数8位,16位,32位,64位;带符号整数:8位,16位,32位,64位;浮点数:float 32位,double 64位;指针(近指针:内存段段内偏移;原指针:内存段段选择符+段内偏移);BCD码:位/字节/字/双字段;SIMD单指令流多数据流打包数据(字节、字、双字、四字))。

数据类型的四重含义:

1、占不同的存储单元数。

2、取值范围不一样。

3、允许的操作不一样。

4、二进制编码方案不一样(整数:二进制补码;浮点数:IEEE754标准;英文字符:ASCII码;汉字:内码;Java中,字符用Unicode编码(汉字的编码范围:'\u4e00' - '\u9fa5')。)

变量Variable就是内存单元的抽象,不同类型的变量占用不同数目的字节单元,用不同的二进制编码,有不同的存储范围,运行不同的操作。编程语言中的常量Constant和变量都有不同的数据类型。

posted @ 2022-04-06 10:16  宣哲  阅读(186)  评论(0编辑  收藏  举报