大端存储和小端存储及基于c语言的测试函数

大端模式是什么?小端模式又是什么?对系统哪些方面有影响?又如何来查看我的电脑到底是大端还是小端呢?这些问题在文中都将获得解决,一起来看看吧。


首先我们来介绍一下概念:

大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节存储在高地址中。如下图。

大端存储和小端存储及基于c语言的测试函数_第1张图片


小端模式(Little_endian):高字节就存储在高地址中,低字节存储在低地址中。

大端存储和小端存储及基于c语言的测试函数_第2张图片

然后我们来看一段代码:

代码段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:

  1. #include  
  2. union var{  
  3.         long int l;  
  4.         int i;  
  5. };  
  6. main(){  
  7.         union var v;  
  8.         v.l = 5;  
  9.         printf("v.l is %d\n",v.i);  
  10.         v.i = 6;  
  11.         printf("now v.l is %ld! the address is %p\n",v.l,&v.l);  
  12.         printf("now v.i is %d! the address is %p\n",v.i,&v.i);  
  13. }  
  14. 结果:  
  15. v.l is 5  
  16. now v.l is 6! the address is 0xbfad1e2c  
  17. 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语言的测试函数_第3张图片

可以看到c.a为1,确定为小端。

于是我们终于得出答案了:代码段1运行后得出的结果将是04030201.


PS:当然也可以直接查看内存

大端存储和小端存储及基于c语言的测试函数_第4张图片


低地址存的是低位的01,再次验证是小端。

你可能感兴趣的:(杂谈)