C语言之大小端详解

什么是大小端呢?如果学完C语言你还不知道这个东西那就说明基础太差了。
假设我们有下面这个例子:

int main()
{
    int a = 1;
    return 0;
}

那么这个a在内存中是怎么存储的呢?
编译器给出的结果是:
C语言之大小端详解_第1张图片
看到这个结果是不是有点懵逼,a这个变量值是1 ,在内存中存储应该是0x 00 00 00 01才对啊,为什么编译器给出的却是0x 01 00 00 00
这就是我们要讲到的大小端模式
大端存储:就是把一个数的低位字节序的内容存放到高地址处,高位字节序的内容存放在低地址处。
小端存储:就是把一个数的低位字节序的内容存放到低地址处,高位字节序的内容存放在高地址处。
C语言之大小端详解_第2张图片
那我们又怎么知道电脑到底是按照那哪种方式存储的呢?
接下来介绍几种检测电脑是大端存储还是小端存储的方式:
注意这里说的都是含有字节序的类型的变量,比如int 而char类型的变量就不能用来检测,因为它就一个字节,根本不存在字节序的概念,想检测也检测不了

法一:利用共用体(联合union)来检测(常用)

#include 
int Check_sys()
{
    union Un
    {
        char c;
        int i;
    }un;
    un.i = 1;
    return un.c;
}

int main()
{
    int ret=Check_sys();   
    if (1 == ret)
    {
        printf("当前模式为小端存储\n");
    }
    else
    {
        printf("当前模式为大端存储\n");
    }
    return 0;
}

C语言之大小端详解_第3张图片
为什么用的是共用体来检测大小端而不是结构体来检测呢?
这是因为共用体特殊的底层结构,下面是共用体的模型:
C语言之大小端详解_第4张图片
可以看出来,char类型的变量和int 类型的变量共用的是同一块空间,我们给 i 赋为1 那整个空间都是 1 ,如果返回的是1,那就说明当前模式是小端存储,返回值是0 就说明当前为大端存储。
法二:利用指针
以前我们说过一个整形的指针每次偏移的是4个字节,而一个字符类型的指针每次偏移的是一个字节,那么我们就可以利用这个特性写一个程序来检验:

int Check_sys()
{
    int a = 1;
    //char* p = (char*)&a;
    //return *p;  //大端返回0,小端返回1
    //还可以写成下面的方式:
    return *(char*)&a;
}
int main()
{
    int ret=Check_sys();    //写一个测试的函数
    if (1 == ret)
    {
        printf("当前模式为小端存储\n");
    }
    else
    {
        printf("当前模式为大端存储\n");
    }
    return 0;
}

C语言之大小端详解_第5张图片
据说检测当前机器是大端还是小端存储还有 更多的方法,希望知道的大佬能给小熊提出更多的解决方案。

你可能感兴趣的:(c)