任务和代码:
利用链表存储数据,写一个通信录程序,能够记录多个联系人的编号、姓名、性别、联系电话、地址,完成数据的录入、添加、删除、修改以及查询功能。
head.h
#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
/*结点数据域中存放另一个结构体记录某个客户的具体信息*/
typedef struct{ //定义(名单上具体信息)结构体
char num[5]; //编号
char name[9]; //姓名
char sex[3]; //性别
char phone[13]; //电话
char addr[31]; //地址
}Client;
typedef struct node{ //定义结点
Client data; //结点数据域
struct node *next; //结点指针域
}Node;
Node *head,*p;
char str[20];
int menu_select();
Node *InsertNode(Node*,Node*);
Node *ListFind(char str[]);
Node *DelNode(char str[]);
void PrintList();
#endif // HEAD_H_INCLUDED
main.c
#include <stdio.h>
#include <malloc.h>
#include "head.h"
#define R 0
int main(){
for(;;){
switch(menu_select()){
case 1:
printf("\n");
printf("* 通讯录链表的建立 *\n");
printf("\n");
int n;
printf("建立n个客户的通讯录:n = ");
scanf("%d",&n);
head=NULL;
while(n--){
p=(Node*)malloc(sizeof(Node));
scanf("%s%s%s%s%s",p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
head=InsertNode(head,p);
}
break;
case 2:
printf("\n");
printf("* 通讯者信息的添加 *\n");
printf("*编号 姓名 性别 电话 地址 *\n");
printf("\n");
Node *p=(Node *)malloc(sizeof(Node));
scanf("%s%s%s%s%s",p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
head=InsertNode(head,p); //插入指向结构体的指针
break;
case 3:
printf("\n");
printf("* 通讯录信息的查询 *\n");
printf("\n");
scanf("%s",str);
p=ListFind(str);
if(p!=NULL){
printf("*编号 姓名 性别 联系电话 地址 *\n");
printf("----------------------------------------\n");
printf("%s\t%s\t%s\t%s\t%s\n",p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
printf("----------------------------------------\n");
}
else
printf("没有查到要查询的通读者!\n");
break;
case 4:
printf("\n");
printf("* 通讯录信息的删除 *\n");
printf("\n");
scanf("%s",str);
head=DelNode(str);
break;
case 5:
printf("\n");
printf("* 通讯录链表的输出 *\n");
printf("\n");
printf("*编 号 姓 名 性 别 联系电话 地 址 *\n");
printf("----------------------------------------\n");
PrintList(head);
printf("----------------------------------------\n");
break;
case 0:
printf("\t 再 见! \n");
return 0;
}
}
}
menu_select.c
#include <stdio.h>
int menu_select(){
int sn;
printf("==============================\n");
printf(" 通讯录管理系统\n");
printf("==============================\n");
printf(" 1.通讯录链表的建立\n");
printf(" 2.通讯者结点的插入\n");
printf(" 3.通讯者结点的查询\n");
printf(" 4.通讯者结点的删除\n");
printf(" 5.通讯录链表的输出\n");
printf(" 0.退出管理系统\n");
printf("==============================\n");
for(;;){
scanf(" %d",&sn);
if(sn<0||sn>5)
printf("\n\t输入错误,重选0-5");
else
break;
}
return sn;
}
InsertNode.c
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "head.h"
Node *InsertNode(Node *h,Node *p){
Node *q1=h,*q2;
if(h==NULL){
h=p;
p->next=NULL;
}
else if(strcmp(p->data.num,h->data.num)<0){
h=p;
p->next=q1;
}
else{
while(q1!=NULL&&strcmp(q1->data.num,p->data.num)<0){
q2=q1;
q1=q1->next;
}
p->next=q2->next;
q2->next=p;
}
return h;
}
PrintList.c
#include <stdio.h>
#include <malloc.h>
#include "head.h"
void PrintList(Node *h){
Node *p;
p=h;
while(p!=NULL){
printf("%s\t%s\t%s\t%s\t%s\n",p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
p=p->next;
}
printf("\n");
}
ListFind.c
#include <stdio.h>
#include <string.h>
#include "head.h"
Node *ListFind(char str[]){
Node *p=head;
while(p!=NULL){
if(strcmp(p->data.num,str)*strcmp(p->data.name,str)*
strcmp(p->data.phone,str)==0)
break;
p=p->next;
}
return p;
}
DelNode.c
#include <stdio.h>
#include <string.h>
#include "head.h"
Node *DelNode(char str[]){
Node *p,*q;
p=head;
if(head==NULL)
printf("通讯录上无成员,删除失败.\n");
else{
while((strcmp(str,p->data.name)+strcmp(str,p->data.num)+strcmp(str,p->data.phone)!=0)
&&p->next!=NULL){
q=p;
p=p->next;
}
if(strcmp(str,p->data.name)*strcmp(str,p->data.num)
*strcmp(str,p->data.phone)==0){
if(p==head)
head=p->next;
else
q->next=p->next;
free(p);
}
else
printf("通讯录上无该成员,删除失败.\n");
}
return head;
}
运行结果:
改进之处:
当前查找只能实现单个查找,比如可以根据客户的编号,姓名,联系电话查找到客户,
但如果查找同个地址的多个客户或查找所有男客户,都实现不了。
同样,删除也只支持单个删除。
知识点总结:
1)结点中的数据域是另一个结构体
定义指向结点的指针后,如何调用数据域中的具体信息
2)将指向结构体的指针作为函数参数
3)字符串作为字符数组在函数中的调用和定义
4)利用条件编译逐步调试
心得:
所有功能模块的实现均是之前所学(选择菜单、插入、新建、查找、删除),"利用积木搭房子" ^_^