不同体系的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. React Native填坑之旅--动画

    动画是提高用户体验不可缺少的一个元素.恰如其分的动画可以让用户更明确的感知当前的操作是什么. 无疑在使用React Native开发应用的时候也需要动画.这就需要知道RN都给我们提供了那些动画,和每个 ...

  2. Cache 的write back和write through

    分类: LINUX 内核 2009-09-23 16:21 4561人阅读 评论(0) 收藏 举报 cachebufferos存储算法 Cache 的write back和write through ...

  3. iOS 开发者必知的 75 个工具(译文)

    原文地址:http://benscheirman.com/2013/08/the-ios-developers-toolbelt (需FQ)   如果你去到一位熟练的木匠的工作室,你总是能发现他/她有 ...

  4. ubuntn下 nginx+phpstorm 中配置xdebug调试

    xdebug安装和配置说明,主要用于个人学习记录. 一.echo phpinfo(); 搜素xdebug,若未搜素到,则标识未安装或安装失败. 二.拷贝步骤1中输出的所有结果.访问http://xde ...

  5. Linux Kernel 3.11 正式版发布

    Linus 发布 了 3.11 版本的 Linux 内核.该版本值得关注的新特性有: Lustre 分布式文件系统.透明的 ARM 架构的大数据页支持:ARM64 上的 Xen 和 KVM 虚拟化:O ...

  6. VC中LINK 2001 和 LINK 2009 的错误的解决

    最近将两个开源C++项目编译成windows版本的时候遇到很多问题,关键是两个项目经过同事的修改之后,一个项目引用了另一个项目,两个项目的头文件中都有一些跨平台的关于数据类型,以及一些通用函数的定义, ...

  7. C#函数式编程之标准高阶函数

    何为高阶函数 大家可能对这个名词并不熟悉,但是这个名词所表达的事物却是我们经常使用到的.只要我们的函数的参数能够接收函数,或者函数能够返回函数,当然动态生成的也包括在内.那么我们就将这类函数叫做高阶函 ...

  8. eclipse导入Android项目后,项目的名称变为了主Activity的名称

    不要使用File -> Import -> Android -> Existing Android Code into Workspace,而是用 File -> Import ...

  9. jQuery的XX如何实现?——1.框架

    源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙). 下面将使用简化的代码来介绍,主要关 ...

  10. java生成竖排文字图片

    package com.kadang.designer.web.action;import java.awt.Color;import java.awt.Font;import java.awt.Fo ...