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

跟我学C++中级篇——字节序

一、什么是字节序

在谈字节序前讲个小故事,在小说《格列佛游记》中,有两派势力为了吃鸡蛋的时候儿到底是先打破大的一端还是打破小的一端展开了战争,而且这场战争持续了很久。后来,1980年,Danny Cohen在论文"On Holy Wars and a Plea for Peace"中引用了这个故事来处理一场关于数据传输时字节该以什么样的顺序进行传送的争论,所以在计算机的世界中也才有了字节序这个概念。
字节序,又称端序、尾序,英文单词为Endian,由于上面的鸡蛋的打破的大小端两种情况,所以这里也分成了little Endian(小头或小端模式),big Endian(大头或大端模式)。
这时候儿大家会不会突然明白,这不和汽车的左舵和右舵一样么?没有什么对错,只是设定的不同。
在开发者或者说常见的体系中一般是以小头字节序多,比如常见的x86体系的电脑基本都是小端模式。那么小端模式和大端模式是什么样子呢?大家都知道电脑的内存是从低地址向高地址增长的,对于存储一个数,如果在低地址存储低字节,高地址存储高字节那就是大端模式,反之为小端模式。举个例子就明白了:
一个十六进制的数:0x12345678(举十六进制是为了容易表述,和十进制一样),字节0x12是高字节,依次向低字节过渡,最低是0x78。如果内存是下面的情况:

 地址:0    1    2     3   (地址由低到高)数据:78   56   34    12则为小端模式,如果如下面的情况则为大端模式:地址:0    1    2     3   (地址由低到高)数据:12   34   56    78

大家有没有发现,大端模式符合人们的日常感官看法,因为人们一般书写数字都是从左到右从高位和低位的。如果大家想更直观的看,可以在VS或者其它的IDE中写个十六进制的变量,然后在内存观察器中查看,就可以看到上面的类似的场景了,非常直观。
常见的大小端的机器如下:
小端模式:x86,MOS Technology 6502,Z80,VAX,PDP-11等处理器
大端模式:Motorola 6800,Motorola 68000,PowerPC 970,System/370,SPARC(除V9外)等处理器
可配置模式:ARM, PowerPC (除PowerPC 970外), DEC Alpha, SPARC V9, MIPS, PA-RISC and IA64等处理器
说是常见,其实对大多数开发人员可能基本都不会遇到几个。

二、应用场景

这时如果大家跳脱出来,决定所有的数据都单纯以字节表示不就没这个大小端之争了么?确实,但计算机一开始的发展是没有标准的。就和全世界有米、尺、英尺等等一样。所以为了表示各种类型的数据,搞计算机的人怎么痛快怎么来嘛。你想看着舒服,我就想用着痛快;你想高位存储在高地址,低位存储在低字节,我就反着来。特别是需要用多个字节才能表示的整形(int,short,long等等)以及一些其它情况,大家肯定是各有所好,而且有的时候就是故意的对着干。
但对程序员来说,最常遇到的当然是小端,X86架构平台。即使开发移动程序,也是在PC上开发不是。
另外一个场景对开发者来说非常常见,网络编程,网络数据的传输是以大端模式进行的。所以大家还记不记得在传递端口号时要做一个转换,使用类似下面的函数:

//主机字节序到网络字节序
htons:unsigned short类型转换到网络序
htonl:unsigned long类型转换到网络序
//网络字节序到主机字节序
ntohs:unsigned short类型转换到主机序
ntohl:unsigned long类型转换主机序

其它的大小端模式,基本都是比较专业的开发才可能遇到了。

三、实际应用

在实际应用中,如果数据是以字节表示的,则不会有任何问题,即使在多个大小端的协议或者平台进行处理都不会有问题,比如图像的字节点阵。另外一个现象是,如果大小端传输的对称性,也没有问题。举个例子,当以小端字节传递数据,经过大端协议,但对方接收也是小端处理,正常情况下也不会有问题,这就是在进行了网络开发时,为什么只是把端口号啥的需要大端解析的数据转换一下,其它的传输的字节流数据(不是单纯的字节流,是小端表示数据转换过来的如int,long等)在接收后进行转换时不会出问题的原因。不过如果非对称的,则需要进行处理,比如发送是大端接收是小端,无论中间过多少手大小端,最终的部分都需要转换(中间部分只负责传输)。
为了保持安全,一般C/C++都有查看大小端的方法:
1、使用宏定义
BYTE_ORDER__宏,值为__ORDER_LITTLE_ENDIAN,即当前环境为小端模式,而值为__ORDER_BIG_ENDIAN__,则为大端模式
2、通过编程实现
可以使用联合体或位运算的方式来处理:

