学链表的时候绷不住了,发现结构体和指针都没学好,这两天把 指针 结构体 链表 一定要啃下来,不惜代价。
要理解 * 解引用运算符,和 & 取地址运算符,就要对C的内存有清楚的理解。
简单来说,* 作为解引用运算符就是把一个指针变量的内容展示出来,而作为标志则是说明一个变量的类型是指针;
&的用法与之相反,获取了一个变量的地址;
每个变量都有内存地址,指针存放的就是一个地址,用了 * 就是把这个地址的内容暴露出来。
清楚了以上后,就要了解指针是什么。
指针一般指指针变量,它们存放的是一个地址,对它的修改是对地址的修改,而不是对那个地址内的东西进行修改,加了*就是让所存地址里的东西暴露出来,从而进行修改。
接下来看重要的结构体;
结构体是一种数据结构,由不同数据类型集成。作为这样的数据结构,与一般变量不同的是,
类型与变量是不同的概念,不是混同,只能对变量赋值,存取或运算,而不能对一个类型赋值,存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
在使用时,必须注意结构体类型和结构体变量,变量有地址,类型没有。
而结构体类型的指针变量,所指向的也是结构体变量,而不是这个类型。
学习的时候就对(struct student *)malloc(sizeof(struct student))产生了疑问,现在剖析一下
(struct student *)是强制类型转换,由于malloc的返回类型是空指针,所以需要把它转换为指向结构体类型的指针,意思就是要求所指对象是结构体变量,而上面这个东西是一个右值,赋给的左值要求是结构体类型指针变量的指针名。
sizeof(struct student)则是返回struct student
结构体实例所需的内存大小(以字节为单位)。
菜鸟编程里在开头用宏定义#define LEN sizeof(struct student),是个很好的方法。
接下来就要面对链表了。
这个小小的struct student *next就大有文章可做了。
定义在结构体内,就使得每个结构体变量可以使用;而它自己是结构体型指针变量,则指向下一个节点的指针变量,而该节点的指针变量是结构体类型指针变量,是结构体的实例而非内部数据,再通过这个指针变量指向自己的next,而这个next又会指向下一个指针变量………
通过这样的类似循环的结构,就构成了链表的基本逻辑。把链表比作一个拉力计,指针变量实例就是拉环,next就是钩子,内部的弹簧就是结构体。拉环是独立于弹簧之外的,钩子则是和弹簧一体的。这么说明应该就明白了。
当然实际应用时,有较为复杂的用法,就不能这样简单的认为了。
总结了一下就是,还是得依赖教材,教材讲的还是蛮清楚的,不应该轻视。