1 #include<stdio.h> 2 #include<stdlib.h>//malloc 3 #include<stdbool.h> 4 #include<string.h> 5 #include<ctype.h> 6 #define SIZE 12 //姓名字符串大小为12个字符,包含空字符 7 #define SEX 6 //性别字符串大小为6个字符,包含空字符 8 typedef struct item{ 9 char name[SIZE]; //创建一个储存姓名的成员 10 char sex[SEX]; //创建一个储存性别的成员 11 int age; //创建一个储存年龄的成员 12 struct item * next; //指向自身的结构的指针用以指向下一个item结构 13 }Item; //利用typdef定义一个Item类型,其结构为item 14 typedef struct node{ 15 Item item; //创建一个Item结构的成员 16 struct node * next; //创建一个指向下一个节点的节点指针 17 }Node; //利用typdef定义一个Node类型,其结构为node 18 typedef Node * List; //定义List为一个指向Node节点的指针类型 19 void InitializeList(List * p){ //接受一个(指向Node节点的指针)的指针 20 *p=NULL; //将指向Node节点的指针设为空(*号解引用指向Node节点的指针的指针得到Node节点的指针) 21 } 22 bool IsListEmpty(List *p){ //接受一个(指向Node节点的指针)的指针 23 return *p==NULL?true:false; //如果Node节点为空返回真否则返回假 24 } 25 void CopyToNode(Item item,Node *p){ //接受一个Item结构参数和一个指向Node节点的指针 26 p->item=item; //Node节点的item成员获得传来的item信息 27 } 28 bool AddItem(Item item,List *p){ //接受一个Item结构参数和一个指(向Node节点的指针)的指针 29 Node * pnew; //声明一个指向Node节点类型的指针pnew 30 Node * scan=*p; //声明一个指向Node节点类型的指针scan,该指针获得传来的节点的指针地址 31 pnew=(Node *)malloc(sizeof(Node)); //为pnew分配空间 32 if(pnew==NULL) //如果分配失败 33 return false; //返回假 34 CopyToNode(item,pnew); //将item结构信息和已分配好空间的pnew作为参数传送以将item作为pnew节点的一部分 35 pnew->next=NULL; //将pnew的下一个节点设为空 36 if(scan==NULL) //如果传来的Node节点为空(代表尚无信息录入)) 37 *p=pnew; //则该Node节点获得pnew这个已获取信息的Node节点的地址 38 else{ //如果传来的Node节点不为空 39 while(scan->next!=NULL) //当传来的Node节点的next指针指向不为空时 40 scan=scan->next; //该节点等于下一个节点 41 //循环结束得到一个节点的下一个节点为空 42 scan->next=pnew; //节点的下一个节点获得pnew这个节点的地址以形成链接 43 } 44 return true; //返回真 45 } 46 void ShowItems(Item item){ //接受一个Item结构类型 47 printf("姓名:%s 性别:%s 年龄:%d\n",item.name,item.sex,item.age); //打印该结构的成员信息 48 } 49 void whi1e(const List *pt,void (*p) (Item item)){ //接受一个(指向Node节点的指针)的指针和一个函数指针(该函数指针,接受一个Item结构参数,其返回值为空) 50 Node * look=*pt; //创建一个指向Node节点的指针,该指针获得解析的来的指向(Node结构的指针的指针)的地址,即节点的指针 51 while(look!=NULL){ //当Node节点指针不为空时 52 p(look->item); //调用传来的函数即ShowItems,将当前Node节点的item成员作为参数传送过去以打印 53 look=look->next; //节点指向下一个节点以打印下一个节点的信息 54 } 55 } 56 void DeList(List *p){ //接受一个指向(Node节点的指针)的指针以删除储存节点信息的列表 57 List * replace=p; //创建一个指向(Node节点的指针)的指针repalce来获得传来的指针p 58 while(replace!=NULL){ //如果该指向(Node节点的指针)的指针不为空 59 free(*replace); //释放该指针指向的节点空间 60 (*p)=(*p)->next; //传来的指针p指向的节点等于下一个节点 61 *replace=*p; //replace指向的节点等于p指针指向的节点 62 } 63 } 64 unsigned int ListCounter(const List *p){ //接受一个只读类型的(指向Node节点的指针)的指针 65 Node * example = *p; //创建一个指向Node节点的指针来获取传来的p指针指向的节点 66 unsigned int counter=0; //计数器置0 67 while(example!=NULL){ //当这个节点不为空 68 counter++; //计数器+1 69 example=example->next; //该节点等于下一个节点 70 } 71 return counter; //返回结果 72 } 73 bool DeNode(List *p,char *pt){ //接受一个(指向Node节点的指针)的指针p和一个字符串pt以删除指定姓名的信息 74 Node * front=NULL; //创建一个指向Node节点结构类型的指针front,初始化为空,该指针用以指向rear这个节点的上一个节点来进行删除节点后的连接工作 75 Node * rear=*p; //创建一个指向Node节点结构类型的指针rear并获得传来的节点 76 while(rear!=NULL){ //当节点不为空时进行循环 77 if(strcmp(rear->item.name,pt)==0){ //如果找到姓名相同的 78 if(front==NULL){ //如果这个节点是第一个节点时 79 free(rear); //释放该节点 80 *p=(*p)->next; //该指针指向的节点等于下一个节点 81 return true; //返回真 82 } 83 else{ //当找到的不是第一个节点时 84 front->next=rear->next; //上一个节点的next指向已找到的当前节点的下一个节点 85 free(rear); //释放当前节点 86 return true; //返回真 87 } 88 } 89 else //没找到时 90 front=rear; //front等于当前节点 91 rear=rear->next; //rear等于当前节点的下一个节点 92 } 93 return false; //返回假 94 } 95 void menu(void){ //打印菜单 96 printf("a:添加信息\n"); 97 printf("d:删除信息\n"); 98 printf("p:打印信息\n"); 99 printf("q:退出并清空列表\n"); 100 } 101 void main(){ 102 Item item; //创建一个item结构以获取输入并作为数据传送 103 List info; //创建一个指向Node类型的指针,Node类型包含一个item结构成员和一个指向下一个节点的指针 104 char ch=‘y‘; //初始化ch 105 char name[SIZE]; //获取要删除的姓名 106 InitializeList(&info); //将指向Node的指针的地址作为参数传送(因该函数要求接受一个指向Node的指针的指针,而info为一个指向Node节点的指针,该函数的指针通过*号解引用便获得了该指针指向的Node节点) 107 menu(); //打印菜单 108 while(ch!=‘q‘){ 109 switch (tolower(ch)) { //将字母小写 110 case ‘a‘:{ 111 printf("请输入你的姓名:"); 112 scanf("%s",item.name); //获取信息以存储到item结构的成员中 113 printf("请输入你的性别:"); 114 scanf("%s",item.sex); //获取信息以存储到item结构的成员中 115 printf("请输入你的年龄:"); 116 scanf("%d",&item.age); //获取信息以存储到item结构的成员中 117 AddItem(item,&info); //将item和指向节点的指针的地址作为参数传送以形成连接 118 menu(); //打印菜单 119 break; 120 } 121 case ‘d‘:{ 122 printf("你想删除哪个人的信息(键入此人姓名):"); 123 scanf("%s",name); 124 printf("%s",DeNode(&info,name)?"删除成功\n":"删除失败\n"); //如果返回为真则删除成功,否则失败 125 menu(); //打印菜单 126 break; 127 } 128 case ‘p‘:{ 129 printf("共有%d条信息\n",ListCounter(&info)); //将指向节点的指针的地址作为参数传送,该函数接受一个(指向Node节点的指针)的指针,该指针指向节点的指针的地址,通过*号解引用获得对应的节点信息 130 whi1e(&info,ShowItems); //将指向节点的指针的地址作为参数传送,同时将一个函数作为参数传送 131 menu(); //打印菜单 132 break; 133 } 134 } 135 setbuf(stdin,NULL); //将标准输入的文件指针指向的缓冲区设为空 136 ch=getchar(); 137 setbuf(stdin,NULL); //将标准输入的文件指针指向的缓冲区设为空 138 } 139 DeList(&info); //删除列表 140 printf("再见!\n"); 141 }
如果大家遇到疑问欢迎指出,我将在收到的第一时间予以回复。
原文:https://www.cnblogs.com/Let-us-Coding/p/12881996.html