c语言嵌套结构体的输出,结构体大小的计算中嵌套结构体的状况

本文探讨了在结构体大小计算中,特别是嵌套结构体时,对齐值和内存布局的正确理解。作者通过实例解析了两种不同的计算方法,并强调了结构体成员对齐的重要性。实验通过查看内存地址来验证,最终揭示了考虑对齐值在结构体大小计算中的必要性。
摘要由CSDN通过智能技术生成

结构体大小的计算中嵌套结构体的情况

以下的结构体struct A

{

char c;

struct B

{

double dbNum;

}stB;

} stA;

在计算结构体大小的时候,如果结构体中嵌套结构体,这时候计算结构体大小应该怎么算呢?

编译器对齐值设置为8,我的计算方式是:

变量c的偏移是0,结构体stB的偏移是+8,再加上stB本身8的大小,所以结构体A大小为16.

我同学的计算方式是:

变量c的偏移是0,结构体stB的偏移是+1,再加上stB本身大小,stA为9,考虑结构体成员dbNum影响对齐值,结果也为16.

我俩的理解方式就是结构体stB是不是可以视为一个普通类型的成员,参与stA的运算,当然是stA的有效对齐值参与运算,这两种方法结果是正确的,但是理解方式有区别,我看到网上大都是最后才考虑对齐值的,是不是我理解错了?请高人指点一下,谢谢

------解决方案--------------------

你的理解应该是对的,你同学的错了

首先要搞清楚为什么需要字节对齐。如果是你同学的那种方式,那么cpu在读取stB的时候,需要做两次读操作。这样很耗时的

------解决方案--------------------

输出它们的指针, 应该会有所发现.

------解决方案--------------------

#include 

#define field_offset(s,f) (int)(&(((struct s *)(0))->f))

struct AD  { int a; char b[13]; double c;};

#pragma pack(push)

#pragma pack(1)

struct A1  { int a; char b[13]; double c;};

#pragma pack(2)

struct A2  { int a; char b[13]; double c;};

#pragma pack(4)

struct A4  { int a; char b[13]; double c;};

#pragma pack(8)

struct A8  { int a; char b[13]; double c;};

#pragma pack(16)

struct A16 { int a; char b[13]; double c;};

#pragma pack(pop)

int main() {

printf("AD.a %d\n",field_offset(AD,a));

printf("AD.b %d\n",field_offset(AD,b));

printf("AD.c %d\n",field_offset(AD,c));

printf("\n");

printf("A1.a %d\n",field_offset(A1,a));

printf("A1.b %d\n",field_offset(A1,b));

printf("A1.c %d\n",field_offset(A1,c));

printf("\n");

printf("A2.a %d\n",field_offset(A2,a));

printf("A2.b %d\n",field_offset(A2,b));

printf("A2.c %d\n",field_offset(A2,c));

printf("\n");

printf("A4.a %d\n",field_offset(A4,a));

printf("A4.b %d\n",field_offset(A4,b));

printf("A4.c %d\n",field_offset(A4,c));

printf("\n");

printf("A8.a %d\n",field_offset(A8,a));

printf("A8.b %d\n",field_offset(A8,b));

printf("A8.c %d\n",field_offset(A8,c));

printf("\n");

printf("A16.a %d\n",field_offset(A16,a));

printf("A16.b %d\n",field_offset(A16,b));

printf("A16.c %d\n",field_offset(A16,c));

printf("\n");

return 0;

}

//AD.a 0

//AD.b 4

//AD.c 24

//

//A1.a 0

//A1.b 4

//A1.c 17

//

//A2.a 0

//A2.b 4

//A2.c 18

//

//A4.a 0

//A4.b 4

//A4.c 20

//

//A8.a 0

//A8.b 4

//A8.c 24

//

//A16.a 0

//A16.b 4

//A16.c 24

//

//

------解决方案--------------------

打印两个变量的内存地址看一下就知道了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值