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

深入理解C语言共用体/联合体(union):大小计算与大小端判断实战

在C语言中,共用体[还有一种称呼是联合体](union)是一种特殊的数据结构,其所有成员共享同一块内存空间,这一特性使其在内存优化和底层编程中极具实用价值。本文将通过三组实战代码,拆解共用体的内存大小计算与大小端字节序判断两大核心应用,帮你彻底搞懂共用体的底层逻辑。

 

一、共用体的内存大小计算:为什么不是成员大小之和?

 

首先看第一组代码,核心是探究共用体的 sizeof 结果:

union Un

{

    char a[5]; // 字符数组,占5字节

    int b; // 整型,占4字节

};

 

int main()

{

    union Un un = { 0 };

    printf("%d\n", sizeof(un)); // 输出结果是多少?

    return 0;

}

 

 

关键结论:

 

共用体的内存大小遵循两个规则:

 

1. 最大成员对齐规则:大小为“最大成员大小”的整数倍(满足内存对齐要求);

2. 共享内存规则:所有成员共用一块内存,大小不会累加。

 

这里最大成员是 char a[5] (5字节),但内存对齐要求需是 int (4字节)的整数倍,因此最小满足条件的是8字节,最终 sizeof(un) 输出8。

 

二、大小端字节序:计算机存储数据的“顺序密码”

 

在讲解第二、三组代码前,先明确大小端的核心概念:

 

- 大端字节序:数据的高位字节存低地址,低位字节存高地址(如 0x11223344 , 0x11 存低地址);

- 小端字节序:数据的低位字节存低地址,高位字节存高地址(如 0x11223344 , 0x44 存低地址)。

 

日常使用的x86架构CPU多为小端,而嵌入式、网络传输中常涉及大端,因此需要通过代码判断当前环境的字节序。

 

三、两种大小端判断方案:数组法vs共用体法

 

方案1:整型+字符指针(数组思想)

 

int reck() // 1为大端,0为小端

{

    int a = 0x11223344; // 4字节整型,二进制高位到低位:11 22 33 44

    char* p = (char*)&a; // char*仅访问1字节,指向a的低地址

    if (*p == 0x11) // 若低地址存高位0x11 → 大端

        return 1;

    else // 若低地址存低位0x44 → 小端

        return 0;

}

 

int main() 

{

    printf("当前是%s端\n", reck() ? "大" : "小");

    return 0;

}

 

 

方案2:共用体法(利用共享内存特性)

union Un

{

    char b; // 1字节,共享int的低地址

    int a; // 4字节,覆盖整个共用体内存

};

 

int reck() // 1为大端,0为小端

{

    union Un un;

    un.a = 0x11223344; // 给int赋值,覆盖共用体内存

    char* p = &un.b; // 指向共用体低地址(即char b的地址)

    return (*p == 0x11) ? 1 : 0; // 判断低地址存储的字节

}

 

int main()

{

    printf("当前是%s端\n", reck() ? "大" : "小");

    return 0;

}

 

 

两种方案对比:

 

- 数组法:逻辑直接,无需借助共用体,适合入门理解;

- 共用体法:更贴合底层内存设计,利用“成员共享内存”特性,代码更简洁,是工业级常用方案。

 

注意:代码易错点修正

 

原代码中 if (*p = 0x11) 是赋值操作( = ),而非判断( == ),会导致结果始终为1,实际开发中需务必修正为判断运算符 == !

 

四、核心总结

 

1. 共用体大小 = 最大成员大小的整数倍(内存对齐);

2. 大小端判断的核心:通过“访问低地址1字节数据”,判断其是原数据的高位还是低位;

3. 共用体是底层编程的“利器”,除了大小端判断,还可用于内存复用、硬件寄存器操作等场景。

http://www.dtcms.com/a/589505.html

相关文章:

  • ITIL 4 测评题库试卷及详细分析
  • 数据库基础-01Mysql库和表的操作
  • linux服务ping不通百度的解决过程【ping www.baidu.comping: unknown host】
  • 广州网站建设模板设计素材库
  • 深入浅出蓝桥杯:算法基础概念与实战应用(一)基础算法(上)
  • C++ vector 全面解析:从接口使用到底层机制
  • 亚马逊欧洲站vat怎么申请湖南企业做网站
  • vite-plugin-vue-mcp:在 Vue 3 + Vite 中启用 MCP,让 AI 理解并调试你的应用
  • 如何20元/年开通Termius专业版
  • 树莓派docker_freeCAD环境搭建
  • 数字营销网站建设佛山规划建设局网站
  • 【数据结构】位图和布隆过滤器
  • 对于数据结构:堆的超详细保姆级解析——下(堆排序以及TOP-K问题)
  • (* MARK_DEBUG=“true“ *)
  • 章丘哪里做网站做商城网站产品怎么分布
  • 使用docker部署Java项目
  • PyTorch深度学习进阶(三)(残差网络ResNet)
  • 02.第一个Python程序
  • 【Redis】Redis分布式缓存 - 分片集群
  • 论基层门户网站的建设vi设计手册完整版案例
  • Spring AI调用MCP服务
  • Goer系列-1-Docker基础命令学习
  • Tauri快速搭建环境
  • 光的压缩态:突破量子极限的 “超精准光源” 科普详解
  • 【C++】分治-归并排序算法习题
  • 网站开发服务合同印花税wordpress主题微博
  • 网站 功能呢杭州如何设计公司网站
  • Ansys SAM 与 Scade One:重塑安全关键系统开发的 MBSE 新范式
  • ADC的学习
  • 【智能体】扣子平台 ① 构建智能体工作流:从提示词到JSON配置的全流程实践