C语言之大小端问题-创新互联

1:大小端名字的由来及发展

公司主营业务:成都网站设计、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出安源免费做网站回馈大家。

 (1)在乔纳森·斯威夫特的著名讽刺小说《格列夫游记》中,小人国内部分裂成Big-endian和Little-endian两派,区别在于一派要求从鸡蛋的大头把鸡蛋打破,另一派要求从鸡蛋的小头把鸡蛋打破。斯威夫特借以讽刺英国的政党之争,在计算机工业中指数据储存顺序的分歧。

    (2)后来计算机通信发展起来后,遇到一个问题就是:在串口等串行通信中,一次只能发送1个字节。这时候我要发送一个int类型的数就遇到一个问题。int类型有4个字节,我是按照:byte0 byte1 byte2 byte3这样的顺序发送,还是按照byte3 byte2 byte1 byte0这样的顺序发送。规则就是发送方和接收方必须按照同样的字节顺序来通信,否则就会出现错误。这就叫通信系统中的大小端模式。这是大小端这个词和计算机挂钩的最早问题。

 (3)现在我们讲的这个大小端模式,更多是指计算机存储系统的大小端。在计算机内存/硬盘/Nnad中。因为存储系统是32位的,但是数据仍然是按照字节为单位的。于是乎一个32位的二进制在内存中存储时有2种分布方式:高字节对应高地址(大端模式)、高字节对应低地址(小端模式)

  (4)现实的情况就是:有些CPU公司用大端(譬如C51单片机);有些CPU用小端(譬如ARM)。(大部分是用小端模式,大端模式的不算多)。于是乎我们写代码时,当不知道当前环境是用大端模式还是小端模式时就需要用代码来检测当前系统的大小端。

2:测试机器大小端模式的测试代码

2.1:使用union来测试机器的大小端

#include
union myunion
{
    int a;
    char b;
};

int little_or_big(void)
{
    myunion u1;
    u1.a = 1;
    return u1.b;
}
int main(void)
{
    int i = little_or_big();
     if(1==i)
    {
        printf("小端模式");
    }
    else
    {
        printf("大端模式");
    }
    return 0;
}

分析:

 首先共用体元素a和b在访问时候都是从低地址开始访问的,u1.a = 1在内存中的存放有两种可能(内存地址从左到右递减),小端模式为 00  00 00 01;大端模式为: 01 00 00 00 ,而共用体u1中的b是char类似,所以我们用u1.b去访问时只能读取到最低地址的值(按char去解析时只会读取一个字节),所以,如果读出u1.b的值为1则说明当前机器是小端模式,读出u1.b的值为0,则说明当前机器是大端模式(这种测试方法要记住,面试时候经常考)

2.2:指针方式来测试大小端

int little_or_big2(void)
{
    int a = 1;
    char  b = *((char *) &a);
    return b;
}

分析:

 选定义变量a= 1,然后将a的指针强制类型转换成char *接着去解应用这个指针,并赋值给b,然后根据b的返回值来确定大小端。其实分析可以发现其本质都是一样的,都是先给一个内存里面存一个char 类型的1,然后使得另一个char 类型的变量b去读取这个内存的值,然后根据读取的值来判断大小端。

3:看似可行但实际不行的大小端测试方法

注:测试方法将测试代码分别放在kile4.0(大端)和gcc(小端)下面去运行,看运行后的结果。

3.1:位运算

理论分析:

 现在将0x1(0001)和0xf(1111)相与假设机器是大端模式,那么相与之后得到的结果是0001;假设机器是小端模式那么相与之后得到的结果是1000,

实际测试:

 理论可行但实际上不行的,原因是位与运算是编译器提供的运算,这个运算是高于内存层次的(或者说&运算在二进制层次具有可移植性,也就是说&的时候一定是高字节&高字节,低字节&低字节,和二进制存储无关)

3.2:移位

理论分析:

 同上假设的大端模式,那么存储的方式是0001,右移1位则把 1 移出去了,所以得到的结果就是0x0;假设是小端模式,那么存储方式是1000,右移1位,则结果是0100

实际测试:

  实际不行,原因同上因为C语言对运算符的级别是高于二进制层次的。右移运算永远是将低字节移除,而和二进制存储时这个低字节在高位还是低位无关的。

3.3:强制类型转换

这里就不再次分析, 实际测试时不行的,原因同上

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网页题目:C语言之大小端问题-创新互联
本文网址:http://myzitong.com/article/diipgd.html