基础知识:
1 malloc 分配的对象生命周期是allocated类型,不同于常规的局部变量
2 指针p指向某个对象obj, 则*p就是obj的别名,引用.
3 如果要函数f 调用函数g,并且在函数g中改变函数f中的局部变量obj, 应该使用如下形式 g(&obj)
4 参数类型是指针有时是为了读取对象,而不是修改对象,这时候可以使用关键字const
5 外部变量没有3中提到的问题,直接访问即可.
下面以教材例7.8来说明
(一) 不好的例子
教材中的creat虽然可以工作,但是creat的参数head一无所用, 因为只传递一个NULL指针是毫无意义, creat的head和main函数中的全然不相干. 主函数中的head获得链表头是通过return的返回值
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <malloc.h> struct node { /*节点的数据结构*/ int num; char str[20]; struct node *next; }; /* * * * * * * * * * * * * 创建链表函数* * * * * * * * * * * * * * * * */ struct node *creat(struct node *head) { char temp[30]; struct node *p1, *p2; p1 = p2 = (struct node*)malloc(sizeof(struct node)); printf("input num, name: \n") ; printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; while (strlen(p1->str) > 0) { if (head == NULL) head = p1; else p2->next = p1; p2 = p1; p1 = (struct node *)malloc(sizeof(struct node)); printf ("input num, name: \n"); printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; } return head; } /* * * * * * * * * * * * * * 链表输出函数* * * * * * * * * * * * * */ void print (struct node *head) { struct node *temp; temp = head; printf("output strings:\n"); while (temp != NULL) { printf("%d -- %s\n", temp->num, temp->str); temp = temp->next; } return; } /* * * * * * * * * * *主函数 * * * * * * * * * * * * * * * * */ int main(void) { struct node *head; head = NULL; head = creat(head); /*调用函数创建以head 为头的链表*/ print(head);/* 调用函数输出节点 */ return 0; }
程序的运行:
input num, name:
exit:double times Enter!
11
zhang
input num, name:
exit:double times Enter!
13
li
input num, name:
exit:double times Enter!
14
wang
input num, name:
exit:double times Enter!
output strings:
11 -- zhang
13 -- li
14 -- wang
Press any key to continue
(二) 对(一)的合理修改, 注意creat没有参数了
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <malloc.h> struct node { /*节点的数据结构*/ int num; char str[20]; struct node *next; }; /* * * * * * * * * * * * * 创建链表函数* * * * * * * * * * * * * * * * */ struct node *creat(void) { char temp[30]; struct node *p1, *p2, *head = NULL; p1 = p2 = (struct node*)malloc(sizeof(struct node)); printf("input num, name: \n") ; printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; while (strlen(p1->str) > 0) { if (head == NULL) head = p1; else p2->next = p1; p2 = p1; p1 = (struct node *)malloc(sizeof(struct node)); printf ("input num, name: \n"); printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; } return head; } /* * * * * * * * * * * * * * 链表输出函数* * * * * * * * * * * * * */ void print (struct node *head) { struct node *temp; temp = head; printf("output strings:\n"); while (temp != NULL) { printf("%d -- %s\n", temp->num, temp->str); temp = temp->next; } return; } /* * * * * * * * * * *主函数 * * * * * * * * * * * * * * * * */ int main(void) { struct node *head; head = creat(); /*调用函数创建以head 为头的链表*/ print(head);/* 调用函数输出节点 */ return 0; }
(三) 不通过函数返回head, 直接传入修改
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <malloc.h> struct node { /*节点的数据结构*/ int num; char str[20]; struct node *next; }; /* * * * * * * * * * * * * 创建链表函数* * * * * * * * * * * * * * * * */ void creat(struct node **head) { char temp[30]; struct node *p1, *p2; p1 = p2 = (struct node*)malloc(sizeof(struct node)); printf("input num, name: \n") ; printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; while (strlen(p1->str) > 0) { if (*head == NULL) *head = p1; else p2->next = p1; p2 = p1; p1 = (struct node *)malloc(sizeof(struct node)); printf ("input num, name: \n"); printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; } } /* * * * * * * * * * * * * * 链表输出函数* * * * * * * * * * * * * */ void print (struct node *head) { struct node *temp; temp = head; printf("output strings:\n"); while (temp != NULL) { printf("%d -- %s\n", temp->num, temp->str); temp = temp->next; } return; } /* * * * * * * * * * *主函数 * * * * * * * * * * * * * * * * */ int main(void) { struct node *head = NULL; creat(&head);/*调用函数创建以head 为头的链表*/ print(head);/* 调用函数输出节点 */ return 0; }
(四) 使用引用代替指针,明显之处就是不用*head了。
void creat(struct node **head) ==> void creat(struct node * &head)
如果使用typedef struct node * PNODE, 则
void creat(PNODE*head) ==> void creat(PNODE &head) 视觉效果更佳
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <malloc.h> struct node { /*节点的数据结构*/ int num; char str[20]; struct node *next; }; /* * * * * * * * * * * * * 创建链表函数* * * * * * * * * * * * * * * * */ void creat(struct node * &head) { char temp[30]; struct node *p1, *p2; p1 = p2 = (struct node*)malloc(sizeof(struct node)); printf("input num, name: \n") ; printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; while (strlen(p1->str) > 0) { if (head == NULL) head = p1; else p2->next = p1; p2 = p1; p1 = (struct node *)malloc(sizeof(struct node)); printf ("input num, name: \n"); printf("exit:double times Enter!\n"); gets(temp); gets(p1->str); p1->num = atoi(temp); p1->next = NULL; } } /* * * * * * * * * * * * * * 链表输出函数* * * * * * * * * * * * * */ void print (struct node *head) { struct node *temp; temp = head; printf("output strings:\n"); while (temp != NULL) { printf("%d -- %s\n", temp->num, temp->str); temp = temp->next; } return; } /* * * * * * * * * * *主函数 * * * * * * * * * * * * * * * * */ int main(void) { struct node *head = NULL; creat(head);/*调用函数创建以head 为头的链表*/ print(head);/* 调用函数输出节点 */ return 0; }