C语言-大端和小端影响的数据类型
在C语言中,大端和小端主要影响多字节数据类型
包括 int、long、short、float、double 以及包含多字节字段的结构体(struct)类型,不影响 char(单字节类型)。
char 类型
char 类型通常是 1 字节(8位),因此它不受大端或小端的影响。无论是在大端还是小端系统中,1 字节的数据的存储方式都一致。
int, long, short, float, double 等类型
这些数据类型通常占据多个字节,因此会受到字节序的影响。字节序是指在存储多字节数据时,字节的顺序安排方式,主要分为大端(Big-endian)和小端(Little-endian)。int:在大多数系统中,int 通常占用 4 字节。例如,在小端模式下,如果一个 int 值为 0x12345678,则在内存中的存储顺序为:地址 值
0x00 78
0x01 56
0x02 34
0x03 12
而在大端模式下,存储顺序则为:地址 值
0x00 12
0x01 34
0x02 56
0x03 78
long:在不同系统中,long 型可能占用 4 字节或 8 字节。在小端模式下,如果 long 的值为 0x123456789ABCDEF0,则在 8 字节系统中的存储顺序为:地址 值
0x00 F0
0x01 DE
0x02 BC
0x03 78
0x04 56
0x05 34
0x06 12
0x07 00
而在大端模式下,存储顺序为:地址 值
0x00 00
0x01 12
0x02 34
0x03 56
0x04 78
0x05 BC
0x06 DE
0x07 F0
short:short 类型通常占用 2 字节。例如,如果 short 值为 0xABCD,在小端模式下的存储顺序为:地址 值
0x00 CD
0x01 AB
在大端模式下,存储顺序为:地址 值
0x00 AB
0x01 CD
float 和 double:浮点数类型在内存中以 IEEE 754 标准格式表示,分别占用 4 字节(float)和 8 字节(double)。例如,float 值 3.14 的 IEEE 754 表示在小端模式下可能存储为:地址 值
0x00 0xC3
0x01 0xF5
0x02 0x48
0x03 0x40
而在大端模式下为:地址 值
0x00 0x40
0x01 0x48
0x02 0xF5
0x03 0xC3
结构体 (struct) 类型
结构体中的多字节字段(例如 `int`、`long`)也会受到字节序的影响。假设我们定义了如下结构体:
```c
struct Example {
int a; // 4 字节
short b; // 2 字节
long c; // 8 字节
};
```
在小端模式下,`Example` 结构体的实例在内存中的布局可能如下所示(假设 `a` 为 0x12345678,`b` 为 0xABCD,`c` 为 0x1122334455667788):
```
地址 值
0x00 78
0x01 56
0x02 34
0x03 12
0x04 CD
0x05 AB
0x06 00
0x07 00 // 这2个字节的0是结构体的内存对齐, 参考C语言的结构体内存对齐知识
0x08 88
0x09 77
0x0A 66
0x0B 55
0x0C 44
0x0D 33
0x0E 22
0x0F 11
```
而在大端模式下,存储顺序则为:
```
地址 值
0x00 12
0x01 34
0x02 56
0x03 78
0x04 AB
0x05 CD
0x06 00
0x07 00 // 这2个字节的0是结构体的内存对齐, 参考C语言的结构体内存对齐知识
0x08 11
0x09 22
0x0A 33
0x0B 44
0x0C 55
0x0D 66
0x0E 77
0x0F 88
```
需要注意的是,结构体还可能有填充字节(Padding)以对齐数据,这些填充位在不同系统间可能有所差异。例如,为了使 `long` 字段在 8 字节对齐,编译器可能会在 `short b` 和 `long c` 之间插入填充字节,从而使结构体的实际大小超过其字段总大小。
指针类型
指针本身是存储内存地址的变量,因此其存储也取决于系统的字节序。比如在 64 位系统中,一个指针通常占用 8 字节。在小端模式下,假设指针指向的地址为 0x00007FFFDEADBEEF,指针的存储顺序为:
```
地址 值
0x00 EF
0x01 BE
0x02 AD
0x03 DE
0x04 FF
0x05 7F
0x06 00
0x07 00
```
在大端模式下,存储顺序则为:
```
地址 值
0x00 00
0x01 00
0x02 7F
0x03 FF
0x04 DE
0x05 AD
0x06 BE
0x07 EF
```
数组类型
数组的字节序影响主要取决于数组元素的数据类型:单字节类型数组:
如 char 数组(char arr[])也就是字符串,因为每个元素仅占用 1 字节,因此不受大端或小端的影响。例如,char arr[] = {'a', 'b', 'c'} 在大端和小端系统中的存储顺序是相同的。
多字节类型数组:
如 int 数组(int arr[]),每个数组元素是多字节类型,因此它的字节序会在大端和小端系统中有所不同。对于一个 int 数组,在小端系统中,数组中的每个 int 元素都按小端顺序存储(低位字节在低地址);在大端系统中,每个 int 元素按大端顺序存储(高位字节在低地址)。但是,数组的元素顺序不变,只是每个元素的字节内部排列不同。
示例:
int arr[2] = {0x12345678, 0x9ABCDEF0};
在小端系统中,内存布局为:
地址 | 值
0x00 | 0x78
0x01 | 0x56
0x02 | 0x34
0x03 | 0x12
0x04 | 0xF0
0x05 | 0xDE
0x06 | 0xBC
0x07 | 0x9A
在大端系统中,内存布局为:
地址 | 值
0x00 | 0x12
0x01 | 0x34
0x02 | 0x56
0x03 | 0x78
0x04 | 0x9A
0x05 | 0xBC
0x06 | 0xDE
0x07 | 0xF0
从这个示例可以看出,数组的元素顺序在内存中是连续的,但元素内部的字节顺序会随系统的字节序而变化。