【转】大小端存储模式精解

计算机系统中内存是以字节为单位进行编址的,每个地址单元都唯一的对应着1个字节(8 bit)。这可以应对char类型数据的存储要求,因为char类型长度刚好是1个字节,但是有些类型的长度是超过1个字节的(字符串虽然是多字节的,但它本质是由一个个char类型组成的类似数组的结构而已),比如C/C++中,short类型一般是2个字节,int类型一般4个字节等。因此这里就存在着一个如何安排多个字节数据中各字节存放顺序的问题。正是因为不同的安排顺序导致了大端存储模式和小端存储模式的存在。

1. 概述

1.1 定义

假如有一个4字节的数据为 0x12 34 56 78(十进制:3054198960x12为高字节,0x78为低字节),若将其存放于地址0x4000 8000中,则有:

内存地址 0x4000 8000(低地址) 0x4000 8001 0x4000 8002 0x4000 8003(高地址)
大端模式 0x12(高字节) 0x34 0x56 0x78(低字节)
小端模式 0x78(低字节) 0x56 0x34 0x12(高字节)

明显可以看出规律,即大端“高低低高”,小端“高高低低”:

  • 大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中
  • 小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中

1.2 特点

为什么截然相反的大小端存储模式能够并存至今?在标准化备受推崇的今天,为什么大小端谁都没有被另外一个所同化?我想这除了历史的惯性使然,还与它们各自的优缺点有关。

大端模式优点:符号位在所表示的数据的内存的第一个字节中,便于快速判断数据的正负和大小

小端模式优点:1. 内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容(注解:比如把int的4字节强制转换成short的2字节时,就直接把int数据存储的前两个字节给short就行,因为其前两个字节刚好就是最低的两个字节,符合转换逻辑); 2. CPU做数值运算时从内存中依顺序依次从低位到高位取数据进行运算,直到最后刷新最高位的符号位,这样的运算方式会更高效

其各自的优点就是对方的缺点,正因为两者彼此不分伯仲,再加上一些硬件厂商的坚持(见1.3节),因此在多字节存储顺序上始终没有一个统一的标准

1.3 现状

  • Intel的80×86系列芯片使用小端存储模式
  • ARM芯片默认采用小端,但可以切换为大端
  • MIPS芯片采用大端,但可以在大小端之间切换
  • 在网络上传输的数据普遍采用的都是大端

2. 判断

方法一:通过将多字节数据强制类型转换成单字节数据,再通过判断起始存储位置是数据高字节还是低字节进行检测

 1 // @Ret: 大端,返回true; 小端,返回false
 2 bool IsBigEndian_1()
 3 {
 4     int nNum = 0x12345678;
 5     char cLowAddressValue = *(char*)&nNum;
 6
 7     // 低地址处是高字节,则为大端
 8     if ( cLowAddressValue == 0x12 )    return true;
 9
10     return false;
11 }

方法二:利用联合体union的存放顺序是所有成员都从低地址开始存放这一特性进行检测

 1 // @Ret: 大端,返回true; 小端,返回false
 2 bool isBigEndian_2()
 3 {
 4     union uendian
 5     {
 6        int nNum;
 7        char cLowAddressValue;
 8     };
 9
10     uendian u;
11     u.nNum = 0x12345678;
12
13     if ( u.cLowAddressValue == 0x12 )     return true;
14
15     return false;
16 }

3. 转换

3.1 大小端转换

1 // 实现16bit的数据之间的大小端转换
2 #define BLSWITCH16(A)   (  ( ( (uint16)(A) & 0xff00 ) >> 8  )    | \
3                            ( ( (uint16)(A) & 0x00ff ) << 8  )     )
4
5 // 实现32bit的数据之间的大小端转换
6 #define BLSWITCH32(A)   (  ( ( (uint32)(A) & 0xff000000) >> 24) |7          (((uint32)(A) & 0x00ff0000) >> 8) | 8          (((unit32)(A) & 0x0000ff00) << 8) | 9          (((uint32)(A) & 0x000000ff) << 32)  )

3.2 网络字节序与主机字节序的转换

