这篇代码文适合超级小白我会结合我小白时期的困惑来解说下面的代码,所以我会讲的很详细,如果看完有问题就评论区!一定回答!
1 #include<stdio.h>
2 #include<stdlib.h>//申请空间所需要的库,没有这个会报警告
3 struct stu//首先要知道的是链表全是结构链在一起的,这个结构定义在main外
4 {
5 int id;//id号
6 int score;//分数
7 char name[20];//姓名
8 struct stu *next;//1 这里见下面详细介绍
9 };//在分号前如果有*first,*last诸如这种的表示,其实就是在申明指针,你可以吧前面的整体看成一个类型,*first *last就是指向stu这样结构的一个指针。
10
11 void main()
12 {
13 char flag;//一个控制while是否继续循环的变量
14 int id = 0;//给id赋初值
15 struct stu *head;//链表头创建所需要的指针
16 head = (struct stu *)malloc(sizeof(struct stu));//2 这里见下面详细介绍
17 if(NULL == head)//为了防止没有申请到空间所加的判断函数,比如你申请几兆大小的空间,就有很大可能申请失败,但在这里基本都会成功。
18 {
19 printf("申请失败!\n");
20 return -1;//程序遇到return就直接结束了,这里就是退出的作用
21 }
22 struct stu *link;//这个是起到一个链接作用的指针
23 link = (struct stu *)malloc(sizeof(struct stu));//申请空间
24 if(NULL == link)//和上面的判断作用一样
25 {
26 printf("申请失败!\n");
27 return -1;
28 }
29 struct stu *ptr;//这是一个游走的遍历指针
30 printf("输入学生成绩:\n");
31 scanf("%d",&(head->score));
32 getchar();//防止下面的scanf把回车给“吞”了,那么名字就不能正常输入了
33 printf("输入学生姓名:\n");
34 scanf("%s",head->name);//注意这里没有&,数组其实也是指针,不多细讲了,防止眩晕。给一个等式 name[0]=*(name + 0)
35 ptr = head;//3 这里的意思见下面详解
36 ptr->next = link;//4 这里的意思见下面详解
//35 36也可以直接替换成head->next = link;
37 while(flag != 'N' && flag != 'n')//while循环的条件
38 {
39 ptr = ptr->next;//结合4所说,现在ptr就指向了link所指的空间了
40 printf("输入学生成绩:\n");
41 scanf("%d",&(ptr->score));
42 getchar();
43 printf("输入学生姓名:\n");
44 scanf("%s",ptr->name);
45 link = (struct stu *)malloc(sizeof(struct stu));//注意这里link地址发生了变化,变成了新的空间的地址。
46 ptr->next = link;//刚申请的空间又和前一个链在一起了
47 getchar();
48 printf("是否继续?输入n或N退出\n");
49 ptr->next = NULL;//最后的节点都要赋值一次空,因为每次新申请的节点就是最后一个节点
50 scanf("%c",&flag);
51 }
52 ptr = head;//遍历,head一直没有变 所以ptr就可以知道这个链表的头在哪,千万不能动head,不然就找不到链表的头了!
53 while(ptr->next != NULL)
54 {
55 printf("ID :%d",id);
56 printf("成绩:%d\n",ptr->score);
57 printf("姓名:%s\n",ptr->name);
58 printf("***********************\n");
59 ptr = ptr->next;//读完一个节点,跳到下一个节点
60 id++;
61 }
62 }
1:这里注意一下指针的类型,它是一个指向结构体的指针,需要注意的是这个结构体不是随随便便的结构体,而是长像如stu这样的结构体。另外要说明的是这里的 ‘*’ 这个没有任何运算符的意思,只是如同int char等一样只是表明我这个next是一个指针类型的变量,如int next表明这个next是个整数,前面的struct stu就是这个指针的类型 举个例子:struct stu * next 和 struct goudan * goudan 那么这个goudan就无法指向stu这个结构,它只能指向goudan这个结构。体会一下。
2:这里就是申请空间的一个过程,malloc这个函数会向系统申请一个大小由用户自定义的空间,然后返回一个申请好空间后这个空间的地址,这个地址类型被(struct stu *)强制转换了,sizeof字面上理解就是什么什么的大小,sizeof(struct stu)的意思就是大小为struct stu这样大的空间,那么这个函数连在一起的意思就是,申请一个大小如struct stu结构这么大的空间并返回了(struct stu *)类型的地址给指针head。只有申请后才能进行赋值操作。
3:你一定没有忘记前面给head申请了一段空间吧,那段空间还没有进行赋值,所以要访问这段空间要么用head去访问,要么就用另一个指针去访问,但是这个指针的值得是那段空间的地址,这样才能访问。所以这里 ptr = head,就是把head的值(地址)赋给了ptr,那么ptr就可以访问那段空间了,也就是ptr指针指向了那段空间,切记指针的值一定是地址(要么就是空NULL),就看是谁的地址,谁的地址那么这个指针就指向谁。另外希望你区分ptr = &head和ptr = head 一个是让ptr指向了head 一个是ptr指向了head申请的空间,&head是head自己的地址,head是它申请好空间的地址。
4:ptr->next = link 结合前面的代码,我们已经申请了两段空间,一个是head申请的,一个是link申请的,这两段空间是独立的两者没有任何关系,但是链表就是得把这两个空间连在一起,所以这里就用到了结构体中struct stu *next这个变量,结合3所说,head它代表的是head申请空间的地址,那么这里也好理解,link就是link申请好空间的地址,所以这里的意思就是将link申请空间的地址给了在head申请好的空间中的next,那么在下次ptr访问了next,就可以将其值读出,自然就可以访问到下一个空间了,这就是链的关键了。