不同体系的CPU在内存中的数据存储往往存在着差异。例如,Intel的x86系列处理器将低序字节存储在起始地址,而一些RISC架构的处理器,如IBM的370主机使用的PowerPC或Motorola公司生产的CPU,都将高序字节存储在起始位置。这两种不同的存储方式被称为little-endian和big-endian。
little-endian是x86系列CPU的数据存储方式,即将低序的部分存储在前面。而big-endian是将高序部分存储在前面。例如,要存储0xF432,little-endian将以32F4存储,而使用big-endian与此相反,将存储为F432,如图13.2所示。
程序p13.1.c讲解了如何判断系统是使用big-endian还是little-endian实现数据存储的。程序中使用的方法如下所示。
 
 
图13.2  big-endian与little-endian方式数据存储示例
(1)利用联合的特点。联合中的数据成员是共享存储空间的,所分配的空间为数据成员中最大所需的内存数。程序定义了名为endian_un的联合体,其中包含两个数据成员,一个是short类型的数据成员(在32位系统上,short类型的长度是2字节),一个是字符类型的字符数组,字符数组的元素个数为short类型的字节数。
程序将var赋值为0x0102。由于联合结构的特点,bits字符串数组中同样存储了0x0102这一数值。通过判断字符串中的低位和高位存储的内容,就可以知道系统是little-endian还是big-endian的。

#include

int main(int argc, char **argv)  {          union {            short  s;        char   c[sizeof(short)];      } un;

un.s = 0x0102;          if (sizeof(short) == 2) {                  if (un.c[0] == 1 && un.c[1] == 2)                          printf("big-endian\n");                  else if (un.c[0] == 2 && un.c[1] == 1)                          printf("little-endian\n");                  else                          printf("unknown\n");          } else                  printf("sizeof(short) = %d\n", sizeof(short));

exit(0);  }

(2)通过强制类型转换实现。程序中通过取flag变量的地址,获得起始空间的存储内容。如果起始空间存储的是数据的低位内容,则表示存储方式为little-endian,否则为big-endian。
程序的具体代码如下:
//使用类型的强制转换实现little-endian与big-endian的判断
int is_little_endian(void)
{
  unsigned short flag=0x4321;
  if (*(unsigned char*)&flag==0x21)
    return 1;
  else
    return 0;
}
使用gcc编译p13.1.c,获得名为p13.1的可执行文件。执行该程序,具体输出如下。可以看到x86系统的内存数据存储方式为little-endian方式。
[program@localhost charter13]$ gcc -o p13.1 p13.1.c 
[program@localhost charter13]$ ./p13.1 
judged by first method, little-endian
judged by second method, little-endian
[program@localhost charter13]$
之所以介绍big-endian和little-endian,是因为这一数据存储方式不仅影响程序在不同硬件平台中的移植,而且在网络编程中也要考虑字节顺序的问题。为了避免兼容性的问题,网络中的数据传输都使用了从高到低的顺序存储方式。因此,如果要将数据从低位字节优先(little-endian)的机器上发往网络,必须首先进行转换。而big-endian的机器是不需要转换的。
Linux系统提供了htons、htonl、ntohs、ntoh这4个函数用于进行字节顺序的转换。其中,h是host的缩写,n表示network。最后一个字符如果是s,表示short类型,如果是l,表示为long类型。4个函数的具体定义如下:
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
 
htonl/htons:表示主机字节顺序转换成网络字节顺序,htonl函数和htons函数的区别在于参数长度存在差异。
 
ntohl/ntohs:表示网络字节顺序转换成主机字节顺序,ntohl函数和ntohs函数的区别在于参数长度存在差异。

