大端模式和小端模式
2013-11-20 22:21
691 查看
大端模式和小端模式是两个相对的概念。网络字节顺序使用的是大端模式,一般的电脑主机中的字节顺序使用的是小端模式,一些大型的IBM主机除外。
从概念上讲:
大端模式:高字节存放在低地址,低字节存放在高地址
小端模式:高字节存放在高地址,低字节存放在低地址
举个例子:一个数据0x12 34 56 78(代表的是一个16进制数据,16进制的两位表示一个字节),那么它在小端模式中的存储方式
低地址——————————————————高地址
而在大端模式下的存储方式正好相反
低地址——————————————————高地址
再举一个例子:一个十进制的数据100;在32位系统下它的二进制表达为:00000000000000000000000001100100;
低地址——————————————————高地址
在大端模式下的存储方式也是相反的:
低地址——————————————————高地址
上面是大端模式和小端模式的概念性解释,下面就通过几个实例具体的解释小端模式(由于是在32位的个人电脑上进行的测试,因此只能测试小端模式的结果)。测试大小端模式经常用到的就是union联合体,因为它是多个数据共享内存的。
输出结果为:
100
0
因为是小端模式,而且char型a[4]数组和int型变量num共享内存。上面已经分析了100在小端模式下的存储模式:
a[0] a[1] a[2] a[3]
低地址——————————————————高地址
因此上面的输出结果是合理的。
再举一个例子:
其输出结果是:
ffffffff
-1
-1
按照上面的分析也是合理的。
下面就举两个比较繁琐的例子:
输出结果为:
0
120
86
这个时候的union的存储分布是这样的,由于struct的存在union的字节大小为8(注意字节对齐)。那么在对num赋值后它的存储分布为:
a b in2
低地址——————————————————高地址
如果是在union中引入位域结构体会出现什么情况呢?
其输出结果是:
0
1
3
那么该union的存储分布为:
c b a
低地址——————————————————高地址
但为什么这里的位域结构体中的存储分布顺序和结构体中的存储分布顺序不同呢?
而且对上面的例子稍作修改:
即令:u_ts.num = 0x34;
输出结果为:
0
-3
1
其中存储的分布为:
c b a
低地址——————————————————高地址
那么再对上面例子做下更改:
令: u_ts.num = 0x12;
输出结果为:
-2
-4
0
c b a
低地址——————————————————高地址
是不是这可以这样理解:对于位域结构体中某个位域如果它的首位为1,那么它转换为十进制输出的值就为负的;如果首位为0,那么它转换为十进制输出的值就是正的。而且按补码的分析,正好能得到测试出来的结果。
上面有不正确的地方,希望大家指正出来。里面有些我也弄不懂,希望大家能给些解释。
从概念上讲:
大端模式:高字节存放在低地址,低字节存放在高地址
小端模式:高字节存放在高地址,低字节存放在低地址
举个例子:一个数据0x12 34 56 78(代表的是一个16进制数据,16进制的两位表示一个字节),那么它在小端模式中的存储方式
0x78 | 0x56 | 0x34 | 0x12 |
而在大端模式下的存储方式正好相反
0x12 | 0x34 | 0x56 | 0x78 |
再举一个例子:一个十进制的数据100;在32位系统下它的二进制表达为:00000000000000000000000001100100;
01100100 | 00000000 | 00000000 | 00000000 |
在大端模式下的存储方式也是相反的:
00000000 | 00000000 | 00000000 | 01100100 |
上面是大端模式和小端模式的概念性解释,下面就通过几个实例具体的解释小端模式(由于是在32位的个人电脑上进行的测试,因此只能测试小端模式的结果)。测试大小端模式经常用到的就是union联合体,因为它是多个数据共享内存的。
union u_test { char a[4]; int num; }; int main() { union u_test u_ts; memset(&u_ts,0,sizeof(u_ts)); u_ts.num = 100; printf("%d\n", u_ts.a[0]); printf("%d\n", u_ts.a[3]); return 0; }
输出结果为:
100
0
因为是小端模式,而且char型a[4]数组和int型变量num共享内存。上面已经分析了100在小端模式下的存储模式:
a[0] a[1] a[2] a[3]
01100100 | 00000000 | 00000000 | 00000000 |
因此上面的输出结果是合理的。
再举一个例子:
union u_test { char a[4]; int num; }; int main() { union u_test u_ts; memset(&u_ts,0,sizeof(u_ts)); u_ts.num = -1; printf("%x\n", u_ts.num); printf("%d\n", u_ts.a[0]); printf("%d\n", u_ts.a[3]); return 0; }
其输出结果是:
ffffffff
-1
-1
按照上面的分析也是合理的。
下面就举两个比较繁琐的例子:
union u_test { struct s_test { char a; char b; int in2; }s_ts; int num; }; int main() { union u_test u_ts; memset(&u_ts, 0,sizeof(u_ts) ); u_ts.num = 0x12345678; printf("%d\n", u_ts.s_ts.in2); printf("%d\n", u_ts.s_ts.a); printf("%d\n", u_ts.s_ts.b); return 0; }
输出结果为:
0
120
86
这个时候的union的存储分布是这样的,由于struct的存在union的字节大小为8(注意字节对齐)。那么在对num赋值后它的存储分布为:
a b in2
0x78 | 0x56 | 0x34 | 0x12 | 0x00 | 0x00 | 0x00 | 0x00 |
如果是在union中引入位域结构体会出现什么情况呢?
union u_test { struct s_test { char a:2; char b:3; char c:3; }s_ts; int num; }; int main() { union u_test u_ts; memset(&u_ts, 0,sizeof(u_ts) ); u_ts.num = 0x64; printf("%d\n", u_ts.s_ts.a); printf("%d\n", u_ts.s_ts.b); printf("%d\n", u_ts.s_ts.c); return 0; }
其输出结果是:
0
1
3
那么该union的存储分布为:
c b a
011 | 001 | 00 | 0x00 | 0x00 | 0x00 |
但为什么这里的位域结构体中的存储分布顺序和结构体中的存储分布顺序不同呢?
而且对上面的例子稍作修改:
即令:u_ts.num = 0x34;
输出结果为:
0
-3
1
其中存储的分布为:
c b a
001 | 101 | 00 | 0x00 | 0x00 | 0x00 |
那么再对上面例子做下更改:
令: u_ts.num = 0x12;
输出结果为:
-2
-4
0
c b a
000 | 100 | 10 | 0x00 | 0x00 | 0x00 |
是不是这可以这样理解:对于位域结构体中某个位域如果它的首位为1,那么它转换为十进制输出的值就为负的;如果首位为0,那么它转换为十进制输出的值就是正的。而且按补码的分析,正好能得到测试出来的结果。
上面有不正确的地方,希望大家指正出来。里面有些我也弄不懂,希望大家能给些解释。
相关文章推荐
- 大端模式与小端模式
- 详解大端模式和小端模式
- 大端模式和小端模式 网络字节顺序与主机字节顺序
- 大端模式和小端模式
- 大端模式和小端模式
- 详解大端模式和小端模式
- 【转载】详解大端模式和小端模式
- 大端模式和小端模式[转]
- 内存对齐(内存中的数据对齐)、大端模式及小端模式
- 大端模式和小端模式
- 深入理解计算机系统-之-数值存储(一)-CPU大端和小端模式详解
- 有一小段C程序看大端、小端模式
- 位段与大端模式、小端模式
- 大端小端存储模式以及其对Union数据类型的影响
- 大端模式与小端模式、网络字节顺序与主机字节顺序 (经典)
- 网络通信之 字节序转换原理与网络字节序、大端和小端模式
- 大端模式 小端模式
- 大端模式和小端模式
- 小端模式 大端模式
- 详解大端模式和小端模式