//联合体
union endian {int d;char order[4];
}Endian;
bool BigEndian() {Endian.d = 1;return (Endian.order[0] == 0);
}
//位
bool BigEndian() {int td = 1;return (*(char*)&td == 0);
}

3、C++中的库
使用std::endian,不过它在C++20才支持。使用的方法就不举例了,非常简单,大家可以查看一下帮助。

四、总结

其实字节序这种东西,如果不是经常和多个不同的架构平台打交道的话,其实意义真得不是多大。虽然经常应用的网络数据处理是大头的,但实际上网传输的基本都有库或者序列化,对开发者影响基本消除了。只有个别的如端口啥的可能需要自己处理,还都有专门的处理函数。所以对绝大多数开发者来说,都可以不需要专门注意这件事,当实际遇到相关的场景后再进行处理即可。

相关文章:

跟我学C++中级篇——字节序

一、什么是字节序 在谈字节序前讲个小故事,在小说《格列佛游记》中,有两派势力为了吃鸡蛋的时候儿到底是先打破大的一端还是打破小的一端展开了战争,而且这场战争持续了很久。后来,1980年,Danny Cohen在论文"On …...

Linux网络编程5——多路IO转接

一.TCP状态时序理解 1.TCP状态理解 **CLOSED:**表示初始状态。 **LISTEN:**该状态表示服务器端的某个SOCKET处于监听状态,可以接受连接。 **SYN_SENT:**这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时…...

Redis常见

Redis 事务 什么是 Redis 事务? 你可以将 Redis 中的事务理解为:Redis 事务提供了一种将多个命令请求打包的功能。然后,再按顺序执行打包的所有命令,并且不会被中途打断。 Redis 事务实际开发中使用的非常少,功能比…...

提升 PHP 编码效率的 10 个实用函数

PHP开发者始终追求更简洁、高效的代码。幸运的是,PHP 提供了丰富的内置函数,能显著减少手动编码,提升开发效率。无论经验深浅,掌握这些函数的使用技巧都至关重要。 以下列出了 10 个可以显著加快您的编码过程的 PHP 函数&#xf…...

设计模式 行为型 访问者模式(Visitor Pattern)与 常见技术框架应用 解析

访问者模式(Visitor Pattern)是一种行为设计模式,它允许你在不改变元素类的前提下定义作用于这些元素的新操作。这种模式将算法与对象结构分离,使得可以独立地变化那些保存在复杂对象结构中的元素的操作。 假设我们有一个复杂的对…...

golang之数据库操作

