博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

判断系统大小端方法的总结

Posted on 2015-04-23 12:26  xymaqingxiang  阅读(1213)  评论(0编辑  收藏  举报

何为大小端?

大端模式:字数据的高字节存放在低地址中,而字数据的低字节则存放在高地址中。(低地址存放最高有效字节MSB)

小端模式:与大端存储格式相反,低地址中存放的是字数据的低字节,高地址中存放的是字数据的高字节。(低地址存放最低有效字节LSB)


使用C语言程序判断CPU大小端的方法:


NO1:直接使用看变量的内存值,这里需要一些调试技巧

1 #include<stdio.h>
2 void main()
3 {
4     short s=0x1234;
5     char * pTest=(char*)&s;
6     printf("%p %0X %X",&s,pTest[0],pTest[1]);    
7 }

以十六进制输出short型变量s在内存中分字节分布。

运行结果为:

  0012FF7C

  34 12


NO2:使用C中的共用体union类型:可以利用union类型数据的特点——所有成员的起始地址一致。

     写一个C函数,若处理器是Big_endian的,则返回false;若是Little_endian的,则返回true。

1 bool IsLitte_Endian()
2 {
3     union w{
4     int a;
5     char b;
6     }c;
7     c.a=1;
8     return (c.b==1);
9 }
 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 } 
checkSystem

NO3:强制类型转换,和共用体的做法差不多

1  bool IsLitte_Endian()
2 {
3     int wTest = 0x12345678;
4     short *pTest=(short*)&wTest;
5     return !(0x1234 == pTest[0]);
6 }

补充:对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 }

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