C-结构体与共用体深度剖析

结构体为一堆相同或不同的数据类型的变量集合

结构体定义可看作一个模板(Template),而结构体变量可以看作是对这个模板的拷贝。

定义,声明

不带typedef

标签,变量,成员可选择性省略,一般至少包含两个

struct FFF//FFF为结构体标签,struct FFF为结构体数据类型名称,像int,long一样     
{
    int member_a;//三个结构体成员,可以是变量,指针,数组,甚至嵌套其他结构体         
    int member_b;         
    int member_c;             
}FFF_A,FFF_B[3] = {{1,2,3},{11,22,33},{111,222,333}},*FFF_P;//声明三个结构体变量,可以是数组,变量,指针     
struct FFF FFF_C;//另一种声明方法,如果省略结构体标签则不能用此方式声明

带typedef

typedef struct EEE//EEE为结构体标签     
{         
    int member_1;         
    int member_2;         
    int member_3;     
}EEE_A,EEE_B;//EEE_A,EEE_B为结构体的数据类型名称     
EEE_A a;//只能这样创建结构体数据类型了。

调用

.是成员访问符,用于普通结构体变量的成员访问

->是类成员访问符,其左值一定为指针。

    FFF_A.member_a = 22;//如果结构体变量就是一个普通变量的话就这样赋值     FFF_P = &FFF_A;//如果结构体变量为指针,那么他必须先有地址,否则p = 0x0     (*FFF_P).member_a = 33;//第一种方法:通过结构体指针变量访问的,这里要注意带括号否则.的优先级大于*     FFF_P->member_a = 44;//第二种方法:通过结构体指针变量访问的     FFF_B[1].member_a = 8888; aaa.AAA.a = 3;结构体嵌套访问。

结构体变量

结构体变量可以是结构体普通变量,结构体变量数组,结构体指针变量

普通变量

如果是一个变量,那么这个变脸包含结构体的成员。

数组结构体变量

如果是一个数组,那么数组中的每个元素都包含结构体的成员。

结构体指针变量

如果是一个指针,那么这个指针的数据类型为该结构体,则指针的值只能为相同结构体的其他变量的地址。千万不要用直接使用结构体指针中的默认地址,当有多个结构体指针和共用体指针的话,尽管不在他们的TAG(标签)是不同的,也可能会出现问题。

结构体变量名

结构体变量名本身无实际意义,但是&结构体变量名是整个结构体变量的地址。这点和数组不同。

结构体内存存储

存储顺序原则

结构体变量成员的存储顺序是连续的,并按照结构体成员的定义顺序进行存储。

如写的顺序为int a,char b,int c,那么存放的顺序就是a,b,c。

字节对齐原则

当在内存中存放一个变量时,这个变量占用的字节数n必须被地址整除。如int的话n = 4,地址就是4的倍数。

也就是说从内存的第一个字节开始,每四个字节为一字,int形的变量必须对齐字的第一个字节。double必须对齐两字的第一个字节。

字节填充原则

如果结构体的最大变量为一个结构体存储单元,如果第一个变量比第二个变量小,那么变量必须字节对齐。那么结构体存储单元中其余空间就会被编译器填充。如果结构体存储单元为int,如第一个变量为char,第二个变量为int,那么中间就有三个填充就造成了浪费。那么如果存储单元是double,那么实际上一个int类型一个char类型就分别造成成了7个字节的浪费和4个字节的浪费。

所以,在配置结构体时,最好调整存储顺序从而减少填充。

结构体内存占用

结构体内存占用为最大变量的数据类型的n倍。且足够放下所有成员。

例如一个结构体成员为int a, char b char c[3]

那么结构体最小为int的2倍数,也就是8个字节。

共用体

共用体与结构体类似,关键字为union,但是共用体变量在一个时刻只能为一个成员的数据类型。

定义,声明

不带typedef

union FFF//FFF为结构公用体标签     
{   double a;
    int a;
    char c;
}AA,BB[2],*CC;//公用体变量。可以是变量,数组,指针     
union FFF DD;//另一种创建共用体变量的方式。

带typedef

typedef union FFF     
{
    double a;         
    int a;         
    char c;     
}AA;
AA dd;

与结构体类似

共用体变量

共用体调用与结构体类似,但是一个时刻只能为一个变量的值。

普通变量

如果为普通变量,那么这个变量一个时刻只能为一个数据类型。

共用体数组变量

如果为数组,那么这个数组每个元素都是一个共用体变量

如果为指针,那么这个指针只能赋值给同一个副本下公用体的其他变量的地址。千万不要创建共用体指针后直接用,一定要赋值为其他共用体变量的值,否则会出问题。

共用体调用

共用体调用时,与结构体一样。都是使用(*a).member的方式或a->member。

共用体变量名

共用体变量名本身无实际意义,但是可以通过&来得到共用体地址以及*号可以访问。并sizeof中的是变量名而非&变量名。

结构体内存存储

最大的数据类型的倍数,可以满足单个的成员内存要求。如最大的类型为double = 8,但是数组最大为char a[12],那么结构体空间为两个double为16字节。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值