什么是大小端, 程序如何判断大小端? 如何判断所使用系统的字节序?
假设计算机要存储4byte int a = 0x12345678, 通常有2种存储方式: 大端, 和小端. 具体是哪种, 取决于计算机体系结构(硬件)
字节地址(序号)
低->高
|
0 |
1 |
2 |
3 |
大端 |
12 |
34 |
56 |
78 |
小端 |
78 |
56 |
34 |
12 |
判断依据:
大端: 低字节存储高位字节数据, 如序号为0的地址存储了高位字节12;
小端: 低字节存储低位字节数据, 如序号为0的地址存储了低位字节78;
注: a按数值的意义, 从高位字节到低位字节, 分别是: 12, 34, 56, 78
程序判断方法(3种):
#include <stdio.h> #include <stdint.h> typedef union { uint16_t v; uint8_t bytes[2]; // bytes[0] 是小地址,bytes[1]是大地址:w }u16; /* 方法1: 利用联合体进行取不同地址对应数 * 利用联合体, 对2byte 联合体赋值后, 分别检查高低地址字节数据是否为大端特征 * */ void isBigEnding() { u16 a; a.v = 0x1234; if (a.bytes[0] == 0x12 && a.bytes[1] == 0x34) { printf("big ending\n"); } else if (a.bytes[0] == 0x34 && a.bytes[1] == 0x12) { printf("little ending\n"); } else { printf("error value"); } return; } #include <arpa/inet.h> /* 方法2: 利用已知端序的API, 进行比较 * 利用已知的网络序为大端, 而htons是将2byte主机序数据转换成网络序, 判断转换前后是否有变化 * 如果没变化, 则说明为大端; 如果有, 则说明为小端 * */ void isBigEnding2() { uint16_t hport = 0x8000; uint16_t nport = htons(hport); // 网络字节序是大端 printf("number in net byte order is 0x%x\n", nport ); if (hport == nport) { printf("big ending\n"); } else { printf("little ending\n"); } } /* * 方法3:取地址直接转换 */ void isBigEnding3() { uint16_t n = 0x1234; if ( *(uint8_t *)&n == 0x12) { printf("big ending\n"); } else if (*(uint8_t *)&n == 0x34) { printf("little ending\n"); } else { printf("error value"); } } /* 写一个程序判断所使用系统的字节序 */ int main() { isBigEnding(); isBigEnding2(); isBigEnding3(); return 0; }