C++ 关于大端模式和小端模式的简析

序言

我记得我已经查过4次了,最近回想一下发现我竟然又忘了!所以特以此文来记录一下。

环境

Qt5.14.2 MSVC2017 64bit(VS2019)

概念

在计算机系统中,计算机存储单元是字节“byte”,在内存中存储的顺序就成了绕不开的问题,也就出现了大端模式和小端模式,为什么会有这两种模式呢?

大端模式是更符合人理解的模式,且符号位在所表示数据内存的第一个字节中,便于快速判断数据的正负和大小。
小端模式是更符合机器性能的模式,CPU做数值运算时从内存中按顺序依次从低位到高位取数据进行运算,直到最后刷新最高位的符号位,这样的运算方式会更高效;内存的低地址处存放低字节,所以在强制转换数据时不需要调整字节的内容。

大端模式(Big-endian):高位字节存低位地址,低位字节存高位地址
小端模式(Little-endian):低位字节存低位地址,高位字节存高位地址

举个例子:
数值: 0x12345678
存的内存位置:0x000000D3B8EFF254 ~ 0x000000D3B8EFF257
大端在内存中分别存的:12 34 56 78
小端在内存中分别存的:78 56 34 12

0x12 34 56 78,其高位字节就是越左越高,低位字节就是越右越低;
0x000000D3B8EFF254 ~ 0x000000D3B8EFF257,其高位地址就是数值越高就高,其低位地址就是数值越低就低;

0x000000D3B8EFF254低位地址里,存储0x12的则是大端模式,存储0x78的则是小端模式。

理解可能有问题的地方

  1. 0x12 34 56 78共4个字节,每个字节大端和小端存的都是一样的,这个没什么区别,意思是0x78的十六进制,同样都是以0b0111 1000二进制的存放方法,不会说大端模式就0001 1110这样存的,不是这个意思,大小端区别是按字节为单位判断的。
  2. 有些人可能理解了十六进制0x12345678为例子时的大小端情况,就不清楚十进制ulong,char数组,std::string等非十六进制情况时大小端情况,如果有这种疑惑说明你对数据的本质不清楚,这些在内存中存放的实质上就是一个个组合成的二进制数或者是十六进制数,字母可以用ASCII对照转换成十六进制数,中文字符可以用Unicode来对照转换成十六进制数。

一般情况下需要注意的大小端情况

TCP/IP协议规定必须采用网络字节顺序NBO(Network Byte Order),即大端模式。
而主机字节顺序(HBO,Host Byte Order)则看所在的CPU处理器及编译器才能确定,而不是看操作系统。

但是普遍常见的CPU是小端模式

关于大小端相关的实用函数/代码

判断自身大小端的代码

union myunion
{
    int a;
    char b;
};

// 如果是小端模式则返回1,大端模式则返回0
bool is_little_endian(void)
{
    union myunion u1;
    u1.a = 0x12345678;				// 地址0的那个字节内是0x78(小端)或者0x12(大端)
    if(0x78 == u1.b)
        return true;
    else if(0x12 == u1.b)
        return false;
}

大小端转换函数

头文件:
windows:	#include <WinSock2.h>
linux:		#include <arpa/inet.h>

1)htonl-》Host to Network Long

函数原型:uint32_t htonl (uint32_t hostlong)
函数返回值:是一个32位的网络字节顺序。
函数的作用:是将一个32位数从 主机字节顺序 转换成 网络字节顺序。

注:无符号的长整型 在 32位的系统是 4字节。

2)htons

函数原型:uint16_t htons (uint16_t hostshort)
函数返回值:是一个16位的网络字节顺序。
函数的作用:是将一个16位数从 主机字节顺序 转换成 网络字节顺序。

注:无符号的短整型 在 32位的系统是 2字节。

3)ntohl Network to Host Long

函数原型是:uint32_t ntohs (uint32_t netlong)
函数返回值:是一个32位的主机字节顺序。
函数的作用:是将一个32位数由 网络字节顺序 转换为 主机字节顺序。

4)ntohs 

函数原型是:uint16_t ntohs (uint16_t netshort)
函数返回值:是一个16位的主机字节顺序。
函数的作用:是将一个16位数由 网络字节顺序 转换为 主机字节顺序。

等...

因个人尚未读到这些函数的源码,所以只清楚上述的函数中是知道主机字节顺序是小端的,不确定自身CPU如果是大端模式会不会自行判断。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溪渣渣_梁世华

打赏?我甚至没有任何收费的章节

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值