C语言中结构体大小

本文探讨了C语言中结构体大小不等于各成员简单相加的原因,实际上是由于字节对齐机制。结构体的大小遵循字节对齐规则,包括结构体变量首地址、成员相对偏移量和结构体总大小都需满足特定条件。通过测试不同结构体示例,展示了64位编译器下字节对齐的影响,例如结构体F、G、H等的大小并不只是成员的简单累加。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    以前用C语言时没多注意,似乎记得结构体的大小是其中各元素大小的简单相加。但今天,一位学弟在测试sizeof时发现了问题,问起来。经过测试发现确实不是如此,网上查资料,测试并总结如下。其实,还是自己没好好去研究C编译器的相关知识。
    其实就是C语言里的字节对齐机制(C++里也是如此):
    为满足以下原则,必要时编译器会填充字节。
    一,结构体变量的首地址能够被其最宽基本类型的成员(其内嵌的结构体要展开来看,只看其中基本类型的成员变量)大小所整除。
    二,结构体每个成员相对于结构体首地址的偏移量都是该成员大小的整数倍。
    三,结构体总大小为结构体最宽基本类型成员大小的整数倍(即使有嵌套)。
    四,结构体中的内嵌复合成员相对于结构体首地址的偏移量是该复合成员中最宽基本类型成员大小的整数倍。
    共用体大小取决于占据最多内存的成员的长度。但同时要满足字节对齐机制(三),所以,其末尾必要时会填充字节。

下面是当时写的一个测试代码,可能并没考虑到所有的情况。
测试时用的是64位的编译器,64位编译器的基本类型中,大体与32位的相同。但指针在64位编译器中占8字节,32位编译器中占4个。
#include<cstdio>
struct A{ char a; };                            //大小是1
struct B{ char a[3]; };                            //..3
struct C{ char a[3]; short b; };                //..6
struct D{ char a[3]; int b; };                    //..8
struct E{ char a[3]; short b; int c; };            //..12
struct F{ short a[3]; double b[4]; int c[5]; };    //..64
struct G{ char a[5]; double b; int c[7]; };    //..48
    struct X{ char a[16]; };
struct H{ X a[5]; int b; };                        //..84
    struct Y{ double a[2]; };
struct I{ char a,b,c; Y d; };                    //..24
struct J{ char a,b; double d; };                //..16
struct K{ char a; char b; double d; };            //..16
struct L{ char a; double d; char b; };            //..24
struct M{ char a, b[2], c; double d; };            //..16
struct N{ char a, *b, c; double d; };            //..32
struct O{ int *a[2]; double d; };                //..24
struct P{ double *a; int *b; double d; };        //..24
int main() {
    printf( "A: %d\n", sizeof( A ) );
    printf( "B: %d\n", sizeof( B ) );
    printf( "C: %d\n", sizeof( C ) );
    printf( "D: %d\n", sizeof( D ) );
    printf( "E: %d\n", sizeof( E ) );
    printf( "F: %d\n", sizeof( F ) );
    printf( "G: %d\n", sizeof( G ) );
    printf( "H: %d\n", sizeof( H ) );
    printf( "I: %d\n", sizeof( I ) );
    printf( "J: %d\n", sizeof( J ) );
    printf( "K: %d\n", sizeof( K ) );
    printf( "L: %d\n", sizeof( L ) );
    printf( "M: %d\n", sizeof( M ) );
    printf( "N: %d\n", sizeof( N ) );
    printf( "O: %d\n", sizeof( O ) );
    printf( "P: %d\n", sizeof( P ) );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值