结构体与联合体计算(二)


前言

本文主要介绍结构体与联合体的具体计算方法


1.基本概念介绍

偏移量: 把存储单元的实际地址与其所在段的段地址之间的距离
成员大小: 变量所占空间大小
成员类型大小: 变量类型所占空间大小
大小单位: 字节

2.计算结构体大小的规则:

1.每一个成员相对于结构体首地址的偏移量都得是当前成员大小的整数倍,如果不是编译器就会在成员之间加上填充字节
2.依据前一规则计算好结构体的大小后,还需保证结构体的大小是最大成员类型的整数倍,如果不是编译器就会填充字节。

3.联合体(Union)大小的计算

1.联合体特性

联合体所有成员变量共享内存,相对于联合体首地址偏移量都为0,同一时间只能存储1个被选择的变量,对其他成员变量赋值会覆盖原变量。

2.联合体大小计算规则

联合体大小要至少能容纳最大的成员变量
联合体大小要是所有成员类型最大值的整数倍。

3.结构体/联合体嵌套结构大小的计算

1.当结构体里面嵌入联合体时
1、嵌套联合体前一个成员的偏移量应当是嵌套联合体中最大成员类型的整数倍;
2、结构体的大小必须是所有成员类型大小的整数倍,这里所有成员计算的是包括嵌入联合体内所有成员在内,而不是将嵌套的联合体当做一个整体;

#include <stdio.h>
int main ()
{
struct strA
{  
      char a; 
	  short b;  
	  int c; 
	  char d;
	  char e;
      union strB   
      {  
           char a;
		   int b ; 
           short c; 
		   double d; 
      }s;   
    char f;  

} ss;
	printf ("ss.a:\t%p\n",&ss.a);
	printf ("ss.b:\t%p\n",&ss.b);
	printf ("ss.c:\t%p\n",&ss.c);
	printf ("ss.d:\t%p\n",&ss.d);
	printf ("ss.e:\t%p\n",&ss.e);
	printf ("ss.a的偏移量:\t%d\n",&ss.s.a-&ss.a);
	printf ("ss.s.a:\t%p\n",&ss.s.a);
	printf ("ss.s.b:\t%p\n",&ss.s.b);
	printf ("ss.s.c:\t%p\n",&ss.s.c);
	printf ("ss.s.d:\t%p\n",&ss.s.d);
	printf ("ss.f的偏移量:\t%d\n",(&ss.f-&ss.a));
	printf ("f:\t%p\n",&ss.f);
    printf ("%d",sizeof(ss));
    return 0;
}
运行结果:
ss.a:   000000000062FE00
ss.b:   000000000062FE02
ss.c:   000000000062FE04
ss.d:   000000000062FE08
ss.e:   000000000062FE09
ss.a的偏移量:   16
ss.s.a: 000000000062FE10
ss.s.b: 000000000062FE10
ss.s.c: 000000000062FE10
ss.s.d: 000000000062FE10
ss.f的偏移量:   24
f:      000000000062FE18
32

2.结构体里面嵌入结构体时:
1、嵌入的结构体前一个成员的偏移量应当是嵌入结构体中最大成员类型的整数倍;
2、结构体的大小必须是所有成员类型大小的整数倍,这里所有成员计算的是包括嵌入结构体内所有成员在内,而不是将嵌入的结构体当做一个整体;

#include <stdio.h>
int main ()
{
struct strA
{  
      char a; 
	  short b;  
	  int c; 
	  char d;
	  char e;
      struct strB   
      {  
           char a;
		   int b ; 
           short c; 
		   double d; 
      }s;   
    char f;  

} ss;
	printf ("ss.a:\t%p\n",&ss.a);
	printf ("ss.b:\t%p\n",&ss.b);
	printf ("ss.c:\t%p\n",&ss.c);
	printf ("ss.d:\t%p\n",&ss.d);
	printf ("ss.e:\t%p\n",&ss.e);
	printf ("ss.a的偏移量:\t%d\n",&ss.s.a-&ss.a);
	printf ("ss.s.a:\t%p\n",&ss.s.a);
	printf ("ss.s.b:\t%p\n",&ss.s.b);
	printf ("ss.s.c:\t%p\n",&ss.s.c);
	printf ("ss.s.d:\t%p\n",&ss.s.d);
	printf ("ss.f的偏移量:\t%d\n",(&ss.f-&ss.a));
	printf ("f:\t%p\n",&ss.f);
    printf ("%d",sizeof(ss));
    return 0;
}
运行结果:
ss.a:   000000000062FDF0
ss.b:   000000000062FDF2
ss.c:   000000000062FDF4
ss.d:   000000000062FDF8
ss.e:   000000000062FDF9
ss.a的偏移量:   16
ss.s.a: 000000000062FE00
ss.s.b: 000000000062FE04
ss.s.c: 000000000062FE08
ss.s.d: 000000000062FE10
ss.f的偏移量:   40
f:      000000000062FE18
48
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值