从大端小端开始

Posted on 2015-06-12 21:46  yzbyzz  阅读(204)  评论(0)    收藏  举报
首先附下百科的解释。
大端模式:数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
小端模式:数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
概念上并不难理解,只是有时容易混淆。
个人的记忆方法是:将数据当做一个字符串顺序处理,从左往右看,如果每个字符(数据)对应的地址变大则为大端;反之则为小端。
 
为什么有大端小端:
电脑的内存单元是一个字节,而int、short等类型的大小不止一个字节。
于是int的4个字节在内存地址中是按照数据高字节对应高地址、低字节对应低地址(即高高低低)或高低低高分为了小端和大端。
 
测试本机为大端小端的方法:
网上看到的做法,多是用union来做的。
 1 #include <stdio.h>
 2 int main(int argc, char **argv)
 3 {
 4     union{
 5         int a;
 6         short b;
 7     }u;
 8     u.a = 0x12345678;
 9     printf("%x\n", u.b);
10     if(u.b == 0x1234)
11         printf("大端");
12     else if(u.b == 0x5678)
13         printf("小端");
14     else
15         printf("Error");
16     return 0;
17 }
View Code

 

这里也重温了C语言中的union这种数据类型。因为根本没用过,所以早已忘了。

这种类型最大的特点是所有成员共享同一块内存空间,编译程序保证分配给联合的内存能够容纳其最大的成员变量。

对其中一个成员赋值时,所有其他成员的值也会被覆盖。当然char类型只会覆盖int类型的部分值。

因此在这里给a赋值时,b的值也变了。而int和short的字节数不同,于是能看出大端小端。

 

 另外一种不用union的做法,本质上思路是相同的:

 1 #include <stdio.h>
 2 int main(int argc, char **argv) {
 3     int a = 0x12345678;
 4     char b = *(char*)&a;
 5     printf("%x\n", b);
 6     if(b == 0x78)
 7         printf("Little-endian\n");
 8     else if(b == 0x12)
 9         printf("Big-endian\n");
10     else
11         printf("Error\n");
12     return 0;
13 }
View Code

 

 在测试过程中发现了变量分配内存时地址也是从高往低的,于是脑洞了能否根据这个来区分大端小端。

然后搜索了变量内存分配顺序,发现了这篇博文

脑洞终结。涨姿势。