1.导入必要的包 import("database/sql"_ "github.com/go-sql-driver/mysql" //使用此作为数据库驱动 ) 2.相关操作 连接数据库 使用sql.Open()函数进行数据库的连接 db, err : sql.Open("mysql", "user:passwordtcp(127.0.0.1:3306)/db…...

对话新晋 Apache SeaTunnel Committer:张圣航的开源之路与技术洞察

近日,张圣航被推选为 Apache SeaTunnel 的 Committer成员。带着对技术的热情和社区的责任,他将如何跟随 Apache SeaTunnel 社区迈向新的高度?让我们一起来聆听他的故事。 自我介绍 请您简单介绍一下自己,包括职业背景、当前的工作…...

Mac 删除ABC 输入法

参考链接:百度安全验证 Mac下删除系统自带输入法ABC,正解!_mac删除abc输入法-CSDN博客 ABC 输入法和搜狗输入法等 英文有冲突~~ 切换后还会在英文状态,可以删除 ;可能会对DNS 输入有影响,但是可以通过复…...

《机器学习》之K-means聚类

目录 一、简介 二、K-means聚类实现步骤 1、初始化数据点、确定K值 2、通过距离分配数据点 3、更新簇中心 4、 迭代更新 三、聚类效果评价方式 1、轮廓系数的定义 2、整体轮廓系数 3、使用场景 4、优点 5、缺点 6、代码实现方法 四、K-means聚类代码实现 1、API接…...

日常工作之 Elasticsearch 常用查询语句汇总

日常工作之 Elasticsearch 常用查询语句汇总 查询现有索引创建索引查询索引结构插入数据查询索引数据查看索引磁盘占用信息删除索引查看分词器分词结果指定查询数量指定条件查询数据迁移统计索引数据量更新数据 在使用 es 的过程中,总是会用到 es 的查询语句&#x…...

WeakAuras NES Script(lua)

WeakAuras NES Script 修星脚本字符串 脚本1:NES !WA:2!TMZFWXX1zDxVAs4siiRKiBN4eV(sTRKZ5Z6opYbhQQSoPtsxr(K8ENSJtS50(J3D7wV3UBF7E6hgmKOXdjKsgAvZFaPTtte0mD60XdCmmecDMKruyykDcplAZiGPfWtSsag6myGuOuq89EVDV9wPvKeGBM7U99EFVVVV33VFFB8Z2TJ8azYMlZj7Ur3QDR(…...

JVM 触发类加载的条件有哪些?

目录 一、类加载生命周期 二、主动引用 2.1、创建类的实例 2.2、访问类的静态字段或静态方法 2.3、反射 2.4、初始化类的子类时,先初始化父类 2.5、虚拟机启动时,初始化 main 方法所在的类 2.6、动态语言支持 三、被动引用 3.1、通过子类引用父…...

Android实战经验篇-增加系统分区

系列文章转如下链接: Android Display Graphics系列文章-汇总 Android实战经验篇-系列文章汇总 本文主要包括部分: 一、Android分区说明 1.1 系统分区查看 1.2 分区表修改 1.3 验证新分区 二、源码修改 2.1 generate_extra_images 2.2 fstab 2…...

深入学习 Python 量化编程

深入学习 Python 量化编程 第一章:Python 基础与量化编程环境搭建 1.1 安装必要的库 首先,你需要安装一些在量化编程中常用的 Python 库。可以通过以下命令安装这些库: pip install numpy pandas matplotlib yfinance backtrader scikit-…...

机器学习笔记——特征工程

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本笔记介绍机器学习中常见的特征工程方法、正则化方法和简要介绍强化学习。 文章目录 特征工程(Fzeature Engineering)1. 特征提取&#xff…...

4种革新性AI Agent工作流设计模式全解析

文章目录 导读:AI Agent的四种关键设计模式如下:1. 反思2. 工具使用3. 规划4. 多Agent协作 总结内容简介: 导读: AI Agent是指能够在特定环境中自主执行任务的人工智能系统,不仅接收任务,还自主制定和执行…...

【入门级】计算机网络学习

网络安全:前端开发者必知:Web安全威胁——XSS与CSRF攻击及其防范-CSDN博客 三次握手四次挥手:前端网络—三次握手四次挥手_前端三次握手-CSDN博客 http协议和https协议的区别:前端网络—http协议和https协议的区别-CSDN博客 网…...

安装 Jenkins 后无法访问用户名或密码且忘记这些凭证怎么办?

Jenkins 是一款功能强大的自动化服务器,在持续集成与交付(CI/CD)领域应用广泛。不过,用户在使用过程中,尤其是首次接触该系统或系统重启后,常常会遇到登录方面的问题。要是 Jenkins 突然要求输入用户名和密…...

day08_Kafka

文章目录 day08_Kafka课程笔记一、今日课程内容一、消息队列(了解)**为什么消息队列就像是“数据的快递员”?****实际意义**1、产生背景2、消息队列介绍2.1 常见的消息队列产品2.2 应用场景2.3 消息队列中两种消息模型 二、Kafka的基本介绍1、…...

安装conda 环境

conda create -n my_unet5 python3.8 (必须设置3.8版本) conda activate my_unet5...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...