1. 程式人生 > >大端儲存和小端儲存及基於c語言的測試函式

大端儲存和小端儲存及基於c語言的測試函式

大端模式是什麼?小端模式又是什麼?對系統哪些方面有影響?又如何來檢視我的電腦到底是大端還是小端呢?這些問題在文中都將獲得解決,一起來看看吧。

首先我們來介紹一下概念:

大端模式(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:

  1. #include<stdio.h>
  2. union var{  
  3.         longint 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.a為1,確定為小端。

於是我們終於得出答案了:程式碼段1執行後得出的結果將是04030201.

PS:當然也可以直接檢視記憶體


低地址存的是低位的01,再次驗證是小端。