一.问题的提出
char c = char ( 0x12345678) ; 在大端机和小端机上的c的结果分别是多少?
答案是:都为0x78
二.分析原因
实际上,不管是大端还是小端一般情况下都是对我们透明的。这只是一种习惯而已:
数据的低位存放在内存的低地址,高位存放在内存的高地址 ----为小端存储
数据的低位存放在内存的高地址,高位存放在内存的低之地 ----为大端存储
但是对已0x12345678这个16进制的数据,它的高地位还是清晰可分的,跟我们写十进制的习惯一样,高低由左至右。
当我们char (0x12345678)强制转换时,因为0x12345678是一个int型变量,所以int强制转换时会发生截断,int型变量会把低地址的内容存入cha的内存单元中。实际山这跟语法有关,跟CPU架构无关,只要是强制转换,int 转换为char,无论是大端还是小端,只取int的低位即可。
三.分析实质性原因
内存地址是由上到下有从左至右依次递增的,小端字节序指低字节位数据存放在内存低地址处, 高字节位数据存放在内存高地址处; 大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。x86的CPU体系结构中,就是使用小端字节序,即低字节数据存放在低地址处,高字节数据存放在高地址处。将int型的数据转化成char型的数据时,我们只取低8位;如果我们的CPU是小端模式,则我们在进行强制类型转换时不需要调整字节内容,非常的方便;如果我们的CPU是大端模式,则我们,需要将高字节地址的数据存入低字节地址,也就是需要调整字节内容。
四.如何判断小端和大端
#include <stdio.h>
int main()
{
int a = 0x1234 ;
char b = *(char*)&a ;
printf("%x\n" , b ) ;
return 0 ;
}
只要答案等于34,那么说明是小端,答案为0那么为大端。
分析一下测试的原理:
(char*)&a是将&a强制转换后的结果,两个都可以理解为指针,虽然两者的值(所指地址)相同,但是他们的类型是不同的,一个是int * 一个是char * ,所指的类型分别为int 和char。所以使用*取值的时候,int指针会取4个字节,但是char指针只会取1个字节。因为指针所指都为变量的低地址,当使用对char*类型指针解引用时只会取得该地址的低地址部分,小端的存储最低字节为34,大端存储最低字节为00。故以此判断。
(参考博客:http://blog.csdn.net/ce123_zhouwei/article/details/7080351)