1.什么是大小端
在平常的调试过程中,尤其是打开内存监视面板的时候,大家是否想过为什么数据会这样存储,就比如下图的整形变量c,我们明明给他的赋值是16进制的11223344,那他为什么在内存中是反着存储(44332211)的呢?
在解决这个问题前,我们需要先理解大小端的概念
大端:是指大端数据存储模式,简称大端,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
小端:是指小端数据存储模式,简称小端,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的低地址中。
2.为什么要有大小端
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8 bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
3.怎么设计程序来判断当前机器的字节序
在百度2015年系统工程师面试题中就有这样一道题:
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序
在解决这个问题的时候就需要用到我们学的指针解引用相关的知识了,我们知道在对不同的类型解引用的时候,可操作的空间是不一样的,对 int 解引用可以操作4个字节,对 short 解引用的时候可以操作2个字节,对 char 解引用的时候可以操作1个字节
int i = 1;
//二进制: //00000000 00000000 00000000 00000001
//十六进制: //00 00 00 01
我们再观察内存界面
通过这样的比较,我可以知道,我们使用的VS2022编译器使用的是小端字节序,因为他的01(低位)是处于低地址位的;那如果是大端字节序就应该是00 00 00 01(高位在前,低位在后)。在这样的比较中,我们就可以得出结论,对于定义一个整形变量 i=1 如果他的第一个字节是01那就是低位字节序,如果第一个字节是00,那他就是高位字节序。在有了以上的分析后,我们就可以动手设计代码了。
4.代码实现判断
#include <stdio.h> int check_sys() { int i = 1; //用char解引用不能完整的访问int //只能访问第一个字节 //拿到这个字节后就可以进行判断了 return (*(char*)&i); } int main() { int ret = check_sys(); if (ret == 1) //第一个字节为1 { printf("小端\n"); } else //反之则为大端 { printf("大端\n"); } return 0; }