[c语言日寄MAX]深度解析:大小端字节序

news2025/4/21 21:16:32

在这里插入图片描述

【作者主页】siy2333
【专栏介绍】⌈c语言日寄MAX⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是进阶开发者,这里都能满足你的需求!
【食用方法】1.根据题目自行尝试 2.查看基础思路完善题解 3.学习拓展算法
【Gitee链接】资源保存在我的Gitee仓库:https://gitee.com/siy2333/study


文章目录

  • 前言
  • 一、什么是大小端字节序?
    • 1. 书面定义
      • 大端字节序(Big-Endian)
      • 小端字节序(Little-Endian)
    • 2.直观理解
      • 高位数据和低位数据
      • 大小端对比
  • 二、怎么写程序判断机器是大端还是小端?
    • 指针
      • 数据的类型会影响指向数据的指针位置吗?
        • 动态内存分配
        • 变量数据
    • 基础判断函数
    • 联合体判断法
  • 总结


前言

大小端字节序是什么?怎么通过程序判断机器是大端还是小段?全局变量和局部变量对大小端的判断有影响吗?本文将为你带来深度的大小端字节序解析,力求一文解决全部疑问。


一、什么是大小端字节序?

大小端字节序是计算机中存储 多字节数据时字节的排列顺序。它们是两种不同的存储方式。

1. 书面定义

大端字节序(Big-Endian)

  • 定义:大端字节序是指在多字节数据中,高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。也就是说,数据的最高有效字节(MSB)存储在地址最低的位置,最低有效字节(LSB)存储在地址最高的位置。

小端字节序(Little-Endian)

  • 定义:小端字节序是指在多字节数据中,低位字节存放在内存的低地址端,高位字节存放在内存的高地址端。也就是说,数据的最低有效字节(LSB)存储在地址最低的位置,最高有效字节(MSB)存储在地址最高的位置。

2.直观理解

我们假设有这样一段由低地址到高地址的内存,每一个格子代表1字节
在这里插入图片描述

现在,我们要将一个有符号整形(int)数据储存在里面。

小端字节序按照“高对高,低对低”的顺序排列。
所谓“高对高,低对低”意思是:高地址存放高位数据,低地址存放低位数据。

而大端则是反过来,”低对高,高对低“。
意思是:低地址存放高位数据,高地址存放低位数据。

高位数据和低位数据

高地址我们知道是哪里,但是什么是高位数据呢?什么又是低位数据呢?
我们看这样一个例子:
在这里插入图片描述

可以看到,对于一个整形数字“2147483649”而言,哪些是低位,哪些是高位。
也就是:高位代表权重更高的比特位,低位代表权重低的比特位。
对于这个数据,
低位的”1“是2^0,计入的值是1。
而高位的”1“是2^31,计入的值为2147483648。

大小端对比

知道了排序规则和高位和低位的定义,我们就可以知道大、小端机器怎么存放多字节数据。
我们将内存映射出来,把他们的数据放在一起对比:
在这里插入图片描述
结合这张图,我们就可以理解大、小端字节序的区别。

值得注意的是:
我们发现,在图中的数据,大小端的区别只在字节层面上。
而字节之下:字节内部 比特位 的排列顺序没有被改变。

二、怎么写程序判断机器是大端还是小端?

指针

在写这个程序之前,我们需要知道计算机是怎么读取数据的。
对于c语言而言,读取内存需要一个指针,这个指针存放着数据在内存中的地址。
在这里插入图片描述

结合这张图,我们知道,无论是大端还是小端,指向数据的指针,都在低地址位。

数据的类型会影响指向数据的指针位置吗?

不会。
我们知道,数据一般分为两种,一种是变量数据,一种是动态内存分配的数据。

动态内存分配

我们知道,动态内存规划分配的内存储存在”堆“中,而堆的使用习惯是优先使用低地址位。
如果我们要动态内存分配一个整形数据,那么内存开辟是这样的:
在这里插入图片描述
可以看到,我们在低地址已经使用的内存之后开辟了4个字节的内存。
这个新数据的指针如图:

在这里插入图片描述
没错,此时的指针指向的依旧是数据的低地址处。

变量数据

再来看看变量数据。
变量数据储存在”栈“中,而栈的使用习惯是先使用高地址,再使用低地址。
如果我们要开辟一个整形变量,那么它在内存中是这样操作的:
在这里插入图片描述
这个变量数据的指针是这样的:
在这里插入图片描述
总结:无论是变量还是动态内存分配的数据,指针位置都是低地址处。

基础判断函数

想要判断大小端,只需要判断指针位置对应的字节就可以了。
在这里插入图片描述