判断big endian和little endian的方法的更多相关文章

  1. 数据在内存中的存储方式( Big Endian和Little Endian的区别 )(x86系列则采用little endian方式存储数据)

    https://www.cnblogs.com/renyuan/archive/2013/05/26/3099766.html 1.故事的起源 “endian”这个词出自<格列佛游记>.小 ...

  2. 大端和小端(Big endian and Little endian)

    一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它 ...

  3. 大端和小端(big endian little endian)

    一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它 ...

  4. 整型,长整型,无符号整型等 大端和小端(Big endian and Little endian)

    一.大端和小端的问题 对于整型.长整型.无符号整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian ...

  5. 字符编码笔记:ASCII,Unicode和UTF-8,附带 Little endian和Big endian的解释

    作者: 阮一峰 日期: 2007年10月28日 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步 ...

  6. Big Endian与Litter Endian

    Big Endian是大端,Litter Endian是小端,意思很明了,但是很难记住谁是谁.每次涉及到这个概念的时候,我都会GOOGLE一下,浪费精力. 怎样才能永远记住他们呢?网上搜索了一下,有很 ...

  7. java代码中存在的Big Endian 和 Little Endian

    Big Endian 和 Little Endian 详解 Java中的Big(Little)-endian问题的一种解决方法 主机序和网络序  很重要很重要 几种ip存放形式 Big-Endian和 ...

  8. Unicode、UTF-8、Big Endian、Little Endian、GBK、UCS-2

    一.Unicode.UCS.GBK 1.开始计算机只在美国用.八位的字节一共可以组合出256(2的8次方)种不同的状态.把这些0×20以下的字节状态称为”控制码”.他们又把所有的空 格.标点符号.数字 ...

  9. c#,关于Big Endian 和 Little Endian,以及转换类

    Big Endian:最高字节在地址最低位,最低字节在地址最高位,依次排列. Little Endian:最低字节在最低位,最高字节在最高位,反序排列. 当在本地主机上,无需注意机器用的是Big En ...

  10. js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法

    js捕捉IE窗口失去焦点事件,判断离开页面刷新或关闭的方法 javascript如何捕捉IE窗口失去焦点事件window.onblur = function(e) { //you code}; 弹框的 ...

随机推荐

  1. Makefile技术和应用总结

    如何学习和运用Makefile 怎么写Makefile?不想讲太多如何如何做.Makefile这东西,公司让一两个人来负责就好了,否则一定是一锅粥.每次看到招聘广告里说,要求懂Makefile,懂Li ...

  2. Druid的使用步骤

    一.关于Druid Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource 高效可 ...

  3. 捉BUG记(To Catch a Bug)

    大约有一年整没有写一篇博客了,由于各种原(jia)因(ban)导致闲暇时间要么拿着IPad看岛国奇怪的片(dong)子(hua).要么拿着kindle看各种各样的资(xiao)料(shuo).本来想写 ...

  4. 用c#开发微信 (14) 微统计 - 阅读分享统计系统 4 部署测试 (最终效果图)

    微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享 ...

  5. Javascript 异步加载详解(转)

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...

  6. C语言 队列 顺序结构 实现

    一个能够自动扩容的顺序结构的队列 ArrQueue (GCC编译). /** * @brief C语言顺序结构队列的实现 * @author wid * @date 2013-10-30 * * @n ...

  7. SQL SERVER 数据库查询表和字段信息语句

    --数据库中所有表的信息(很强悍的)    SELECT    表名               =   CASE   WHEN   A.COLORDER=1   THEN   D.NAME   EL ...

  8. MVP

    引自: http://www.cnblogs.com/Leo_wl/archive/2013/05/03/3056299.html http://www.codeproject.com/Article ...

  9. 服务器端json数据文件分割合并解决方案

    问题引入 Json 是什么就不多说了,本文把Json理解成一种协议. 印象之中,Json貌似是前端的专属,其实不然,服务器端组织数据,依然可以用Json协议. 比如说,某公司有一套测评题目(基于Jso ...

  10. HBase在单Column和多Column情况下批量Put的性能对比分析

    作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/11/28/hba ...