近日学习数据结构的时候发现一些以前没有察觉到的点,就是结构体的指针,当修改到头节点的时候,为什么要用二级指针呢?
A:二级指针才可以修改一级指针本身的值,而不是修改一级指针指向的变量的值
详解
观察如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <stdio.h> struct student{ int num,source; struct student *next; }; struct student a={1,90},b={2,86},c={3,20},d={8,80}; void main(){ struct student *head,*p; head=&a;a.next=&b;b.next=&c;c.next=NULL;d.next=&b; void change1(struct student *head); void change2(struct student **head); void change3(struct student *head); printf("使用函数前数据:\n"); p=head; while(p){ printf("%-5d%-5d\n",p->num,p->source); p=p->next; } change1(head); printf("\n使用函数1后:\n"); p=head; while(p){ printf("%-5d%-5d\n",p->num,p->source); p=p->next; } change2(&head); printf("\n使用函数2后:\n"); p=head; while(p){ printf("%-5d%-5d\n",p->num,p->source); p=p->next; } head=&a;a.next=&b;b.next=&c;c.next=NULL;d.next=&b; printf("恢复数据数据:\n"); p=head; while(p){ printf("%-5d%-5d\n",p->num,p->source); p=p->next; } change3(head); printf("\n使用函数3后:\n"); p=head; while(p){ printf("%-5d%-5d\n",p->num,p->source); p=p->next; } }
void change1(struct student *head){ head=&d; } void change2(struct student **head){ (*head)=&d; } void change3(struct student *head){ *head=d; }
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 使用函数前数据: 1 90 2 86 3 20
使用函数1后: 1 90 2 86 3 20
使用函数2后: 8 80 2 86 3 20 恢复数据数据: 1 90 2 86 3 20
使用函数3后: 8 80 2 86 3 20
|
数据结构:
change1函数
参数:struct student *head
change1(head)
取主函数中head变量存储的值,即head指向的节点的地址(a的地址);所以change1函数中的head接收了a的值(注意:主函数的head与change1函数的head不是同一个),此时新旧head指向的变量相同,但自身不同。
head=&d
将change1函数中的head存储的地址改成d的地址,在change1函数中head指向d,因为没有怼主函数的head进行改动,所以主函数的head还是指向a,所以修改不成功
change2函数
参数:struct student **head
change2(&head) 取主函数中head变量自身的值传给change2函数中的head变量,而*
的作用是进入指针指向的变量,所以*head
即进入了change2函数head指向的变量–>主函数的head,所以此时*head
等价于主函数的head,修改*head
就可以修改主函数的head
(*head)=&d
将*head
改为d的地址等于将主函数的head改为d的地址
change3函数
参数:struct student *head
change3(head)
取主函数中head变量存储的值,即head指向的节点的地址(a的地址)
*head=d
*head
进入head指向的节点,即进入a,将d赋给*head
等价于将d赋给a,此时原来存储a的空间存储的数据与存储d的空间存储的数据一样(有、绕,就是现在没有a,有两个d,因为a变成d),此时主函数的head、change3函数的head都不变,而是将他们指向的变量重新赋值。此语句会改变数据使得数据丢失,最好不要用