判斷系統大小端方法分析與總結

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   strong   

轉自http://blog.csdn.net/delphiwcdj/article/details/6234383

問題 :如何用程式確認當前系統的儲存模式(大端還是小端)?寫一個C函數,若處理器是Big-endian的,則返回0;若是Little-endian的,則返回1。

情況1:利用數群組類型

  1. #include <cstdio>  
  2. int checkSystem()  
  3. {  
  4.     char s[]="1000";  
  5.     return (s[0]==‘1‘);  
  6. }  
  7. int main()  
  8. {  
  9.     checkSystem()==1 ? printf("Little-endian/n") : printf("Big-endian/n");  
  10.     return 0;  
  11. }  

情況2:利用位移運算

  1. int i = 1;  
  2. if(1>>32 == 0)  
  3.       cout<<"小端模式"<<endl;  
  4. else  
  5.       cout<<" 大端模式"<<endl;  

 

上述方法正確嗎?要理解為什麼不正確?

 

因為不要在數值上做文章,而大小端是嚴格與記憶體掛鈎的東西。如果int a=1; 那麼a&1==1一定成立,因為這是從數值角度運算的,已經給使用者屏蔽掉了大小端的問題。一定要int a=1; *((char*)(&a)) == 1 ,這樣判斷才有效。

下面總結一些有效方法。

方法1:利用union類型 —— 可以利用union類型資料的特點:所有成員的起始地址一致。

  1. #include <cstdio>  
  2. int checkSystem()  
  3. {  
  4.     union check  
  5.     {  
  6.         int i;  
  7.         char ch;  
  8.     }c;  
  9.     c.i=1;  
  10.     return (c.ch==1);  
  11. }  
  12. int main()  
  13. {  
  14.     checkSystem()==1 ? printf("Little-endian/n") : printf("Big-endian/n");  
  15.     return 0;  
  16. }  

 

方法2:對int強制類型轉換

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. int main()  
  4. {  
  5.     int i = 1;  
  6.     (*(char *)&i == 1) ? printf("Little-endian/n") : printf("Big-endian/n");  
  7.     system("pause");  
  8.     return 0;  
  9. }  

 

方法3:使用union和宏定義

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. static union  
  4. {  
  5.     char a[4];  
  6.     unsigned long ul;  
  7. }endian = {{‘L‘, ‘?‘, ‘?‘, ‘B‘}};  
  8. #define ENDIAN ((char)endian.ul)  
  9.   
  10. int main()  
  11. {  
  12.     printf("%c/n", ENDIAN);  
  13.     system("pause");  
  14.     return 0;  
  15. }  

 

補充:
大小端模式對union類型資料的影響。

  1. #include <cstdio>  
  2. union  
  3. {  
  4.     int i;  
  5.     char a[2];  
  6. }*p, u;  
  7. int main()  
  8. {  
  9.     p=&u;  
  10.     p->a[0]=0x39;  
  11.     p->a[1]=0x38;  
  12.     printf("%x/n",p->i);// 3839 (hex.)  
  13.     printf("%d/n",p->i);// 111000 00111001=14393 (decimal)  
  14.     return 0;  
  15. }  

 

分析如所示:
高地址        低地址
—— —— —— ——   int
0   |   0   |  56  |  57   
—— —— —— ——
               —— ——   char
                56  |   57
               —— ——     
這裡需要考慮儲存模式:大端模式和小端模式。
大端模式(Big-endian):資料的低位元組存放在高地址中。
小端模式(Little-endian):資料的低位元組存放在低地址中。
union型資料所佔的空間等於其最大的成員所佔的空間,對union型成員的存取都是相對於該聯合體基地址的位移量為0處開始,即,聯合體的訪問不論對哪個變數的存取都是從union的首地址位置開始。因此,上面程式輸出的結果就顯而易見了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.