C语言基础之结构体进阶

本文详细介绍了C语言结构体的对齐规则,包括基本对齐方式和自定义对齐方式,强调了`pragma pack()`的作用和影响。同时,讨论了位字段的使用限制及访问方式,以及结构体中的动态数组(柔性数组)的应用。最后,提到了在操作系统内核中常用的结构体相关宏,用于获取元素偏移量和计算结构体首地址。
摘要由CSDN通过智能技术生成

1,结构体元素的对齐规则

基本对齐方式

为了提高访问效率,结构体里变量的存储遵循一定的规则
例如:

#include <stdio.h>
struct data
{
    char a; // 填充3个字节
    int b;
    short c;
}s;    // 结构体变量名s
int main(void)
{
    printf("sizeof(s) = %d.\n", sizeof(s));
} 

输出的结果是12,因为char填充了3个字节,short填充了2个字节
但如果加上double型变量,结果却不是12+8=20:

#include <stdio.h>
struct data
{
    char a; 
    int b;
    short c;
    double d;
}s;
int main(void)
{
    printf("sizeof(s) = %d.\n", sizeof(s));
} 

而是24,原因在于:1,在64位系统下结构体元素默认是8字节对齐,而在32位系统默认4字节对齐。
2,默认的对齐方式和结构体本身元素对齐方式相比,两者取其小。
所以,第一个例子,结构体里元素最大是int,4字节,比默认的8字节小,所以4字节对齐;
第二个例子,结构体里最大元素是double,8字节,所以8字节对齐。

自定义对齐方式

#pragma pack(n) //设置结构体对齐方式,限制一个区间 n = 2的次方(0、1、2…)
如上例一,将其定义为2字节对齐:

#include <stdio.h>
#pragma pack(2)   
struct data
{
    char a; 
    int b;
    short c;

}s; 
int main(void)
{
    printf("sizeof(s) = %d.\n", sizeof(s));
} 

则打印结果为8,因为2比默认的8位小,所以就按2字节对齐

注意:pragma pack()只对接下来相邻的结构体有效
总结:你指定的对齐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值