C语言入门:进阶篇06 结构 联合 枚举

C语言中的struct、联合与枚举详解
文章详细介绍了C语言中的struct结构体,包括设计、定义、访问成员、初始化以及类型重定义。还讨论了内存对齐和内存补齐的概念,以及如何计算结构体的总字节数。此外,提到了联合和枚举的特性及其与结构体的区别。枚举用于限制特定类型值的范围,而联合则允许在有限内存中共享多个成员。

1 结构

        由程序员自己设计的一种数据类型,用于描述一种事物的各项数据,由若干个不同的基础类型组成。

1.1 设计

        struct 结构体类型名
        {  
            类型名1 成员名1;
            类型名2 成员名2;
                 ...
        };

1.2 定义

        struct 结构体类型名 结构体变量名;

*注意:c语言定义结构变量时struct关键字不能省略

1.3 访问成员

        结构体变量名.成员名;

*注意:字符串赋值要用函数strcpy!!

        结构体变量名->成员名;

*注意:

        ① 由于结构体变量一般字节数较大,普通的值传递会效率较低,因此一般都传递结构变量的地址

        ② 存储结构变量一般存在堆内存比较合适

1.4 初始化

        struct 结构体类型名 结构体变量名={数据1,数据2...};

*注意:必须根据成员的设计顺序初始化

        struct 结构体类型名 结构体变量名={.成员名1=数据1,.成员名2=数据2...};

*注意:不需要按照顺序,只初始化某些成员

        struct 结构体类型名 结构体变量名 = 同类型的结构变量

*注意:同类型的结构变量可以直接整体赋值

1.5 类型重定义

1.5.1方法1:

        typedef struct 结构体类型名
        {  
            类型名1 成员名1;
            类型名2 成员名2;
                 ...
        }结构体类型名;

1.5.2 方法2

        typedef struct 结构体类型名 结构体类型名

1.6 函数使用

        void tch_show(const struct Teacher* tch)
        {
            printf("%s %c %d %hd",tch->name,tch->sex,tch->id,tch->wage);
        }

1.7 如何计算结构体的总字节数

        结构成员的顺序可能会影响总字节数,因此如果能够在设计结构体时合理安排成员顺序可以大大节约内存

1.7.1 内存对齐

        假设第一个成员的地址编号从0地址开始,之后存储每个成员的地址编号必须能被该成员类型字节数整除,如果不能整除,则填充空白字节数直到能整除为止。

*例如:以下是40字节,发生了内存对齐。

    typedef struct Data
    {
        char name[20];
        char sex;
        int id;
        char age;
        double score;
    }Data;

         具体过程可见下图:        

1.7.2 内存补齐

        整个结构体的总字节数必须能被它字节数最大的成员整除,如果不能则在末尾填充空白字节直到能整除为止。

*例如:以下是8字节,不发生内存对齐,但发生了内存补齐。     

    typedef struct Data
    {
        int id;
        char age;
    }Data;

          具体过程可见下图:        

*注意:

        ① 在linux系统中,计算结构体的对齐和补齐时,如果成员的类型字节数超过4,就按照4字节算;

        ② 在windows中,会根据实际字节数计算;

        ③ 预处理指令#pragma pack(n) 可以设置对齐、补齐最大字节数,在Linux中只有1和2有效果。

二、联合

        联合与结构的适用方法基本一致,与结构体的区别是所有成员共用一块内存,其中一个成员值改变,其他成员的值也会随之改变

    联合就是想用少量的内存对用较多的标识符,从而节约内存的目的,现在基本不再使用了

    计算联合的字节数时候,虽然不用考虑内存对齐,但是依然要考虑内存补齐。

三、枚举:enum

        枚举就是希望把一种类型可能出现的所有的值罗列出来,并取一个有意义的名字表示,除此之外,该类型的值如果是其他值则非法。

        可以把枚举当做值受限的int类型,但是gcc编译器不检查。

*注意:

        ① gcc不检查是否非法,g++检查

        ② 如果枚举成员不赋值,那么成员的值默认从0开始,逐渐+1,如果某个成员设置了值,后续的成员在它的基础上逐渐+1。

3.1 枚举常量和宏定义的区别

        ① 枚举常量需要占用内存,宏常量定义不占用内存

        ② 枚举常量设计目的是为了限制实际数据的输入,宏常量是为了完成代码的替换和维护。

        ③ 枚举常量是有类型,宏定义没有类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就酱77叭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值