1.什么是结构体:可以理解成一个内涵丰富的自定义变量集合,如:可以定义一个变量student,里面包含了int age;int height;int weight;等变量
2.结构体的声明,定义,以及基础使用:
a.声明:结构体名首字母要大写,成员为变量,在语句结束分号前面可以添加属于该类型的变量的变量名。
在此说明:结构体的成员可以为结构体,即结构体的嵌套,如:
b:定义:可以像a描述的方式定义,也可以另起定义,如:struct Date birthday;
c.基础使用:
1.初始化:{ , , };一一对应
2.引用:如修改上图变量a的成员char sex则:a.sex=
3.成员变量的运算:可以赋值,四则,++等
4.输入输出:单位为成员,不可以一次性输入或输出整个结构体
3.结构体数组:必要性:如定义了一个结构体student,但明显的,学生不止一个,要统计多个学生的信息,所以我们需要多个student类型的结构体,就引入了结构体数组,其中结构体student为数组单元类型。以统计学生为例:
a.结构体的定义格式:struct 结构别名 结构名;
结构体数组的定义格式:struct 结构别名 结构体数组名[ ];(见下图第十五行)
b.结构体数组的初始化:类似二维数组,注意下图没有进行初始化是因为数组大小不确定,系统尚确定分配的内存空间
4.结构体指针:
a.结构体指针的定义格式:和指针无异,只是指针类型变成了struct 别名而已,如下图:
b.结构体指针指向结构体单元:利用->,假如p指向结构体,现在要访问该结构体的某一成员,格式为:p->成员名;
c.若指向一个结构体数组?以一维数组为例,赋值数组首地址,即可用指针加减运算访问数组的各个单元,即该数组内不同的结构体
5.链表:带指针的结构体,防止内存的浪费
a.链表的逻辑:先由一个head指针存储第一个结构体的地址,指向第一个结构体
在第一个结构体的成员中包含一个指针(next)存储了下一个结构体的地址,指向下一个结构体,一直到最后一个结构体,指向NULL
在此过程中,我们就用到了结构体指针,不过这次不同在于,指向的成员也是一个指针。新的指针是我们可以访问下一个结构体,一直如此,我们实际上就通过这些是本结构体类型指针的成员,实现了结构体的互通
特别地,我们将这一系列结构体称为链表,每一个结构体都是这个链表的一个结点
我们在下面静态链表里,给出一段代码,具象化这件事
b.静态链表:每一个结点都已经定义,而非临时开辟(malloc(),free())
c.动态链表:每次收到某一信号,就产生一块内存空间,并且用指针的方式将这些空间连接起来,在效果上有点类似于a[n]
我们思考一下:一、像这样一个“a[n]数组”,它得能有地方存值,有地方存放下一位置的地址,那么我们确定了,每一个单元,应该是一个结构体。二、结构体一个个的通过指针串联起来了,那这形成了一个链表。三、不同于静态链表的是,我们每次需要时要再定义这么一个结构体,并且我们并不知道要定义多少个,所以我们要不断地使用malloc与free函数,并且得设置一个条件结束不断的申请
第一次尝试:
好像成功了,只要输入值不等于-1,就可以一直创建结构体,存储输入值,但是,这样一个链表,为了要遍历,要有头有尾,比较合适
第二次改进:
但,我们发现23到27行每次都要从head开始最后定位到上一个结构体,是否有些麻烦耗时?
所以,我们有了第三版,引入了一个temp指针,在每次循环的最后存储上一个结构体的位置
现在,我们就可以以第三版为例,对这样一个链表尝试操作
小结:这里的head,temp都是一个存储过程量的变量,每一次循环,不可避免要进行重新赋值的操作,而这类变量相当于备份,下一次循环修改后,我仍然可以通过取备份中的值,了解到上个循环或者更之前循环的样子(其实第二版程序还有个问题,若第一次输入的就是-1呢?)这个问题在第三版中也得到了改进
链表的函数:
第一种写法:二级指针
错误:21行后面添加:while(num!=-1);
第二种写法:定义一个新的结构,使head成为其成员(结构定义和main函数的改动就不再截图,可以自己尝试)
以下任务使用链表函数的第二种写法,先做一些声明:
输出链表:
链表的查找,清除与结束后内存的释放
备注:b,c都是单向的链表
6.共用体结构:成员占用相同的内存空间
a.占用多大的空间:sizeof()为成员中所占空间最大的字节数
b.格式:union 共用体名{成员列表};
c.用途:在以下情形可以节省空间,我们只需要补充if语句判断person[i].profession即可
也可以联合一个int和一个char a[4]数组,不妨我们认为int占用四个字节,char占用一个字节,那么因为写入int后,这段内存空间,以char的形式看,对于每一个单元,所占据的就是输入int的十六进制数的一个数位。以1234为例,十六进制数为0x4D2,由上,以及小端机器的低位先行机制,可知:char[0]以十六进制数输出为D2,char[1]为04。我们可以利用这种方式,进行位制转换。
7.枚举:一个变量只有有限种可能值,将值具象化成字符串
a.枚举的声明(放在main大括号内):enum 枚举名 {枚举元素列表}
b.枚举变量的定义
c.枚举元素的值:从mon到sun,都是int,且默认第一个值为0,然后顺次增大1。枚举元素不可再赋值,是const,可以对枚举变量做赋值,可以输出。
8.typedef声明:简化结构体前缀
a.结构体别名:其实如果这样简化前缀,第九行Date,也就是原来的变量别名可以不声明
b,指针别名
c.