大端模式是什么?小端模式又是什么?对系统哪些方面有影响?又如何来查看我的电脑到底是大端还是小端呢?这些问题在文中都将获得解决,一起来看看吧。
首先我们来介绍一下概念:
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节存储在高地址中。如下图。
小端模式(Little_endian):高字节就存储在高地址中,低字节存储在低地址中。
然后我们来看一段代码:
代码段1:
union
{
int i;
char a[4];
}*p,u;
p = &u;
p->a[0] = 0x01;
p->a[1] = 0x02;
p->a[2] = 0x03;
p->a[3] = 0x04;
p.i的值你觉得应该是多少呢?
在这之前我们先来明确几点:union类型的大小等于其最大数据成员的大小,所有的成员都公用同一地址起始点,也就是说联合体的访问不管对哪个变量的存取都是从union的首地址位置开始的。我们再来看下面这个代码。
代码段2:
- #include<stdio.h>
- union var{
- long int l;
- int i;
- };
- main(){
- union var v;
- v.l = 5;
- printf("v.l is %d\n",v.i);
- v.i = 6;
- printf("now v.l is %ld! the address is %p\n",v.l,&v.l);
- printf("now v.i is %d! the address is %p\n",v.i,&v.i);
- }
- 结果:
- v.l is 5
- now v.l is 6! the address is 0xbfad1e2c
- now v.i is 6! the address is 0xbfad1e2c
通过代码段2的测试,更是验证了上面我们说的那一段话,即在同一时刻只能使用一个数据成员,并且每次使用都是从union的首地址位置开始。代码段2中的联合体定义了2个成员,在主函数中令v.i = 6时打印输出l和i的值以及各自的地址,此时i和l都使用同一地址空间,由由于i是最后赋值的变量,自然l也会变为6且地址相同。
现在我们回看代码段1.通过上面两段解释我们已经明白了如果使用%x(16进制)打印出来,它的结果应当会有两种情况:
04030201
或者
01020304
那么怎么确定到底是哪一个呢?这里就涉及到了大端和小端的判断了。关于大小端的概念已经介绍过了,那让我们废话不多说直接进入判断函数的编写吧。
int check() //判断大小端函数。return 1为小端,return 0为大端。{
typedef union check
{
int i;
char a;
}ch,*p;
ch c;
c.i = 1;
return (c.a == 1); //int i=1时,1这里在二进制中是低位。若c.a==1,则代表了从低位开始读取(低地址),对应小端。
}
通过debug查看return的值:
可以看到c.a为1,确定为小端。
于是我们终于得出答案了:代码段1运行后得出的结果将是04030201.
PS:当然也可以直接查看内存
低地址存的是低位的01,再次验证是小端。