zoukankan      html  css  js  c++  java
  • 判断系统大小端方法分析与总结

    转自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的首地址位置开始。因此,上面程序输出的结果就显而易见了。

  • 相关阅读:
    03_ if 练习 _ little2big
    uva 11275 3D Triangles
    uva 12296 Pieces and Discs
    uvalive 3218 Find the Border
    uvalive 2797 Monster Trap
    uvalive 4992 Jungle Outpost
    uva 2218 Triathlon
    uvalive 3890 Most Distant Point from the Sea
    uvalive 4728 Squares
    uva 10256 The Great Divide
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/3859761.html
Copyright © 2011-2022 走看看