【c语言】写了一个简单的通讯录程序

【c语言】写了一个简单的通讯录程序


刚学习完单链表,赶紧写了一个通讯录小程序练练手!光看不练是很难提升的,自己真正动起手来才会发现许多问题。这次练习的过程中忽略了刚进入循环时的条件和逻辑符号的短路求值特性。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024 	//内存池的最大结点数量
void addPerson(struct Person **head);
void getInput(struct Person *person);
void printfPerson(struct Person *person);
void findPerson(struct Person *head);
void changePerson(struct Person **head);
void delPerson(struct Person **head);
void displayContent(struct Person *head);
void releasePool(void);
//为了不产生内存碎片,在程序中加入了内存池管理,用一个链表来存储内存
struct Person *pool = NULL;		
int count; 		//用于记录内存池中结点数量
struct Person
{
		char name[40];
		char phone[44];
		struct Person *next;
};

void getInput(struct Person *person)
{
		printf("请输入联系人姓名:");
		scanf("%s" , &person->name);
		printf("请输入联系人电话:");
		scanf("%s" , &person->phone);
}

void printfPerson(struct Person *person)
{
		printf("联系人姓名:%s\n" , person->name);
		printf("联系人电话:%s\n" , person->phone);
}

void addPerson(struct Person **head)  //这里要修改head指针,所以要传入二级指针(即指向head指针的指针)
{
		struct Person *_new;
		static struct Person *tail; 		//静态变量(全局)指向链表尾部,用于尾插法 
		
		//如果内存池非空,则直接从里面获取空间
		if (pool != NULL)
		{
				_new = pool;
				pool = pool->next;
				count--;	
		} 
		//如果内存池为空,则调用malloc函数申请新的内存空间 
		else
		{
				_new = (struct Person *)malloc(sizeof(struct Person)); 	
				if(_new == NULL)
				{
						printf("内存分配失败!\n");
						exit(1);
				}
		}
		getInput(_new);
		if(*head != NULL)
		{
				tail->next = _new;
				_new->next = NULL;
		}
		else
		{
				*head = _new;
				_new->next = NULL;
		}
		tail = _new;
		printf("录入成功!\n\n");	
}

void findPerson(struct Person *head)
{
		struct Person *person;
		person = head;
		char name[40];
		printf("请输入联系人姓名:");
		scanf("%s" , &name);
		
		while( person != NULL && strcmp(person->name , name) ) 		//注意判断条件的先后顺序!!!若person为NULL,就没有person->name,程序就卡在那无法判断  
		{
				person = person->next;	
		}
		if(person == NULL)
		{
				printf("找不到该联系人!\n\n");
		}
		else
		{
				printfPerson(person);	
				putchar('\n');
		}
			
}

void changePerson(struct Person **head)
{
		char name[40];
		struct Person *person;
		printf("请输入要查找的联系人姓名:");
		scanf("%s" , &name);
		person = *head;
		while( person != NULL && strcmp(person->name , name) )
		{
				person = person->next;
		}
		
		if(person == NULL)
		{
				printf("找不到该联系人!\n\n");
				return;
		}
		else
		{
				printf("请输入新的联系电话:" );
				
				scanf("%s" , &person->phone);
				printf("修改成功!\n\n");
		}
}

void delPerson(struct Person **head)
{
		struct Person *previous;
		struct Person *temp;
		struct Person *person;
		char name[40] ;
		char judge; 
		
		previous = NULL;
		person = *head;
		
		printf("请输入要删除的联系人姓名:");
		scanf("%s" , &name);
		
		while( person != NULL && strcmp(person->name , name) )
		{
				previous = person;
				person = person->next;
		}
		if(person == NULL)
		{
				printf("该联系人不存在!\n\n");
				return;
		}
		else
		{
				getchar(); 		//没加的时候出错 
				printf("确认删除该联系人吗?(Y/N):");
				scanf("%c" , &judge);
				if(judge == 'Y')
				{
						if(previous == NULL)				//这里要注意考虑删除第一个结点的情况,一开始忽略了 
						{
								*head = person->next;
						}
						else
						{
								previous->next = person->next;
								
						}
						printf("删除成功!\n\n");
						//判断内存池有没有空位
						if (count < MAX)
						{
								//用头插法把内存加入内存池 
								if (pool != NULL)
								{
										temp = pool;
										pool = person;
										person->next = temp;
								}
								else
								{
										pool = person;
										person->next = NULL;
								}
								count++;
						} 
						else
						{
								free(person);
						}
						
				}	
		}
}

void displayContent(struct Person *head)
{
		struct Person *person;
		person = head;
		if(person == NULL)
		{
				printf("通讯录为空!\n");
		}
		else
		{
				while(person != NULL)
				{
						printfPerson(person);
						person = person->next;
				}
				putchar('\n');
		}
}


void releaseContacts(struct Person **contacts)
{
		struct Person *temp;
		while(*contacts != NULL)
		{
				temp = *contacts;
				*contacts = (*contacts)->next;
				free(temp);
		}
}

void releasePool(void)
{
		struct Person *temp;
		while(pool != NULL)
		{
				temp = pool;
				pool = pool->next;
				free(temp);
		}
}
int main()
{
		printf("============通讯录程序2.0===========\n\
|---------1.插入新的联系人---------|\n\
|---------2.查找已有联系人---------|\n\
|---------3.更改已有联系人---------|\n\
|---------4.删除已有联系人---------|\n\
|---------5.显示当前通讯录---------|\n\
|---------6.退出通讯录程序---------|\n\
|--------Powered by PencilX--------|\n\n");

		struct Person *head = NULL; 		//链表头指针 
		
		while(1)
		{
				int order;		//指令 
				printf("请输入指令:");
				scanf("%d" , &order);
				
				switch(order)
				{
						case 1 : addPerson(&head);break;
						case 2 : findPerson(head);break;
						case 3 : changePerson(&head);break;
						case 4 : delPerson(&head);break;
						case 5 : displayContent(head);break;
						case 6 : goto END;
						default:{printf("请输入正确的指令!\n");putchar('\n');break;}
				}
		}
END:	
		releaseContacts(&head);
		releasePool();
		return 0;
}

实现效果如下:
运行效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端corner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值