数据存储大小端问题

大端和小端,也就是big-endian和little-endian,其实是从描述鸡蛋的部位而引申到计算机地址的描述,也可以说,是从一个俚语衍化来的计算机术语。
如果把一个数看成一个字符串,比如11223344看成”11223344”,末尾是个’\0’,’11’到’44’个占用一个存储单元,那么它的尾端很显然是44,前面的高还是低就表示尾端放在高地址还是低地址,它在内存中的放法非常直观,如下图:
这里写图片描述

对于一个由2个字节组成的16比特位整数,在内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址,这称为小端(little-endian)字节序;另一种方法是将高序字节存储在起始地址,这称为大端(big-endian)字节序。

这里写图片描述
如果将一个32位的整数0x12345678存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。为简单起见,此处使用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),使用OP3表示一个32位数据最低字节LSB(LeastSignificant Byte)。
这里写图片描述
如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。
这里写图片描述
由上表所知,采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将高位存放在高地址。采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。到目前为止,采用大端或者小端进行数据存放,其孰优孰劣也没有定论。

有的处理器系统采用了小端方式进行数据存放,有的处理器系统采用了大端方式进行数据存放。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择。因此在一个处理器系统中,有可能存在大端和小端模式同时存在的现象。这一现象为系统的软硬件设计带来了不小的麻烦,这要求系统设计工程师,必须深入理解大端和小端模式的差别。大端与小端模式的差别体现在一个处理器的寄存器,指令集,系统总线等各个层次中。
用程序判断一个整型数据为大端存储还是小端存储:
方法一:用一个字符指针解引用,获取第一个字节,若为1则为大端存储,为0则为小端存储

#include <stdio.h>
int main()
{
    if (check_sys() == 1)
        printf("小端存储\n");
    else
        printf("大端存储\n");
    system("pause");
    return 0;
}
int check_sys()
{
        int a = 255;
        char *pc = (char*)&a;
        return *pc;//返回值为1小端存储,返回值为0则大端存储
}

方法二:使用union联合:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    union {
        int i;
        char c[sizeof(int)];
    } un;
    un.i = 0x0102;
    if (sizeof(int) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("大端存储\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("小端存储\n");
    }
    system("pause");
}

猜你喜欢

转载自blog.csdn.net/qq_39539470/article/details/80072309