当前位置: 首页 > article >正文

字节序 大端和小端

目录

  • 什么是 大端存储和小端存储?
  • 为什么会有大小端转换问题
  • 如何检查自己电脑 是大端还是小端?
  • 大端小端处理函数
    • 使用位运算操作来手动转换大端和小端。
    • 使用标准库中的htonl和ntohl函数
      • 代码示例:

什么是 大端存储和小端存储?

  • 大端模式(Big-endian):高字节存储在低地址,低字节存储在高地址。也就是说,数据的最高有效字节存储在内存的起始地址。
  • 小端模式(Little-endian):低字节存储在低地址,高字节存储在高地址。也就是说,数据的最低有效字节存储在内存的起始地址。

假设有一个32位整数0x12345678,在内存中占据4个字节。
在我们叫法中,二进制位有低位到高位,那么也要低字节到高字节。
在这里插入图片描述

  • 高字节存储在低地址,为大端
    在这里插入图片描述
  • 低字节存储在低地址为小端
    在这里插入图片描述

为什么会有大小端转换问题

1.硬件架构差异

  • 不同的计算机硬件架构采用不同的字节序。例如:大端模式(Big-endian):通常在一些网络协议和大型机系统(如IBM的大型机)中使用。小端模式(Little-endian):在大多数现代个人计算机、服务器、嵌入式系统中使用(如基于 x86和x86_64的系统)。
  • 当在不同硬件平台之间传递多字节数据时,如通过网络通信、文件存储或进程间通信,如果不处理字节序的差异,就可能导致数据解释错误。

2.网络协议的要求

  • 许多网络协议规定数据传输时必须使用特定的字节序。例如,TCP/IP协议使用大端序作为标准(也称为网络字节序)。因此,当数据在不同系统之间通过网传输时,可能需要在主机字节序与网络字节序之间进行转换。

3.文件和数据格式

  • 某些文件格式或数据格式(如图片、音频、视频、数据库文件等)规定了特定的字节序。例如,图像文件格式BMP在文件头中使用小端序存储数据。如果在大端模式的系统上读取或写入这种文件,需要进行字节序转换。

如何检查自己电脑 是大端还是小端?

可以通过联合体

#include <iostream>
using namespace std;

union {
	int i;//4字节,32位
	char c[4];//4字节字符数组
}test;

int  main()
{
	test.i = 0x12345678;

	//根据第一个字节的值判断大小端
	if (test.c[0] == 0x78)
	{
		cout << "低字节放在低地址 为小端" << endl;
	}
	else if (test.c[0] == 0x12)
	{
		cout << "高字节放在低地址 为大端" << endl;
	}
	else
	{
		cout << "无法确定字节序" << endl;
	}

	return 0;
}

大端小端处理函数

在C++中,处理大端(BigEndian)和小端(LittleEndian)存储的相关函数和方法通常与字节序的转换有关。 C++并没有内置的标准库函数专门用于处理大端和小端之间的转换,但可以通过以下几种方式来进行字节序的转换:

使用位运算操作来手动转换大端和小端。

以下是一个示例,将32位整数从小端转换为大端:

#include <iostream>
using namespace std;

//将小端转换为大端
uint32_t littleToBigEndian(uint32_t littleEndian)
{
	return ((littleEndian & 0xFF000000) >> 24) |
		((littleEndian & 0x00FF0000) >> 8) |
		((littleEndian & 0x0000FF00) << 8) |
		((littleEndian & 0xFF0000FF) << 24);
}
int main()
{
	uint32_t littleEndian = 0x12345678;
	uint32_t bigEndian = littleToBigEndian(littleEndian);
	cout << hex << "小端: 0x" << littleEndian << endl;
	cout << hex << "大端: 0x" << bigEndian << endl;
	return 0;
}

使用标准库中的htonl和ntohl函数

在网络编程中,POSIX标准提供了htonl(Host to Network Long)、htons(Host to Network Short)、ntohl(Network to Host Long)和ntohs(Network to Host Short)这些函数用于字节序转换。这些函数可以用于转换16位和32位的整数。

  • htohl和ntohl:用于转换32位(long)的字节序。
  • htons和ntohs:用于转换16位(short)的字节序。

这些函数在<arpa/inet.h>(Linux/Unix)或<winsock2.h>(Windows)头文件中定义。

代码示例:

需要添加系统的lib。

#include <iostream>
#include <cstdint>
#include <WinSock2.h>

using namespace std;

int main()
{
	
	uint32_t hostOrder = 0x12345678;
	
	//主机转网络
	uint32_t networkOrder = htonl(hostOrder);
	cout << hex << "host : 0x" << hostOrder << endl;
	cout << hex << "Net : 0x" << networkOrder << endl;

	//网络转主机
	uint32_t hostConvertedBack = ntohl(networkOrder);
	cout << hex << "hostConvertedBack : 0x" << hostConvertedBack << endl;
	return 0;
}

http://www.kler.cn/a/505496.html

相关文章:

  • CDP中的Hive3之Hive Metastore(HMS)
  • 网络编程 - - TCP套接字通信及编程实现
  • SpringData-Redis缓存之RedisTemplate
  • 大疆机场及无人机上云
  • 东芝3525AC彩色复印机复印默认成黑白模式方法
  • Three.js 用户交互:构建沉浸式3D体验的关键
  • 用Excel开发进销存软件,office Access开发ERP管理软件
  • 计算机视觉语义分割——FCN(Fully Convolutional Networks for Semantic Segmentation)
  • 计算机网络 (37)TCP的流量控制
  • # [Unity] 使用控制运动开发简单的小游戏
  • 【SpringSecurity】SpringSecurity安全框架授权
  • 【Apache Paimon】-- 源码解读之环境问题
  • MybatisPlus--Lombok的使用
  • Cyberchef开发operation操作之-node开发环境搭建
  • 【PCIe 总线及设备入门学习专栏 5.3.1 -- PCIe PHY firmware load | trainning | link up 区别与联系】
  • CES 2025:科技热点与趋势深度剖析
  • JMeter下载与使用,新手详细
  • 【Uniapp-Vue3】showLoading加载和showModal模态框示例
  • Git | git revert命令详解
  • ubuntu各分区的用途
  • 使用virsh-console连接虚拟机报连接到域一直卡着
  • Java基于SSM框架的在线视频教育系统小程序【附源码、文档】
  • 环境部署——minio部署
  • STM32F1——CAN驱动代码
  • 【QT】如何在遍历QTreeWidgetItem的子项过程中正确删除子项
  • 电动汽车V2G技术Matlab/Simulink仿真模型