什么是大小端, 程序如何判断大小端? 如何判断所使用系统的字节序?

假设计算机要存储4byte int a = 0x12345678, 通常有2种存储方式: 大端, 和小端. 具体是哪种, 取决于计算机体系结构(硬件)
字节地址(序号)
低->高
0
1
2
3
大端
12
34
56
78
小端
78
56
34
12
上面表格都以16进制表示, 省略了"0x".

判断依据:
大端: 低字节存储高位字节数据, 如序号为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;
}
posted @ 2021-05-13 19:26  明明1109  阅读(540)  评论(0编辑  收藏  举报