Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[c语言日寄MAX]深度解析:大小端字节序

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

作者头像
siy2333
发布于 2025-03-27 00:35:23
发布于 2025-03-27 00:35:23
8400
代码可运行
举报
文章被收录于专栏:来自csdn的博客来自csdn的博客
运行总次数:0
代码可运行
【作者主页】s

前言

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

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

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

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就是大端)

解决方案如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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)也可以实现判断大小端字节序的功能。 基于联合体的解决方案如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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语言题目详解~ 本文手工制作,如果对你有帮助,欢迎点赞收藏和评论~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一文读懂大小端:从原理到实践的深度剖析
推荐下我之前写的C/C++ OpenGL入门专栏,如果你想学习OpenGL,欢迎订阅,也可以通过底部的阅读原文进入
程序员的园
2025/04/29
780
一文读懂大小端:从原理到实践的深度剖析
C语言两种方法求证大小端存储
低位字节也同理,比如一个十六进制0x11223344,11就是高位字节,44就是低位字节。
用户11316056
2024/10/16
1120
C语言两种方法求证大小端存储
整数和浮点数在内存中的存储​(大小端详解)
在讲解操作符的时候,我们就讲过了下面的内容: 整数的2进制表示方法有三种,即 原码、反码和补码​ 三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位最 高位的一位是被当做符号位,剩余的都是数值位。 正整数的原、反、补码都相同。
走在努力路上的自己
2024/01/26
9980
整数和浮点数在内存中的存储​(大小端详解)
百度2015年系统工程师笔试题:判断当前机器的大小端
aosei
2024/01/23
1110
百度2015年系统工程师笔试题:判断当前机器的大小端
字节序(大小端)详解从高低地址和高低位开始理解【转】
http://blog.csdn.net/jk110333/article/details/44137423
保持热爱奔赴山海
2019/09/17
7.9K0
清晰讲解LSB、MSB和大小端模式及网络字节序
今天在做需求的涉及到一个固件版本的概念,其中固件组的人谈到了版本号从MSB到LSB排列,检索查阅后将所得整理如下。
翎野君
2023/05/12
6.2K0
清晰讲解LSB、MSB和大小端模式及网络字节序
【C语言进阶】数据如何安家?C语言内存中的存储艺术深度解析
前言:在当今这个数据驱动的世界里,无论是软件开发、系统编程还是嵌入式系统开发,对数据的处理与存储都占据着举足轻重的地位。C语言,作为一门历史悠久且功能强大的编程语言,其直接操作内存的能力使得它在处理复杂数据结构和高性能数据存储方面展现出独特的优势。因此,深入理解C语言中的数据存储机制,对于任何希望成为高效程序员或系统分析师的学习者而言,都是不可或缺的一步
Eternity._
2024/08/29
1480
【C语言进阶】数据如何安家?C语言内存中的存储艺术深度解析
《编程千问》第七问:你了解大端和小端字节序吗?
大端(Big Endian) 和 小端(Little Endian) 是计算机中数据存储的两种字节序方式。它们主要描述多字节数据(如整型、浮点型)在内存中的存储顺序。
码事漫谈
2024/12/20
3480
【C语言课程学习】:计算机中大端和小端字节序
下面是4个字节(int)类型按16进制在大小端存放的区别。2个16进制数占一个字节,字节的内部是不会改变顺序的,大小端的区别只存在字节之间的顺序不同。
用户11396661
2024/12/09
5650
【C语言课程学习】:计算机中大端和小端字节序
C语言—大小字节序和字节序判断
超过一个字节的数据在内存中存储时,就有存储顺序的问题,按照不同的存储顺序分为大端字节序存储和小端字节序存储。 大端(存储)模式: 是指数据的低位存储在高地址处,高位存低地址处. 小端(存储)模式: 是指数据的低位存低地址处,高位存高地址处.
_孙同学
2024/10/21
1620
C语言—大小字节序和字节序判断
[c语言日寄]内存初阶:大端字节序和小端字节序
今天给大家带来的是大端字节序(Big Endian)和小端字节序(Little Endian)题目,它们在硬件层面、网络通信、编程语言和数据存储都有涉及。
siy2333
2025/02/05
2130
C语言-- 大端小端详解
16bit宽的数0x1234在Little-endian模式(以及Big-endian模式)CPU内存中的存放方式(假设从地址0x4000开始存放)为:
用户3479834
2021/02/03
5K0
大小端,你应该知道的,这篇文章讲全了
在计算机中,大小端描述了多字节数据在内存中的存储顺序。理解和正确处理大小端问题是编写健壮跨平台程序的关键。本文将全面介绍大小端的基本概念、判断方法、应用场景及注意事项,结合全样本数据分析哪些数据受大小端影响并给出处理方法。
程序员的园
2024/11/22
4530
大小端,你应该知道的,这篇文章讲全了
面试官:你能用Go写段代码判断当前系统的存储方式吗?
我一直都不理解,为什么要有大小端区分,尤其是小端,总是会忘记,因为他不符合人类的思维习惯,但存在即为合理,存在就有他存在的价值。这里有一个比较合理的解释:计算机中电路优先处理低位字节,效率比较高,因为计算机都是从低位开始的,所以计算机内部处理都是小端字节序。但是我们平常读写数值的方法,习惯用大端字节序,所以除了计算机的内部,其他场景大都是大端字节序,比如:网络传输和文件储存时都是用的大端字节序。
Golang梦工厂
2022/07/08
9300
面试官:你能用Go写段代码判断当前系统的存储方式吗?
机器大小端存储模式
一开始是由于不同架构的CPU处理多个字节数据的顺序不一样,比如x86的是小段模式,KEIL C51是大端模式。但是后来互联网流行,TCP/IP协议规定为大端模式,为了跨平台通信,还专门出了网络字节序和主机字节序之间的转换接口(ntohs、htons、ntohl、htonl)
用户11029129
2024/06/04
1710
机器大小端存储模式
【编程基础】简单理解大小端那些事儿
什么是计算机大小端?简单来说,大小端(Endian)是指数据存储或者传输时的字节序,大小端分大端和小端。 所谓大端(Big-Endian)模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。 所谓小端(Little-Endian)模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部
程序员互动联盟
2018/03/13
1.9K0
【编程基础】简单理解大小端那些事儿
C语言数据在内存中的存储超详解
实际上对于整形来说:数据存放在内存中的是补码。 为什么呢? 在计算机系统中,数值一律用补码来表示和存储。 原因在于,使用补码,可以将符号位和数值域统一处理。 同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是 相同的,不需要额外的硬件电路。 关于 其运算过程是相同的 这一点:正整数不必赘述,负数的补码是原码取反+1,如果要从补码得到原码的操作应该是-1再取反,但实际上由于是二进制,取反+1也能得到原码,因此说补码和反码的转换是相同的。
fhvyxyci
2024/09/24
1100
C语言数据在内存中的存储超详解
C++从入门到精通——类对象模型
类对象模型是一种编程概念,用于描述和实现面向对象编程(OOP)中的类和对象。在这个模型中,类定义了对象的结构和行为,包括数据成员(属性)和成员函数(方法)。对象是类的实例,具有类的所有属性和方法。类对象模型支持封装、继承和多态等OOP特性,使得代码更加模块化、可重用和易于维护。通过类对象模型,程序员可以创建复杂的软件系统,提高开发效率和代码质量。
鲜于言悠
2024/04/11
2420
C++从入门到精通——类对象模型
Golang 主机字节序的判断
字节序按类别分两种,一种是小端(Little Endian),另一种是大端(Big Endian)。 (1)小端字节序,指一个单元在计算机中存放时按照低位在低地址,高位在高地址的模式存放; (2)大端字节序,指一个单元在计算机中存放时按照低位在高地址,高位在低地址的模式存放。
恋喵大鲤鱼
2019/07/01
1.8K0
回溯--数据在内存中的存储:整数、大小端和浮点数的深度解析
在计算机系统中,数据的存储是非常基础但极其重要的一部分。理解数据在内存中的存储机制不仅有助于我们编写更高效的代码,还可以帮助我们理解一些计算机运行中的底层细节。这篇博客将为大家详细讲解整数和浮点数是如何存储在内存中的,并且会解释大端字节序与小端字节序的区别,最后介绍内存对齐的重要性及其实现方式。
用户11289931
2024/11/24
2040
推荐阅读
相关推荐
一文读懂大小端:从原理到实践的深度剖析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验