那么,思路就是:

  1. 设置一个无符号整形(unsigned int)变量,赋值“1”。(往内存中存入数据)
  2. 强制类型转换为无符号字符(unsigned char)类型(只读取第一个字节的数据)
  3. 判断数据是0,还是1。(0就是小端,1就是大端)

解决方案如下:

#include <stdio.h>

// 函数声明:判断系统是大端字节序还是小端字节序
int isLittleEndian() {
    // 定义一个无符号整型变量,赋值为1
    unsigned int x = 1;

    // 将x的地址强制转换为unsigned char指针
    // 这样可以逐字节访问x的内存
    unsigned char* bytePointer = (unsigned char*)&x;

    // 检查x的第一个字节(最低地址的字节)
    // 如果x的值为1,那么在小端字节序下,第一个字节为1
    // 在大端字节序下,第一个字节为0
    if (bytePointer[0] == 1) {
        // 如果第一个字节为1,说明是小端字节序
        return 1;
    } else {
        // 否则是大端字节序
        return 0;
    }
}

int main() {
    // 调用函数判断字节序
    if (isLittleEndian()) {
        printf("System is Little Endian.\n");
    } else {
        printf("System is Big Endian.\n");
    }

    return 0;
}

联合体判断法

使用联合体(union)也可以实现判断大小端字节序的功能。
基于联合体的解决方案如下:

#include <stdio.h>

// 定义一个联合体,包含一个无符号整型和一个无符号字符数组
union EndianChecker {
    unsigned int value; // 用于存储整数值
    unsigned char bytes[sizeof(unsigned int)]; // 用于逐字节访问value的内存
};

// 函数声明:判断系统是大端字节序还是小端字节序
int isLittleEndian() {
    // 创建一个联合体变量
    union EndianChecker checker;

    // 将联合体的value成员赋值为1
    checker.value = 1;

    // 检查联合体的bytes数组的第一个字节
    // 如果是小端字节序,第一个字节(最低地址的字节)为1
    // 如果是大端字节序,第一个字节为0
    if (checker.bytes[0] == 1) {
        // 如果第一个字节为1,说明是小端字节序
        return 1;
    } else {
        // 否则是大端字节序
        return 0;
    }
}

int main() {
    // 调用函数判断字节序
    if (isLittleEndian()) {
        printf("System is Little Endian.\n");
    } else {
        printf("System is Big Endian.\n");
    }

    return 0;
}

总结

大小端字节序是针对“字节”的排序,和bit的排序无关,和数据类型无关。
我们可以使用指针+强制类型转换法实现大小端字节序的判定,也可以使用联合体实现。

关注窝,每三天至少更新一篇优质c语言题目详解~
本文手工制作,如果对你有帮助,欢迎点赞收藏和评论~

[专栏链接QwQ] :⌈c语言日寄MAX⌋CSDN
[关注博主ava]:siy2333
感谢观看~ 我们下次再见!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android ADB工具使用教程(从安装到使用)

目录 ADB工具介绍 什么是ADB&#xff1f; 组成 主要功能 ADB工具安装与连接设备 WIFI连接&#xff0c;提示计算机积极拒绝10061 WIFI成功连接后&#xff0c;拔掉数据线显示offline 提示adb版本不一致​编辑 ADB工具使用 ★日志操作命令 adb logcat:抓取日志 日志格式…

基于SSM框架的线上甜品销售系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此网上销售信息的…

Redis原理:Monitor 实现

在调用 Redis 的 MONITOR 命令后&#xff0c;可以在对应的客户端上实时查看服务器的执行情况。今天&#xff0c;我们将从源码的角度来深入探讨 MONITOR 机制是如何处理这些请求以及如何将数据反馈给用户的。 MONITOR 命令的实现 Redis 中所有命令的具体实现细节都可以在其源代…

计算机工具基础(七)——Git

Git 本系列博客为《Missing in CS Class(2020)》课程笔记 Git是一种分布式版本控制系统&#xff0c;被其跟踪的文件可被查询精细到行的修改记录、回退版本、建立分支等 模型 一般流程&#xff1a;工作区 → \to →暂存区 → \to →仓库(本地 → \to →远端) 工作区&#xff1…

23种设计模式-创建型模式-工厂方法

文章目录 简介场景问题1. 直接依赖具体实现2. 违反开闭原则3. 条件分支泛滥4. 代码重复风险 解决根本问题完整类图完整代码说明核心优势代码优化静态配置表动态策略 总结 简介 工厂方法是一种创建型设计模式&#xff0c;它提供了在父类中创建对象的接口&#xff0c;但允许子类…

142. 环形链表 II——考察数学,难!

142. 环形链表 IIhttps://leetcode.cn/problems/linked-list-cycle-ii/ 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,…

从零开始:使用Luatools工具高效烧录Air780EPM核心板项目的完整指南

