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

C/CPP 结构体、联合体、位段内存计算 指南

C/CPP 结构体、联合体、位段内存计算 指南

   在C语言中,结构体、联合体和位段是对数据的高级抽象,它们可以让程序员以更易于理解的方式来操作复杂的数据结构。然而,这些结构在内存中的布局可能并不如它们的语法结构那样直观,特别是当涉及到内存对齐和位段时。因此,理解这些结构在内存中的占用情况对编写高效的C程序非常重要。


零、常见内置类型占用大小

数据类型字节大小(Byte)位大小(Bit)
char18
short216
int432
long4 或 8(视平台而定)32 或 64
long long864
float432
double864
long double12 或 16(视平台而定)96 或 128
unsigned char18
unsigned short216
unsigned int432
unsigned long4 或 8(视平台而定)32 或 64

一、结构体内存计算

1.1 结构体的定义与内存对齐

   C语言中的结构体(struct)是用于将不同类型的变量组合在一起的用户自定义数据类型。编译器为了提高CPU访问速度,通常会对结构体成员进行内存对齐操作,即将成员存储在某些地址边界上。

示例:
#include <stdio.h>struct A {char c;int i;short s;
};int main() {printf("Size of struct A: %lu\n", sizeof(struct A));return 0;
}

   上述结构体中,成员的内存对齐方式会导致内存空隙的存在。char类型通常占1字节,int类型占4字节,而short类型占2字节。但在实际内存分配中,结构体A的大小可能是12字节而非7字节,因为编译器为了内存对齐,会在char后面添加3字节的填充。

1.2 内存对齐规则

  • 结构体的每个成员按其类型的大小进行对齐。
  • 结构体的总大小必须是最大成员大小的整数倍。
示例:
struct B {char c1;char c2;int i;
};int main() {printf("Size of struct B: %lu\n", sizeof(struct B));return 0;
}

   在这个例子中,两个char类型的成员c1c2通常会被对齐到4字节边界以便于后面的int成员,因此struct B的大小可能是8字节而不是6字节。


二、联合体内存计算

2.1 联合体的定义与特点

   C语言中的联合体(union)允许在相同的内存空间中存储不同类型的数据。所有的成员共用同一块内存,因此联合体的大小等于最大成员的大小。

示例:
#include <stdio.h>union C {int i;char c;double d;
};int main() {printf("Size of union C: %lu\n", sizeof(union C));return 0;
}

   在这个例子中,union C的大小等于double类型的大小(通常为8字节),因为它是最大成员。联合体中的其他成员也共享这8字节的内存。

2.2 联合体的内存管理

   由于联合体的所有成员共享同一块内存,只有一个成员可以在任意时刻保存有效数据。使用联合体时应小心管理数据,以避免数据被意外覆盖。


三、位段(Bit Fields)内存计算

3.1 位段的定义与用途

   C语言中的位段允许在结构体中定义占用特定位数的成员。它们常用于硬件寄存器编程和节省内存的场景。

示例:
#include <stdio.h>struct D {unsigned int a : 3;unsigned int b : 5;unsigned int c : 8;
};int main() {printf("Size of struct D: %lu\n", sizeof(struct D));return 0;
}

   在这个例子中,struct D中的三个成员分别占用了3位、5位和8位,总共16位。根据内存对齐规则,结构体D的大小会依赖于目标平台的内存分配机制。在32位系统中,struct D可能会占用4字节(32位),而在某些系统中可能会进一步优化。

3.2 位段的内存对齐

   位段成员的排列方式通常受制于目标机器的字节对齐要求。在某些系统中,位段可能无法跨字节边界进行存储,编译器会自动填充以确保对齐。

3.3 注意事项

  1. 位段的定义依赖于具体的编译器实现,跨平台使用时可能表现不同。
  2. 位段的宽度不能超过基础类型的大小。例如,一个unsigned int位段的宽度不能超过32位。

四、总结

   通过计算C语言中结构体、联合体和位段的内存占用大小,程序员能够更加清楚地了解程序的数据布局和效率。合理地选择数据结构并理解内存对齐规则,可以有效减少内存浪费,优化系统性能。这在嵌入式系统、硬件编程、数据传输等场景中尤其重要。尤其是当我们需要在资源受限的系统中最大限度地压缩内存占用时,位段等技术提供了极大的灵活性。

内存计算的意义在于:

  1. 提高程序的内存效率:合理设计结构体可以减少填充字节,减少内存开销。
  2. 优化性能:内存对齐可以提升CPU访问内存的效率,避免性能损耗。
  3. 便于跨平台移植:了解不同平台的内存对齐规则有助于编写跨平台的可移植代码。
  4. 精确控制硬件资源:在与硬件设备交互时,位段的使用可以帮助控制硬件寄存器中的具体位,提高控制精度。

   通过这些优化,可以在多种场景中有效提升C/CPP程序的性能和资源利用率。

http://www.xdnf.cn/news/944353.html

相关文章:

  • 总结input标签的各种类型
  • 可视化预警系统:如何实现生产风险的实时监控?
  • 篮球杯软件赛国赛C/C++ 大学 B 组补题
  • GC1808:高性能音频ADC的卓越之选
  • Web APIS Day01
  • 超低成本U型光电开关红外对射管检测电路
  • 基于单片机的宠物屋智能系统设计与实现(论文+源码)
  • 力扣HOT100之栈:394. 字符串解码
  • 256bps!卫星物联网极低码率语音压缩算法V3.0发布!
  • docker容器保存为不依赖基础镜像的独立镜像方法
  • 【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
  • 深入剖析AI大模型:大模型时代的 Prompt 工程全解析
  • Jenkins自动发布C# EXE执行程序
  • Unity中的对象池ObjPool/PoolManager
  • 安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
  • 基于Python的气象数据分析及可视化研究
  • Python打卡训练营学习记录Day49
  • C++11智能指针
  • Linux入门(十五)安装java安装tomcat安装dotnet安装mysql
  • 虚拟机网络不通的问题(这里以win10的问题为主,模式NAT)
  • Python爬虫(52)Scrapy-Redis分布式爬虫架构实战:IP代理池深度集成与跨地域数据采集
  • 使用 C# 将 Word、Excel、PDF 和 PPT文档转换为 Markdown 格式
  • 《C++初阶之入门基础》【普通引用 + 常量引用 + 内联函数 + nullptr】
  • 【BUG】记STM32F030多通道ADC DMA读取乱序问题
  • 2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
  • 曲面的存在性定理
  • 【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
  • 【医疗电子技术】新型医疗电子和医学人工智能发展现状和趋势
  • 【异常】极端事件的概率衰减方式(指数幂律衰减)
  • 漏洞检测方案如何选工具?开源与商业工具适用环境大不同