zoukankan      html  css  js  c++  java
  • 大端模式 VS 小端模式

    简单点说,就是字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如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.<< 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的编码。

  • 相关阅读:
    【乱侃】How do they look them ?
    【softeware】Messy code,some bug of Youdao notebook in EN win7
    【随谈】designing the login page of our project
    【web】Ad in security code, making good use of resource
    SQL数据库内存设置篇
    关系数据库的查询优化策略
    利用SQL未公开的存储过程实现分页
    sql语句总结
    sql中使用cmd命令注销登录用户
    SQLServer 分页存储过程
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3324448.html
Copyright © 2011-2022 走看看