50字范文,内容丰富有趣,生活中的好帮手!
50字范文 > 深度剖析 —— 结构体

深度剖析 —— 结构体

时间:2024-06-23 09:48:22

相关推荐

深度剖析 —— 结构体

系列文章目录

深度剖析:数据

深度剖析:递归

深度剖析:结构体

深度剖析:动态内存管理

深度剖析:文件操作

深度剖析:预处理

文章目录

系列文章目录前言一、示例问题:创建通讯录1.通讯录的需求 二、结构体1.建立结构声明2.创建结构变量3.初始化结构体4.访问结构成员 三、结构体数组1.创建结构数组2.数组的初始化3.数组访问成员 四、嵌套结构1.结构体的嵌套2.嵌套的初始化3.嵌套访问成员 五、结构体指针1.创建结构指针2.指针的初始化3.指针访问成员 六、结构体的计算1.空间换取时间2.结构体的存储 总结

前言

在设计程序时,最重要的步骤之一是选择表示数据的方法。许多情况下数组已经部能很好的满足我们的需求,而结构变量通过创造新的形式提高了我们表示数据的能力。

一、示例问题:创建通讯录

1.通讯录的需求

通讯录就需要一种能包含数字的数据形式,而切要保持各信息的独立

信息

名字年龄性别电话地址

功能

增加删除查找修改排序

二、结构体

1.建立结构声明

结构声明(structure declaration)描述了一个结构组织布局

struct PeoInfo {char Name[8];char Sex[4];int Age;char Telephone[12];char Address[12];};

该声明描述了一个由四个字符数组和一个整型变量组成的结构。该声明并未创建实际的数据,只是描述了该对象由什么组成。

从本质上看,结构声明创建了一个名为struct PeoInfo的新类型(int double等类型等价) 。

struct

它表明其后的是一个结构struct PeoInfo则是这个结构的名称

2.创建结构变量

结构变量定义了一个struct PeoInfo类型的变量

struct PeoInfo Mail;

此时此刻才向堆栈申请了一块sizeof(struct PeoInfo)大小的空间(这里是为了便于理解所以恰好设置了40个字节的大小布局,后面会有结构体大小的计算详解)。

3.初始化结构体

struct PeoInfo类型也可以直接进行初始化

struct PeoInfo Mail = {"小明", "男", 18, "11111111111", "某小区"};

struct PeoInfo和int等其他类型一样,可以直接进行赋值,它的内容需要由花括号括起来,各初始化项由逗号进行分隔。

4.访问结构成员

结构体成员的基本访问(对象.访问成员或指针->访问成员)

printf("%s", Mail.Name);printf("%s", Mail.Sex);printf("%d", Mail.Age);printf("%s", Mail.Telephone);printf("%s", Mail.Address);

本质上Name、Sex、Age、Telephone、Address都是struct PeoInfo的下标,就像数组的下标0、1、2、3一样,数组是用[ ]来访问所在下标位置的元素, 而结构体则是用.->来访问成员。

三、结构体数组

1.创建结构数组

创建结构数组创建明其他类型的数组类似

struct PeoInfo Mail[100];

与其他类型一样,数组的每一个元素又是struct PeoInfo类型的元素。

2.数组的初始化

与其他数组一样只能在创建的时被直接初始化

struct PeoInfo Mail[20] = {{"小明", "男", 18, "11111111111", "某小区"}, {"小红", "女", 18, "11111111111", "某小区"}};

下面的这种写法是错误的!

Mail[0] = {"小明", "男", 18, "11111111111", "某小区"}; //错误示例

3.数组访问成员

找到结构数组的某一个元素的下标进行访问

printf("%s", Mail[0].Name);printf("%s", Mail[0].Sex);printf("%d", Mail[0].Age);printf("%s", Mail[0].Telephone);printf("%s", Mail[0].Address);

四、嵌套结构

1.结构体的嵌套

当我们需求更丰富时就需要在结构体中嵌套一层结构体