由于网络字节序一律为大端,而目前个人PC大部分都是X86的小端模式,因此网络编程中不可避免得要进行网络字节序和主机字节序之间的相互转换,下面是 socket 提供的转换函数

1 #define ntohs(n)     // 16位数据类型网络字节顺序到主机字节顺序的转换
2 #define htons(n)     // 16位数据类型主机字节顺序到网络字节顺序的转换
3 #define ntohl(n)     // 32位数据类型网络字节顺序到主机字节顺序的转换
4 #define htonl(n)     // 32位数据类型主机字节顺序到网络字节顺序的转换

原文

原文地址:https://www.cnblogs.com/skullboyer/p/8625406.html

时间: 2024-10-27 11:49:03

【转】大小端存储模式精解的相关文章

【总结】大端、小端存储模式的那点事

----------------------------------------------------------------------------------------------------- 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放: 小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权

C语言面试篇1:判断数据大小端存储

一.前言 本节,我们将学习C语言库中数据存储方式,并通过编写代码确定当前系统的数据存储方式. 二.简介 1.大端模式 大端模式是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中. 2.小端模式 小端模式是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中. 3.为什么会有大小端之分? 为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit.但是在C语言中除了8bit的char之外,还有

大小端存储

字节的高位与低位举个例子,int a = 0x12345678 ; 那么左边12就是高位字节,右边的78就是低位字节,从左到右,由高到低,(注意,高低乃相对而言,比如56相对于78是高字节,相对于34是低字节). 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放: 小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低

堆栈方向以及大小端存储

在程序的设计中,都会涉及都堆栈的使用,其实堆栈是指堆和栈,它们是两个不同的概念,其中堆是通过用户来调用的内存空间,需要用户主动分配和释放,如果只分配而不即使释放,则可能出现内存泄漏的问题,其结果的难以估量的:栈是系统自动调用的内存空间,系统也会根据实际情况自动去释放该空间. 在平时的使用当中,我们需要注意堆栈(这里仅指栈)的增长方向,一般来说,当堆栈指针(栈顶)由高地址向低地址增长时,我们称为向下增长,:当堆栈指针(栈顶)由低地址向高地址增长时,我们称为向上增长. 在程序设计中我们还需要注意的就

Cisco交换机接口模式精解

cisco网络中,交换机在局域网中最终稳定状态的接口类型主要有四种:access/ trunk/ multi/ dot1q-tunnel. 1.access: 主要用来接入终端设备,如PC机.服务器.打印服务器等. 2.trunk: 主要用在连接其它交换机,以便在线路上承载多个vlan. 3.multi: 在一个线路中承载多个vlan,但不像trunk,它不对承载的数据打标签.主要用于接入支持多vlan的服务器或者一些网络分析设备.现在基本不使用此类接口,在cisco的网络设备中,也基本不支持此

(转)大小端模式详解

int i=1; char *p=(char *)&i; if(*p==1) printf("1"); else printf("2"); 大小端存储问题,如果小端方式中(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端. 请写一个C函数,若处理器是Big_end

存储中的大端模式和小端模式详解

什么是大端,什么是小端: 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中: 所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中. 为什么会有大小端: 为什么会有大小端模式之分呢?这是因为在计算机存储系统中,我们是以字节为单位进行管理的,每个内存中的地址单元都对应着一个字节,一个字节为8bit.但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大

CPU大小端模式及转换

通信协议中的数据传输.数组的存储方式.数据的强制转换等这些都会牵涉到大小端问题. CPU的大端和小端模式很多地方都会用到,但还是有许多朋友不知道,今天暂且普及一下. 一.为什么会有大小端模式之分呢? 因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit. 但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的int型.另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何

CPU的大小端及如果判断

不同体系结构的CPU,数据在内存中存放的排列顺序是不一样的. 存储器中对数据的存储是以字节(Byte)为基本单位的,因此,字(Word)和半字(Half-Word)在存储器中就有两种次序,分别称为:大端模式(Big Endian)和小端模式(Little Endian). 大端存储模式是指字或半字的最高字节(Most Significant Bit,MSB)存放在内存的最低位字节地址上,而字数据的低字节则存放在高地址中.打个比方,有一个字为0×12345678,这个字由4个字节组成, 从高位到低