前言
C语言中的结构体作为一大难点,并且对于需要学习数据结构的同学来说,这个结构是每次上课都会遇到的,所以,我们只有更深层次的理解结构体的知识,才能更好的掌握数据结构
结构体用处
结构体到底有什么用?
比如,在STM32的RTC开发中,我们需要数据来表示日期和时间,这些数据通常是年、月、日、时、分、秒。如果我们不用结构体,那么就需要定义6个变量来表示。这样的话程序的数据结构是松散的,我们的数据结构最好是“高内聚,低耦合”的。所以,用一个结构体来表示更好,无论是从程序的可读性还是可移植性还是可维护性皆是:
这个时候,我们就可以定义一个结构体来解决这个问题
定义
struct 结构体名{
结构体所包含的变量或数组
};
或者
struct 结构体名{
结构体所包含的变量或数组
}结构别名;
这两种定义是相等的,区别就在于一个多了一个结构别名
我们还可以使用
typedef struct 结构体名{
结构体所包含的变量或数组
}结构别名;来定义,他们之间的区别,主要在于定义结构变量的书写
如定义一个结构变量 date
使用struct结构定义
struct structname date;
使用typedef struct定义
结构别名 date
使用这种方法我们可以不用写多余的struct,只需写结构别名 date就行,这种方式方便了很多
结构体成员
我们定义了结构体后,我们就可以为其定义成员变量
定义结构体成员变量的方法和定义变量没有什么区别
数据类型 名字
我们为上面的结构体A定义成员变量
调用
关于C语言结构体调用其成员的方法,可以用Java中类的方式来理解,这样会更加的形象
C语言调用成员方法 = 结构别名.a,结构别名.b,结构别名.c
下面写一个C程序调用实例
这是一个简单的用户输入图书信息,最后调用的过程
#pragma warning(disable:4996)
//#define _CRT_SECURE_NO_WARNINGS
和(void)如果你使用vs编译器,需要加上这两个才不会报错,其他编译器我不确定,没怎么使用
结构体嵌套使用
结构体的嵌套使用和函数一样,在一个结构体中使用另外一个结构体,他们之间并没有多大的区别
用一段代码来简单理解
解释:这里定义了两个两个结构体
Date和Book,从里面的代码可以看到
我们在book结构体中调用了Date,这个时候,就可以通过book访问Date结构体重的成员变量了
struct Date dd中dd的意思就是通过结构体struct Date定义一个变量
调用
printf("发售时间: %d-%d-%d\n",book.dd.year, book.dd.moon, book.dd.day);因为他们是嵌套的关系,所以就可以使用一个调用一个的方式进行调用
初始化结构体
先来定义一个结构体
方法一:
struct autonlist *nlists = 0;
直接进行赋值操作
symbol,symbol,nl[0],nl[1],left,left,*right,right会初始化成什么?
先搞清这句话的意思:
struct autonlist *nlists = 0;
等价于:struct autonlist *nlists = NULL;
这句话定义了一个autonlist结构的指针nlists,然后初始化指针为NULL,以防止被后面的语句误用(主要就是防止未对该指针赋值造成的内存错误,野指针操作);
既然这只是对指针的初始化,还使这个指针指向相应的结构变量,当然就不存在对结构的成员进行初始化的操作。
//symbol,nl[0],nl[1],left,*right //这些要自己去显示的初始化,系统默认的都是危险的,一般在用到结构体时要自己去初始化他们
方法二:
初始化结构体指定某一成员可以使用逗号(.) 运算符
比如只初始化autonlist的price成员
struct autonlist tesk = {.price = 34};
我们还可以不按结构体的顺序进行初始化
struct autonlist tesk = {.date = 'chu',
price = 23};
注意:当对多个成员进行初始化时,需要注意格式,其实就是JavaScript对象的书写格式
{
成员一 ,
成员二,
成员三,
成员四
}
最后一个不需要使用逗号
结构体指针
什么是结构体指针?
指向结构体的指针就叫做结构体指针
定义指针
struct Book *po;po = &book;
定义一个指针,使其指向book这个结构体
注意:这里的指针和数组不同,数组是默认地址就是其[0]号位,二结构体不同,所以需要用到“&”运算符
通过结构体指针访问结构体成员有两种方法
1. (*结构体指针).成员名
2. 结构体指针->成员名
问题: 这里的1、为何访问成员需要加括号()?
这是因为运算符等级的关系
逗号(.)运算符等级高于*号运算符
全部代码