大端小端问题总结及相关面试题

来源:互联网 发布:java上最简单的游戏 编辑:程序博客网 时间:2024/06/07 18:51

昨天有一同学问了我一个关于大端小端的面试题,以前掌握的蛮好的现在突然之间想不起来了,回来翻了翻书,觉得现在有必要写一篇文章来记录一下这个知识点。
大端小端是存储讲的是数据在内存中的存放顺序。大端存储格式就是自数据的高字节存放在低地址中,低字节存放在高地址中。而小端存取就和大端存取恰好相反,小端存储格式即高地址存放字数据的高地址数据,低字节就存放字数据的低地址数据。
举个例子:在32位的机器上存放0X12345678,在小端存储模式下是
这里写图片描述
在大端存储模式下是:
这里写图片描述
对比两种存储模式区别是:字中的存储顺序是不同的,字与字间的存储顺序是相同的。一般我们所使用的X86系统也就是俗称的32位系统采取的是小端存储模式,大端存储格式不是很常见。
数据在结构体或者是共用体之中是按声明顺序存储的,地址是从低地址开始。
讲到这里就可以解决一部分问题了那么下面我们就列出一道题吧

union Student{     int  i;     unsigned char ch[2];}int main(){     Student student;     student.i=0x1420;     printf("%d %d",student.ch[0],ch[1]);     return 0;}

解析:如果在32位小端系统下,那么这段代码输出什么呢。我们来分析一下,因为Student是一个共用体,所以student的大小是4字节,又因为数组中的元素是按照从低地址到高地址存储,所以ch[0]存储的是i的低位,就是十六进制的20,转换为十进制为32,ch[1]存储的是i的高位即为十六进制的14换算为十进制为20,所以输出的值为32,20
再来一个面试题
在32位小端 所有参数用栈传递,那么下面的代码输出的结果是什么?

int main(){     long long a=1,b=2,c=3;     printf("%d %d %d\n",a,b,c);     return 0;}

那么在栈里面是怎么存储呢?
这里写图片描述
左侧为栈顶,右侧为栈底printf函数时最后一个元素先入栈,按照低位存在低地址,栈的地址栈顶到栈底的地址逐渐增加,一个long long类型占8个字节如果按照 int 类型读取的话,就是按4个字节读取的话就是上图中的样子,如果按照long long类型读取的话应该是下面的图:
这里写图片描述
所以输出的就按照最上面的图所以输出为1 0 2
大端小端还会影响到位域成员的存放,例如;

struct{     short bit1:4;     short bit2:9;     short bit3:3;}

那么这个在内存中是怎么存取的呢?
存储是按照一个一个的字节存取的,前一个字节存满才会像下一个字节里面存储,字节里面按照低位存储在低字节高位存储在高字节的规则存储,如果正在存储一个数据时,该字节存储不下就会把剩下的比特位存储在下一个字节的低地址中。举个例子:

在32位小端机器上,下面程序的输出结果是什么?

struct Test{     unsigned short int a:5;     unsigned short int b:5;     unsigned short int c:6;}int main(void){     Test test;     test.a=16;     test.b=4;     test.c=0;     int i=*(short*)&test;     printf("%d\n",i);     return 0;}

按照上面讲的规则这道题中test是怎么在内存中存储的?让我们画个图表示一下在内存中怎么存储:
这里写图片描述
这个用printf函数输出时就像是我们平时读十进制的数是先读高位的。代码中是把test的地址强转为short类型的然后解引用后隐式转换为int类型,所以就 i 按照short类型的分析,那么先从高地址的字节开始读取所以读出来的二进制为00000000 10010000换算为十进制就是144
这就基本上把大端小端中的问题基本弄清楚了,如果还有问题,请评论我们在评论中交流一下,如果我写的文章有问题,请谅解,新手上路请老司机指点,也请在评论中指出,谢谢

原创粉丝点击