简单点说,就是字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如int,double等,就要考虑存储的顺序了。注意字节序是硬件层面的东西,对于软件来说通常是透明的。再说白一点,字节序通常只和你使用的处理器架构有关,而和编程语言无关,比如常见的Intel x86系列就是小端序。

Big-endian(大端序)

数据的高位字节存放在地址的低端 低位字节存放在地址高端

Little-endian(小端序)

数据的高位字节存放在地址的高端 低位字节存放在地址低端

字节的高位与低位
举个例子,int a = 0x12345678 ; 那么左边12就是高位字节,右边的78就是低位字节,从左到右,由高到低,(注意,高低乃相对而言,比如56相对于78是高字节,相对于34是低字节)

地址的高端与低端
0x00000001
0x00000002
0x00000003
0x00000004
从上倒下,由低到高,地址值小的为低端,地址值大的为高端。

不同字节序如何存储数据?

看看两种方式如何存储数据,假设从地址0x00000001处开始存储十六进制数0x12345678,那么

Bit-endian 如此存放(按原来顺序存储)
0x00000001           -- 12
0x00000002           -- 34
0x00000003           -- 56
0x00000004           -- 78

Little-endian 如此存放(颠倒顺序储存)
0x00000001           -- 78
0x00000002           -- 56
0x00000003           -- 34
0x00000004           -- 12

一个很好的记忆方法是,大端序是按照数字的书写顺序进行存储的,而小端序是颠倒书写顺序进行存储的。

编程判断大端序和小端序

方法一


bool IsBigEndian()
{
int a =1 ; 
if(((char*)&a)[3] ==1)
returntrue ;
else
returnfalse ;
}

打开VS的内存窗口,看一下a的存储方式,一目了然

由于a是int,所以占四个字节,其值是00000001,存储方式如下。所以a[3]是0,不是大端序。一个更标准的写法是将a[3]替换为a[sizeof(int) - 1]。

0x0012FE88  01

0x0012FE89  00

0x0012FE8A  00

0x0012FE8B  00

方法二,使用union,原理见后面的面试题。


bool IsBigEndian()
{
union 
{
unsigned short a ;
char b ;
} c; c.a =0x0102 ; if(c.b ==1)
return true ;
else
return false ;
}

一道面试题

来道题巩固一下,下面代码输出什么?


union u
{
int i ;
char x[2] ;
} a ; int main(void)
{
a.x[0] ='1' ;
a.x[1] ='2' ; cout << a.i << endl ; getchar() ;
return0 ;
}

这个题,要看你使用的是什么系列的CPU,姑且假设是Intel系列的。Union是一个特殊的结构,其中所有成员共享结一个内存地址,任意时间只能存储一个成员,上面的Union大小为4个字节,所以上面的代码存储完字符1和2之后,Union的存储貌似应该是0x31320000,31和32分别是字符'1'和'2'的十六进制ASCII码(注意是字符1和2,而不是整数),但是Intel系列的CPU都是按照小端序存储的,所以,正确的顺序是0x00003231,对应的十进制数是12849,你答对了么?

关于字节序的详细内容,请看Wikipedia的介绍 http://en.wikipedia.org/wiki/Endianness

 
 
个人补充内容:

大端小端没有谁优谁劣,各自优势便是对方劣势:

小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。

为什么会有大小端模式之分呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

 常见CPU的字节序

Big Endian : PowerPC、IBM、Sun
Little Endian : x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。

常见文件的字节序

Adobe PS – Big Endian
BMP – Little Endian
DXF(AutoCAD) – Variable
GIF – Little Endian
JPEG – Big Endian
MacPaint – Big Endian
RTF – Little Endian
 
另外,Java和所有的网络通讯协议都是使用Big-Endian的编码。

