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


轉自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的首地址位置開始。因此,上面程序輸出的結果就顯而易見了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM