引入
我们知道,数据的类型可以是系统自带的int float char double
等类型,也可以是我们自己声明的结构体、共用体、枚举类型
等。其实,我们还可以用 typedef 指定新的类型名代替已有的类型名。
替换原有类型
我们用一个新的类型名,替换原有的类型名
1 | typedef int integer; |
声明之后,那么下面的内容等价:
1 | typedef int Bliner; |
方便在自己的程序中使用和方便其他人查看和维护。
高树靡阴,独木不林。
我们知道,数据的类型可以是系统自带的int float char double
等类型,也可以是我们自己声明的结构体、共用体、枚举类型
等。其实,我们还可以用 typedef 指定新的类型名代替已有的类型名。
我们用一个新的类型名,替换原有的类型名
1 | typedef int integer; |
声明之后,那么下面的内容等价:
1 | typedef int Bliner; |
方便在自己的程序中使用和方便其他人查看和维护。
如果一个变量,我们只希望它的值在我们指定的值得范围内,例如week,我们只希望值在周一至周日之间,而不是星期八等特殊情况,我们就需要枚举类型。
如果一个变量,只有可能是几种类型的值,就可以定义为枚举类型
。枚举就是把可能的值都列举出来,变量的值,只能在列举的这个值的范围内。
一般形式
enum 枚举类型名 {枚举元素列表}
我们来定义一个 weekday 变量类型
1 | enum Weekday {sun , mon , tue , web , tuhe , fri , sat}; |
上节,我们学习了共用体,即所有成员的起始内存地址相同。共用体和结构体的定义方法差不多,我们说结构体和共用体最大的区别就是共用体的占用内存长度是成员中占用内存最长的,而结构体则是成员占用内存长度之和。
共用体和结构体有很多却别,那么这些区别造就了结构体和共用体各自什么样的特点呢?
共用体是使用同一段内存存放不同类型的成员,但每一瞬间只能存放一个成员,不能同时存放几个
。因为在每一个瞬间,存储单元只能有唯一的内容。
1 | union Data{ |
如果想在一段内存单元,存放不同类型的变量,如
整型
字符型
实型变量
存放在同一个地址开始的内存单元。
该怎么办?
这时,就需要共用体类型,整型、字符型、实型变量所占用的字节数是不同
的,如果要在同一个内存地址开始,势必意味着后一个数据要覆盖前一个数据。
我们称这种使几个不同的变量共享同一段内存的结构,为共用体
类型的结构。
共用体也可以顾名思义,共用一段内存开始地址的共用体
一般形式
union 共用体名
{
成员表列
} 变量表列; (注意有分号)
如:
1 | union Data{ |
一句话,输出动态链表,就是输出链表中的各个节点。
上一节,我们已经大概知道了,如何使用头指针输出第一个结点,那么该如何输出其它结点呢?我们来写一个输出链表的函数 print。
1 | #include <stdio.h> |
上一节,我们讲了如何建立一个静态链表,今天我们就来说说如何建立一个动态链表。还记得他们的区别吗?
静态链表
所有结点都是手动创建的,不是程序创建的。
不能随时创建和随时释放。
在程序执行过程中,从无到有地建立
起一个链表,即一个一个地开辟结点和输入各个结点数据,并建立起先后相连的关系
的链表为动态链表
。
建立有3名学生的单向动态链表
1 | #include <stdio.h> |
如果学习过数据结构,就会知道,链表是一种常见的重要的数据结构
。它是动态的进行存储分配的一种结构
。
在前面的学习中,我们知道,用数组存放数据时,必须线定义数组长度,也就是数组中元素的个数。
那么如果我们用来存储班级人数,有的班级100人,有的班级30人,那么为了能放下100人的数据,我们必须设计一个100个元素的数组。显然,这会浪费很多内存
。
链表,就没有这种缺点,它根据需要开辟存储单元。
我们先来看一个链表
头指针
变量。它存放一个地址,该地址指向一个元素。链表中的每一个元素
,称为结点
;上面的图中,head 是头指针,指向第1个元素
第1个元素指向第2个元素,以此类推
直到最后一个元素,该元素不再指向其它元素,它称为表尾
表尾的地址部分存放的地址为:NULL
链表到此结束
前面,我们知道了什么是结构体变量和结构体变量的指针,那么它们能不能在形参中出现,接收主调函数传递过来的值呢?我们现在就一起来看看~
其实,结构体变量和结构体变量的指针,甚至结构体变量的成员都可以作为函数参数来使用。
例如使用 stu[1].name stu[3].num 等结构体变量的成员作为函数参数,进行虚实结合,跟普通变量一样,属于值传递
的方式。
注意: 实参和形参的类型要保持一致。
用结构体变量做实参,也是采用值传递
的方式,结构体变量所占的内存单元的内容全部按顺序传递给形参。所以,形参必须也是相同的结构体类型
。
我们知道,指针就是地址,那么结构体指针呢?其实就是指向结构体变量的起始地址,就是这个结构体变量的指针。相反的,如果吧结构体的起始地址存放在一个指针的,那么这个指针就指向该结构体变量。
指向结构体对象的指针:
即可以指向结构体数组
中的元素;
也可以指向结构体变量
。
1 | struct Student *student_1; |
通过指向结构体变量的指针变量,来输出结构体内各成员的信息
1 | #include <stdio.h> |
前面,我们学习了如何声明一个结构体类型和初始化结构体变量,那么数组能不能设置为结构体类型呢?答案是肯定的,这就是结构体数组
。结构体数组和普通数组的最大区别就是,每个数组元素其实都是一个结构体类型的数据,因为数组是结构体类型。
三个候选人,10张选票,我们设计一个统计选票的程序,输入10个选票的结果,输出统计数量。
1 | #include <stdio.h> |