目录
前言
该部分是对结构体这一重要知识点的巩固。需要实现基本的增删改查的任务。
1.设计思路
我们知道通讯录需要记录联系人信息,并且还要支持对该通讯录的增删改查。
首先,我们如何对 “ 联系人 ” 这个概念进行抽象。当然是使用我们的自定义类型,也就是使用结构体。 同理,通讯录这个概念也是由多个联系人构成,再加上序号。我们同样可以使用结构体来表示这个通讯录。
而具体的内容就是对结构体的展示,以及操作部分。
2.主要步骤
2.0 使用结构体描述该通讯录
见代码:
//通过这个结构体来表示一个联系人的情况
typedef struct PersonInfo{
char name[1024];
char phone[1024];
} PersonInfo ;
//通过这个结构体来描述通讯录(size是当前通讯录的人数)
typedef struct addressBook{
PersonInfo persons[1024];
int size;
}addressBook;
//定义一个全局结构体变量来表示这个通讯录
addressBook addressbook;
2.1 初始化通讯录
初始化通讯录只需要将现有的联系人个数设置为0就行。
void init(addressBook* addressbook){
//将size设置为零,其实不用管pensons在内存中的结果
addressbook->size= 0;
//反正闲着也是闲着,就用memeset顺便将peresons也初始化为0
memset(addressbook->persons,0,sizeof(addressbook->persons));
}
2.2实现交互菜单
所谓交互菜单,就是接受用户的输入然后完成指定的操作。具体实现方法如下。为了完成交互,我们使用转移表,具体的实现见总体实现。
int menu(){
printf("欢迎使用通讯录!\n");
printf("按0退出!\n");
printf("按1新增联系人!\n");
printf("按2删除联系人!\n");
printf("按3查找联系人!\n");
printf("按4修改联系人!\n");
printf("请输入您的选项:\n");
int choice=0;
scanf("%d",&choice);
return choice;
}
2.3 新增联系人
新增联系人也就是给联系人结构体中添加数据。代码如下:
void insert(addressBook* addressbook){
printf("按1新增联系人!\n");
assert(addressbook!=NULL);
printf("新增联系人!");
PersonInfo person={0};
//将联系人的信息输入到联系人结构体中
printf("请输入联系人的姓名!");
scanf("%s",person.name);
printf("请输入联系人的电话!");
scanf("%s",person.phone);
//将该结构体输入到通讯录结构体中,同时size++
addressbook->persons[addressbook->size]=person;
(addressbook->size)++;
}
2.4 查看联系人信息
只需要遍历整个通讯录结构体。具体代码如下:
void show(addressBook* addressbook){
//printf("按3查看联系人!\n");
assert(addressbook!=NULL);
for(int i=0;i<addressbook->size;i++){
//此处用指针更好
PersonInfo* p=&addressbook->persons[i];
printf("[%d]\t\t姓名:%s\t\t电话:%s\n",addressbook->size,p->name,p->phone);
}
printf("查看完毕!共有%d个联系人\n",addressbook->size);
}
2.5删除联系人
删除联系人也就是让用户输入一个序号,然后删除该序号对应的数据。具体实现如下:
(我们如果删除的不是末尾元素,可以将末尾元素移到待删除位置,然后删除末尾元素,注意这种情况只针对序号不重要的例子)
void dropout(addressBook* addressbook){
//printf("按2删除联系人!\n");
printf("请输入需要删除的联系人序号:");
int id =0;
scanf("%d",&id);
if(id < 0 || id >= addressbook->size){
//用户输入有误,请重新输入。
printf("用户输入有误,请重新输入!!!\n");
}
//尾删直接size--
if(id==(addressbook->size)-1){
addressbook->size--;
printf("删除成功\n");
return;
}
//其余情况就把尾数据移到要删除的地方再size--
else{
PersonInfo* p=&addressbook->persons[(addressbook->size)-1];
addressbook->persons[id]=*(p);
addressbook->size--;
}
printf("删除成功!!\n");
}
2.6修改联系人信息
不解释,直接看代码:
void update(addressBook* addressbook){
//printf("按4修改联系人!\n");
printf("请输入需要修改的联系人序号:");
int id =0;
scanf("%d",&id);
if(id <= 0 || id > addressbook->size){
//用户输入有误,请重新输入。
printf("用户输入有误,请重新输入!!!\n");
return;
}
PersonInfo* p=&addressbook->persons[id-1];
printf("请输入新的用户名(旧的用户名为%s)\n",p->name);
scanf("%s",p->name);
printf("请输入新的电话号码(旧的号码为%s)\n",p->phone);
scanf("%s",p->phone);
printf("修改成功!!!\n");
}
3.整体实现
不解释,直接看代码;
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <windows.h>
//通过这个结构体来表示一个联系人的情况
typedef struct PersonInfo{
char name[1024];
char phone[1024];
} PersonInfo ;
//通过这个结构体来描述通讯录(size是当前通讯录的人数)
typedef struct addressBook{
PersonInfo persons[1024];
int size;
}addressBook;
//定义一个全局结构体变量来表示这个通讯录
addressBook addressbook;
void init(addressBook* addressbook){
//将size设置为零,其实不用管pensons在内存中的结果
addressbook->size= 0;
//反正闲着也是闲着,就用memeset顺便将peresons也初始化为0
memset(addressbook->persons,0,sizeof(addressbook->persons));
}
void insert(addressBook* addressbook){
//printf("按1新增联系人!\n");
assert(addressbook!=NULL);
if(addressbook->size==1024){
printf("通讯录已满!新增失败!\n");
return;
}
printf("新增联系人!\n");
PersonInfo person={0};
//将联系人的信息输入到联系人结构体中
printf("请输入联系人的姓名!\n");
scanf("%s",person.name);
printf("请输入联系人的电话!\n");
scanf("%s",person.phone);
//将该结构体输入到通讯录结构体中,同时size++
addressbook->persons[addressbook->size]=person;
(addressbook->size)++;
printf("新增联系人完成!\n");
Sleep(1000);
//system("cls");
}
void dropout(addressBook* addressbook){
//printf("按2删除联系人!\n");
printf("请输入需要删除的联系人序号:");
int id =0;
scanf("%d",&id);
if(id <= 0 || id > addressbook->size){
//用户输入有误,请重新输入。
printf("用户输入有误,请重新输入!!!\n");
return;
}
//尾删直接size--
if(id-1==(addressbook->size)-1){
addressbook->size--;
printf("删除成功\n");
return;
}
//其余情况就把尾数据移到要删除的地方再size--
else{
PersonInfo* p=&addressbook->persons[(addressbook->size)-1];
addressbook->persons[id-1]=*(p);
addressbook->size--;
}
printf("删除成功!!\n");
}
void show(addressBook* addressbook){
//printf("按3查看联系人!\n");
assert(addressbook!=NULL);
for(int i=0;i<addressbook->size;i++){
//此处用指针更好
PersonInfo* p=&addressbook->persons[i];
printf("[%d]\t\t姓名:%s\t\t电话:%s\n",i+1,p->name,p->phone);
}
printf("查看完毕!共有%d个联系人\n",addressbook->size);
}
void update(addressBook* addressbook){
//printf("按4修改联系人!\n");
printf("请输入需要修改的联系人序号:");
int id =0;
scanf("%d",&id);
if(id <= 0 || id > addressbook->size){
//用户输入有误,请重新输入。
printf("用户输入有误,请重新输入!!!\n");
return;
}
PersonInfo* p=&addressbook->persons[id-1];
printf("请输入新的用户名(旧的用户名为%s)\n",p->name);
scanf("%s",p->name);
printf("请输入新的电话号码(旧的号码为%s)\n",p->phone);
scanf("%s",p->phone);
printf("修改成功!!!\n");
}
typedef void(*Func)(addressBook*) ;
int menu(){
printf("欢迎使用通讯录!\n");
printf("按0退出!\n");
printf("按1新增联系人!\n");
printf("按2删除联系人!\n");
printf("按3查看联系人!\n");
printf("按4修改联系人!\n");
printf("请输入您的选项:\n");
int choice=0;
scanf("%d",&choice);
return choice;
}
int main()
{
//使用指针的方式来初始化。
init(&addressbook);
Func funcs[]={
NULL, //这个NULL用来占位,使输入和函数指针对齐
insert,
dropout,
show,
update
};
//接下来就需要和用户交互
while(1){
int choice=menu();
if(choice<0||choice >= sizeof (funcs)/sizeof (funcs[0])){
printf("您的输入有误请重新输入\n");
continue;
}
if(choice==0){
printf("goodbye!!!按enter退出!\n");
break;
}
funcs[choice](&addressbook);
system("pause");
system("cls");
}
return 0;
}
4.总结
该部分,用于对结构体的知识回顾。