大端模式 VS 小端模式的更多相关文章

  1. 大端模式、小端模式和C#反转

    A.C#大端模式和小端模式. 小端(little-endian)模式:低地址上存放低字节,高地址上存放高字节. 如0x11223344→ byte[] numBytes = new byte[]{ 0 ...

  2. C/C++ 工具函数 —— 大端模式和小端模式的互换

    小端模式:小在小,大在大:大端模式:小在大,大在小: uint32_t swap_endian(uint32_t val) { val = ((val << 8) & 0xFF00 ...

  3. 【C/C++开发】内存对齐(内存中的数据对齐)、大端模式及小端模式

    数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍.DWORD数据的内存起始地址能被4除尽,WORD数据的内存起始地址能被2除尽.X86 CPU能直接访问对齐的数据,当它试图访问一个未对齐的数据 ...

  4. 转!大端模式&小端模式

    大端模式&小端模式   在C语言中除了8位的char型之外,还有16位的short型,32位的long型(要看具体的编译器),对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器 ...

  5. 大端模式&小端模式、主机序&网络序、入栈地址高低问题

    一.大端模式&小端模式 所谓的“大端模式”,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处 ...

  6. 判断CPU是大端还是小端模式

    在小端模式中,低位字节放在低地址,高位字节放在高地址:在大端模式中,低位字节放在高地址,高位字节放在低地址.big-endian和little-endian,51单片机是典型的大端模式,Intel电脑 ...

  7. Linux网络编程1——小端模式与大端模式

    数据存储优先顺序的转换 计算机数据存储有两种字节优先顺序:高位字节优先(称为大端模式)和低位字节优先(称为小端模式).内存的低地址存储数据的低字节,高地址存储数据的高字节的方式叫小端模式.内存的高地址 ...

  8. 【转】如何判断CPU是大端还是小端模式

    原文网址:http://blog.csdn.net/ysdaniel/article/details/6617458 如何判断CPU是大端还是小端模式 http://blog.sina.com.cn/ ...

  9. C语言--测试电脑存储模式(大端存储OR小端存储)

    相信大家都知道大端存储和小端存储的概念,这在平时,我们一般不用考虑,但是,在某些场合,这些概念就显得很重要,比如,在 Socket 通信时,我们的电脑是小端存储模式,可是传送数据或者消息给对方电脑时, ...

随机推荐

  1. UVALive 6577 Binary Tree 二叉树的LRU串

    今天继续攒人品...真开心啊O(∩_∩)O~~各种身体不舒服~~ https://icpcarchive.ecs.baylor.edu/external/65/6577.pdf 题意是这样的,现在有一 ...

  2. oracle触发器 ORA-01722:invalid number 解决方法

    问题在于,远程库是nvarchar2类型,本地是number类型,同步的时候有问题. create or replace trigger tri_org_department after insert ...

  3. 【Git】标签管理

    来源:廖雪峰 为什么要标签: 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来. ...

  4. NEFU 504 new Flip Game (高斯消元)

    题目链接 题解:和 poj1753Filp game 差不多,区别在于t组数据并且翻转的时候多了一个左上角. #include <iostream> #include <cstdio ...

  5. 【jquery】一个简单的单选、多选、全选、反选、删除的小功能

    对表格内容进行单行删除.单行选中.多行选中.全选.反选.删除选中行等操作 HTML代码 <table class="table table-bordered border-shadow ...

  6. autolayout autoresizing

    WWDC 2012 Session笔记——202, 228, 232 AutoLayout(自动布局)入门 这是博主的WWDC2012笔记系列中的一篇,完整的笔记列表可以参看这里.如果您是首次来到本站 ...

  7. java实现批量上传(swfupload)

    下载 swfupload 文件夹 里面包含handlers.js,swfupload.js,swfupload.swf 三个文件. 我的是和ssh项目整合在一起的.因为struts2的拦截器会拦截所有 ...

  8. IOS - 内购

    内购的五种产品类别 •非消耗品(Nonconsumable)买了就有,头衔,功能 –指的是在游戏中一次性购买并拥有永久访问权的物品或服务.非消耗品物品可以被用户再次下载,并且能够在用户的所有设备上使用 ...

  9. ajax基础语法、ajax做登录、ajax做用户名验证是否可用、ajax做关键字查询动态显示、ajax做用表格显示数据并增加操作列

    AJAX: AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新.   ...

  10. java课后作业6

    一.运行TestInherits.java 结论:通过super调用基类构造方法,必须是子类构造方法中的第一个语句. 二.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不 ...