【链表2】如何链接两个孤单的结构体变量

文 / Edward


上一小节里面介绍了结构体指针,貌似结构体指针除了引用麻烦一点之外,和结构体变量相比就没有什么特别了。那么结构体指针究竟有什么作用呢?首先我们需要知道的就是,结构体指针是可以作为一个结构体类型的内部成员变量的。假设我们有一个student_t结构类型,其内部是可以包含一个用其本身定义的一个结构体变量的。如图1所示。
图1在定义结构体时,加入一个其自身类型的结构体指针
如图1所示,我们在使用typedef定义结构体存储类型的时候,可以将结构体的标签选项保留下来。这个标签在定义指向这种类型的结构体指针的时候,可以和struct联合起来定义。
好了,我们现在已经定义好了一个student_t类型的结构体了,这个结构体有一个最显著的特点,就是它的成员变量里面包含了一个可以指向它自己(student_t)类型的结构体指针。
这里就有个假设了。假设小明和小丽是一个班上的学生,我们可以分别定义两个结构体变量用来存放他们的名字和年龄,如图2所示。
图2 打印小明和小丽的信息
现在我们可以再想一下,如果我们要建立起来一个关系,即坐在小明后面的那个同学,她的名字叫做小丽,换句话说,就是能否找到一种关系,将小丽的信息通过小明这个同学去找到。答案是可以的,我们看到,用来描述小明的结构体里面还包含了一个结构体指针*next,由于用于描述小明和小丽的结构体类型是完全一致的,因此*next指针是可以指向小丽结构体的。如图3所示。
图3 next结构体指针指向另一个结构体变量
而这个指针的指向操作,我们可以使用代码来实现,只需要将XiaoLi结构体的首地址赋值给Xiaoming.next即可。这样操作之后,Xiaoming的next指针就指向了XiaoLi了,此时我们可以很简单地通过小明去查询到XiaoLi的相关信息。这里需要注意的是,Xiaoming.next是一个结构体指针,因此在使用Xiaoming结构体查询XiaoLi的信息时,需要使用Xiaoming.next的指向操作,即Xiaoming.next->name,和Xiaoming.next->age。具体代码如图4所示。
图4 利用next指针打印后一个结构体变量的信息
现在我们再将这些信息扩大一些,假设Xiaoming和XiaoLi这个小组里面又加入了两个小伙伴,分别叫做MaLi和JieKe。那我们也可以使用同样的方式将MaLi和JieKe的信息存储下来,并且使用next指针将他们的信息一个一个地“串联起来”。如图5所示。
图5 利用小明打印出所有学生的信息
上述的printf函数在写起程序来还是比较麻烦的,我们需要为这四个同学写出四个不同的printf函数,如果学生的数量到了100个,还要写100个printf?那么有没有办法只写出一个printf,就能将整个这种连接到一起的结构体的信息都打印出来呢?答案又是肯定的,我们再来反观一下现在这几个结构体的关系。如图6所示。
图6四个结构体之间的关系
如果要可以满足只用一句printf就可以将这四个或者以后的多个结构体的信息全部打印出来,我们联想到学习数组的时候,有一种被称为数组遍历的操作与之类似。我们仔细观察这几个结构体,我们很容易找到一个判断条件,最后一个结构体的next指针势必会指向NULL。因此利用这一点,我们可以定义一个student_t的结构体指针seek,先指向第一个结构体变量,输出完成后,指向第二个结构体变量,即将第一个的next指针赋给这个seek指针,以此类推。当最后一个next赋给seek指针的时候,seek指针的值势必为NULL,因此可以退出整个循环。具体代码如图7所示。
图7 seek指针变量这四个结构体变量
好了,到此为止,如果你能够完全理解以上的代码,那么恭喜你已经弄明白C语言中的链表了。上述的操作就是C语言里面的链表操作,只不过我用来当链表节点的结构体变量是利用auto类型的变量定义出来的,因此其最终会存放在栈区,而真正意义上的C语言链表其是可以动态创建和销毁的,在创建节点之前先要去申请一块堆上面的动态存储区,删除节点的时候需要将这一块内存区域回收。但是不管怎么样,能理解以上内容,说明你对于链表的认识已经入门了。
(0)

相关推荐