//成员信息struct PeoInfo {char Name[8];char Sex[4];int Age;char Telephone[11];char Address[13];};//通讯录struct Contact {struct PeoInfo Data[MAX]; //存放增加进来的人的信息(此处为结构体的嵌套)int count; //记录当前通讯录中有效信息的个数} Contact;

2.嵌套的初始化

嵌套式结构体建议一个一个进行赋值而非直接初始化

//方法一strcpy(Mail.Data[0].Name, "小明");strcpy(Mail.Data[0].Sex, "男");Mail.Data[0].Age = 18;strcpy(Mail.Data[0].Telephone, "11111111111");strcpy(Mail.Data[0].Address, "某小区");//方法二scanf("%s", Mail.Data[0].Name);scanf("%s", Mail.Data[0].Sex);scanf("%d", &Mail.Data[0].Age);scanf("%s", Mail.Data[0].Telephone);scanf("%s", Mail.Data[0].Address);

当结构体过于复杂时,不建议像下面代码这样直接初始化,当嵌套更加复杂时,直接初始化会非常困难。

struct Contact Mail = {{{"小明", "男", 18, "11111111111", "某小区"},{"小红", "女", 18, "11111111111", "某小区"}}, 20};

3.嵌套访问成员

嵌套成员依然是一层一层的去访问(与前面一模一样)

printf("%s", Mail.Data[0].Name);printf("%s", Mail.Data[0].Sex);printf("%d", Mail.Data[0].Age);printf("%s", Mail.Data[0].Telephone);printf("%s", Mail.Data[0].Address);

五、结构体指针

1.创建结构指针

指向结构体的指针

struct Contact *PMail;

2.指针的初始化

当结构体过于复杂时建议一个一个进行赋值

//方法一 (结构体过于复杂时不推荐该方法)struct Contact Mail = {{{"小明", "男", 18, "11111111111", "某某小区"},{"小红", "女", 18, "11111111111", "某某小区"}}, 20};struct Contact *PMail = &Mail;//方法二strcpy(PMail->Data[0].Name, "小明");strcpy(PMail->Data[0].Sex, "男");PMail->Data[0].Age = 18;strcpy(PMail->Data[0].Telephone, "11111111111");strcpy(PMail->Data[0].Address, "某小区");//方法三scanf("%s", PMail->Data[0].Name);scanf("%s", PMail->Data[0].Sex);scanf("%d", &PMail->Data[0].Age);scanf("%s", PMail->Data[0].Telephone);scanf("%s", PMail->Data[0].Address);

3.指针访问成员

访问时可以*指针.->直接访问

printf("%s", PMail->Data[0].Name);printf("%s", PMail->Data[0].Sex);printf("%d", PMail->Data[0].Age);printf("%s", PMail->Data[0].Telephone);printf("%s", PMail->Data[0].Address);

六、结构体的计算

1.空间换取时间

效率至上:在尽可能不浪费空间的情况下,尽可能的提高运行的效率来达到我们想要的结果。所以在结构体的存储方面我们选择牺牲较少的空间,来降低计算机计算的时间复杂度,便于更快的运行程序。

2.结构体的存储

存储法则 第一个成员在与结构体变量偏移量为0的地址处。 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。(对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值)。 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处。 结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。 计算结构体的偏移量:offsetof (type, 成员)修改默认最大对齐数8:#pragma pack(最大对齐数)(一般设置为2的n次方)

//计算下面代码的大小struct Book {char title[3];int count;short value;};

题解

int的对齐数是4,而char占了3个字节,显然不是4的整数倍,于是浪费1个空白字节从而凑出4个字节恰好为int对齐数4的整数倍,此时此刻占了8个字节。short的对齐数是2个字节,8恰好是2的整数倍,所以short紧跟在int后面占2个字节,此时占用10个字节,但10并不是最大对齐数4(默认对齐数和int的对齐数取较小值)的整数倍,所以还要再浪费2个空白字节,最终结构体占用12个字节的大小。

总结

结构体提供了再相同的数据对象中存储多个不同类型数据项的方法。可以创建一个具体的结构模板,并声明相应的变量。通过.运算符和->运算符可以访问结构中的各个成员。它使得我们在处理问题时有更佳灵活的方式去解决。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。