169-学习结构体

结构体类型的设计

C语言提供了基本数据类型,如char,short,int,float…等类型,我们称之为内置类型。程序开发人员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称之为结构体类型

结构体类型的设计:
在C语言中,结构体是一种数据类型。(由程序开发者自己设计的类型)
可以使用结构体(struct)来存放一组不同类型的数据。
结构体的定义形式为:
struct 结构体名
{
成员列表(可以是基本数据类型,指针,数组或其他结构体类型)
};

我们自己设计一个学生类型
客观事物(实体)是复杂的,要描述它必须从多方面进行,也就是用不同的数据类型来描述不同的方面。如学生实体可以这样来描述:
学生学号(用字符串描述), 学生姓名(用字符串来描述),性别(用字符串来描述),年龄(用整型数描述)。
这里用了属于2种不同数据类型,以及4个数据成员来描述学生实体
图示:
在这里插入图片描述
函数定义的花括号{}后面没有分号

结构体变量的定义和初始化
既然结构体是一种数据类型,那么就可以用它来定义变量。结构体就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。
结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要存储空间。

结构体变量在内存中表示(暂不考虑内存对齐问题)
在这里插入图片描述
结构变量初始化
在这里插入图片描述
在这里插入图片描述
结构体嵌套结构体
在这里插入图片描述
结构体自定义
在这里插入图片描述
在这里插入图片描述
结构体成员访问(获取和赋值)
结构体变量的成员,访问
获取和赋值结构体变量成员的一般形式为:
结构体变量,成员名:

结构体变量成员的访问:
在这里插入图片描述
注意:对结构体变量整体赋值有3种情况
1、定义结构体变量(用{}初始化)
2、用已定义的结构变量初始化
3、结构体类型相同的变量可以作为整体相互赋值

其他情况的使用过程中只能对成员逐一赋值
在C语言中不存在对结构体类型的强制转换(和内置类型的区别)

结构体变量和指针
内置类型能够定义指针变量,结构体类型也可以定义结构体类型指针。
结构体类型指针访问成员的获取和赋值形式:
(*p).成员名(.的优先级高于 ,( p)两边的括号不能少)

p->成员名(->是减号加大于号,中间没有空格,称为指向符)
在这里插入图片描述
结构体变量和函数
在这里插入图片描述
只是第打印而已,第一种方式比较好,数据安全,使用第二种方式可能会修改主函数sx的数据

结构体与数组
所谓结构体数组,是指数组中的每个元素都是一个结构体类型。在实际应用中,C语言结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生,一个公司的员工等。
在这里插入图片描述
结构体大小
在这里插入图片描述
由于存储变量地址对齐的问题,计算结构体大小的3条规则:
1、结构体变量的首地址,必须是结构体变量中的“最大基本数据类型成员所占字节数”的整数倍
2、结果体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍
3、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节数”的整数倍

假设是从0地址开始
在这里插入图片描述

sizeof(struct node)=sizeof(sd)=12;

详细示例见我另外一篇博客《结构体的大小怎么算?》

为什么要理解字节对齐问题?

1、内存大小的基本单位是字节(byte),理论上讲,可以从任意地址访问变量,但是实际上,CPU并非逐字节读写内存,而是以2,4或8的倍数的字节块来读写内存,因此就会对基本数据类型的地址作一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。
2、有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果放在偶地址开始的地方,那么一个读周期就可以读出32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
3、由于不同平台对齐方式可能不同,如此一来,同样的结构在不同的平台其大小可能不同,在无意识的情况下,互相发送的数据可能出现错乱,甚至引发严重的问题。

指定对齐值
预处理命令#pragma pack(n)可以改变默认对齐数。 n取值是1,2,4,8,16
VS中默认值=8,gcc中默认值=4;

在这里插入图片描述
总结:
1、结构体变量的首地址,必须是MIN{“结构体最大基本数据类型成员所占字节数”,指定对齐方式}大小的整数倍
2、结构体每个成员相对于结构体首地址的偏移量,都是MIN{基本数据类型成员,指定对齐方式}大小的整数倍
3、结构体的总大小,为MIN{结构体“最最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式}大小的整数倍

联合体(共用体)

联合体(union)与结构体(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间。而在联合体中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。
应该说明的是,这里所谓的共享不是指把多个成员同时装入一个联合变量内,而是指该联合变量可被赋予任一成员值,但每次只能赋一种值,赋入新值则冲去旧值。
一个联合体类型必须经过定义之后,才能使用它,才能把一个变量声明定义为该联合体类型。
在这里插入图片描述
程序演示:使用联合体变量
在这里插入图片描述
关于IP地址
在这里插入图片描述

枚举

枚举顾名思义就是一一列举。把需要的取值一一列举。
比如:星期表示,月份表示:
枚举的特点是:枚举类型是受到限制的有符号整型类型,枚举值必须是整型类型(有符号);枚举变量的取值范围必须是枚举值集合。

枚举类型的设计:
在这里插入图片描述
定义枚举变量 enum week x=Mon;
1、取值只能赋值为{枚举值集合中值};
2、枚举变量不能++,–;

枚举与常变量,#define 定义常量的区别

1、增加代码的可读性和维护性
2、和#define 定义的标识符比较,枚举有类型检查,更加严谨
3、封装性好
4、便于调试
5、使用方便,一次可以定义多个常量

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林林林ZEYU

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

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

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

打赏作者

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

抵扣说明:

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

余额充值