• 大端模式 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的编码。

  • 相关阅读:
    android之APN
    Simple XML
    Retrofit – Java(Android) 的REST 接口封装类库
    Android 删除短信
    解决android:background背景图片被拉伸问题
    人分三等,你是哪一等?
    将android中的sample例子到eclipse中
    linux内存管理
    Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚(转)
    使用maven创建web项目
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3324448.html
Copyright © 2020-2023  润新知