本文将深入讲解如何使用Luatools工具烧录一个具体的项目到Air780EPM开发板中。如何使用官方推荐的Luatools工具&#xff08;一款跨平台、命令行驱动的烧录利器&#xff09;&#xff0c;通过“环境配置→硬件连接→参数设置→一键烧录”四大步骤&#xff0c;帮助用户实现Air780E…

一套云HIS系统源码,系统融合HIS与EMR,基于云端部署,采用B/S架构与SaaS模式

云HIS系统完全基于云端部署&#xff0c;采用B/S架构&#xff0c;并通过软件即服务&#xff08;SaaS&#xff09;的形式面向二级及以下医院可快速交付、便捷运维、云化的医院核心业务平台产品。融合医院HIS和EMR两大主营系统&#xff0c;构建涵盖患者、费用、医嘱、电子病历等核…

C++数据结构(搜索二叉树)

1.二叉树搜索的概念 二叉搜索数也成为二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者是满足以下性质的树&#xff1a; 1.若他的左子树不为空&#xff0c;则左子树上的所有节点的值都小于等于根节点的值。 2.若他的右子树不为空&#xff0c;则右子树上的所有节点的值…

OpenCV图像拼接(6)图像拼接模块的用于创建权重图函数createWeightMap()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::detail::createWeightMap 是 OpenCV 库中用于图像拼接模块的一个函数&#xff0c;主要用于创建权重图。这个权重图在图像拼接过程中扮演着重…

炫酷的HTML5粒子动画特效实现详解

炫酷的HTML5粒子动画特效实现详解 这里写目录标题 炫酷的HTML5粒子动画特效实现详解项目介绍技术栈项目架构1. HTML结构2. 样式设计 核心实现1. 粒子类设计2. 动画效果实现星空效果烟花效果雨滴效果 3. 鼠标交互 性能优化效果展示总结 项目介绍 本文将详细介绍如何使用HTML5 C…

YoloV8训练和平精英人物检测模型

概述 和平精英人物检测&#xff0c;可以识别游戏中所有人物角色&#xff0c;并通过绘制框将人物选中&#xff0c;训练的模型仅仅具有识别功能&#xff0c;可以识别游戏中的视频、图片等文件&#xff0c;搭配Autox.js可以推理&#xff0c;实现实时绘制&#xff0c;但是对手机性…

BC93 公务员面试

&#x1f680;个人主页&#xff1a;BabyZZの秘密日记 &#x1f4d6;收入专栏&#xff1a;C语言练习题分享 &#x1f30d;文章目入 #include <stdio.h> int main() {int score 0, max 0, min 100, sum 0, count 0; while (scanf("%d", &score) ! EOF){…

3.0 Disruptor的使用介绍(一)

Disruptor: 其官网定义为&#xff1a;“A High Performance Inter-Thread Messaging Library”&#xff0c;即&#xff1a;线程间的高性能消息框架&#xff0c;与Labview的生产者、消费者模型很相似。 其组成部分比较多&#xff0c;先介绍几个常用的概念&#xff1a; …

[深度学习]图像分类项目-食物分类

图像分类项目-食物分类(监督学习和半监督学习) 文章目录 图像分类项目-食物分类(监督学习和半监督学习)项目介绍数据处理设定随机种子读取文件内容图像增广定义Dataset类 模型定义迁移学习 定义超参Adam和AdamW 训练过程半监督学习定义Dataset类模型定义定义超参训练过程 项目介…

java8循环解压zip文件---实现Excel文件数据追加

java8循环追加Excel数据 实际遇到问题&#xff1a;定期获取zip文件&#xff0c;zip文件内有几个固定模板的Excel文件&#xff0c;有的Excel文件可能还包含多个sheet。 有段时间一次性获取到好几个zip包&#xff0c;需要将这些包都解压&#xff0c;并且按照不同的文件名、sheet进…

基于SpringBoot的电影售票系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

SQL Server 2022 安装问题

一、安装与配置问题 1. SQL Server 2022 安装失败怎么办&#xff1f; 常见原因&#xff1a; 硬件或操作系统不满足最低要求&#xff08;如内存、磁盘空间不足&#xff09;。未关闭防火墙或杀毒软件。之前版本的 SQL Server 残留文件未清理。 解决方案&#xff1a; 确保硬件配…

MySQL 8.0.41安装教程(附安装包)mysql8.0.41图文详细安装教程

文章目录 前言一、MySQL 8.0.41下载安装包二、MySQL 8.0.41安装教程1.启动安装程序2.选择安装模式3.选定安装组件4.确认安装设置5.执行安装操作6.安装进行中7.设置数据库密码8.继续点击下一步9.执行配置操作10.完成配置11. 再次点击下一步12.结束安装向导 三、MySQL 8.0.41配置…