本篇文章需要基于读者对于顺序表能理解掌握,如果对顺序表还有些许不懂,可以先看以下链接的文章:https://blog.csdn.net/xpcxpt/article/details/147466492?spm=1001.2014.3001.5501
目录:
一、通讯录的介绍
二、实现通讯录
1.准备阶段
2.通讯录的初始化
3.通讯录的销毁
4.实现通讯录的增加联系人
5.实现通讯录的删除联系人
6.展示通讯录里联系人的信息
7.实现通讯录修改联系人信息
8.查找通讯录的联系人
9.编写目录
三、代码
一、通讯录的介绍
我们想要实现通讯录,是要基于顺序表的,我们学会了对顺序表的增删查改等,而对于通讯录,我们也是需要增删查改,所以我们可以以顺序表为基础,来实现通讯录。
首先我们可以了解到,在顺序表中,我们定义了一个结构体,里面分别有数据,顺序表中有效的数据个数和顺序表容量空间的大小。

我们利用 SLdata 表示数据的类型,那如果我们要实现通讯录,一个通讯录包含很多信息,联系人的姓名,年龄,电话号码等等,所以我们可以定义一个结构体来包含他们,那显然易见,我们的SLdata,也就是数据类型将是结构体。
我们假定我们需要的联系人信息是姓名,性别,年龄,电话和家庭住址。我们还需要在顺序表文件的基础上,创建一个contact.h的头文件和一个contact.c的源文件。
二、实现通讯录
1.准备阶段
首先我们按照思路:先来创建一个结构体,将联系人信息包含在里面

这里除了年龄是数字用int类型,其他的都可以用char类型来包含,这里数组里面都用NAME_MAX这类的来表达,这样子如果数据太大,数组包含不下可以方便修改,那我们就要用#define来定义最大值,除了地址,我对于其他几个,给点都是29,地址给的是100。

我们要使用这个结构体,那我们给他改一下方便的名字,叫作PI,如下:

以上都是在contact.h的头文件里面完成的,那我们创建的这个结构体只是通讯录中的数据,我们要让顺序表知道这个的存在,所以我们需要再seq.h中包含contact.h的头文件,接着我们也需要将seq.h改成PI:

但是我们也需要让contach.h这个文件知道有struct seqlist的存在,但是我们又不能再在contact.h里面声明seq.h的头文件,因为我们已经在seq.h的文件里面声明了contact.h的头文件了,那这里就要使用一个方法,叫前置声明!我们也给顺序表改了个名字,叫Contach(通讯录 )
![]()
到此为止,还差最后一步,就是对seq.c的文件要有一些修改,我们在seq.c的文件里面,定义了查找函数:

这些都要注释掉,因为这里我们利用的是找下标,但是现在已经不是单纯的类型了,现在是我们呢自定义的结构体类型,所以不能这样子使用!
另外,打印函数也要注释掉:

这里同样,以前是基于int类型的,所以在通讯录里面不适用!
contact.c的文件记得包含头文件:

准备阶段完毕,进入通讯录的编写
2.通讯录的初始化
有了前置的准备,其实下面的内容都很简单,首先要初始化通讯录,那不就是初始化顺序表吗,所以代码如下:

3.通讯录的销毁
销毁也是一样,其实就是在通讯录的代码里面套壳顺序表:

4.实现通讯录的增加联系人
我们要添加联系人,我们就要给出提示,然后根据提示输入联系人的姓名、年龄等等,那我们一开始已经把所有信息定义在结构体PI里面了,所以直接调用就可以了:

这里一定要注意不同于其他的年龄,它是int类型
运行出来如下:

5.实现通讯录的删除联系人
在删除联系人前,我们要先确定删除的是哪个联系人,我们假定输入联系人姓名就可以删除联系人的信息,那我们需要定义一个前置函数,用来找到删除的是哪一个联系人:

接着,我们来完成删除联系人:

6.展示通讯录里联系人的信息
展示数据其实很简单,只需要遍历通讯录里面每一个联系人,然后打印出来就好了:
注意age要用%d

可以随便输入信息看一下效果:

7.实现通讯录修改联系人信息
修改联系人信息的思路和前面一样,首先要输入修改的姓名,然后利用姓名找到要修改联系人的信息,然后进行修改:


8.查找通讯录的联系人
查找的原理也是一样的,利用前置函数找到联系人姓名,然后打印联系人的所有信息:

9.编写目录
编写一个目录,方便用户查看:
首先编写一个目录,1.增加联系人 2.删除联系人 3.修改联系人 4.查找联系人 5.展示联系人 0.退出

接着我们利用dowhile循环进行输入,在利用switch语句选择要进行的操作:



三、代码
下面是全部的代码:
seq.c:
#include "seq.h"
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
void SLDestroy(SL* ps)
{
if (ps->arr)
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
void checkcapacity(SL *ps)
{
if (ps->capacity == ps->size)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
SLdata* tmp = (SLdata*)realloc(ps->arr, newcapacity * sizeof(SLdata));
if (tmp == NULL)
{
perror("realloc fail!");
exit(1);
}
else
{
ps->arr = tmp;
ps->capacity = newcapacity;
}
}
}
void SLPushBack(SL* ps, SLdata x)
{
assert(ps);
checkcapacity(ps);
ps->arr[ps->size++] = x;
}
void SLPushFront(SL* ps, SLdata x)
{
assert(ps);
checkcapacity(ps);
for (int i=ps->size;i>0;i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[0] = x;
ps->size++;
}
//void SLprint(SL s)
//{
// for (int i = 0;i < s.size;i++)
// {
// printf("%d ", s.arr[i]);
// }
// printf("\n");
//}
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps->size);
ps->size--;
}
void SLPopFront(SL* ps)
{
assert(ps);
assert(ps->size);
for (int i = 0;i < ps->size - 1;i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
void SLInsert(SL* ps, int pos, SLdata x)
{
assert(ps);
//检测顺序表
assert(pos >= 0 && pos <= ps->size);
//确保pos的值在顺序表所限定的元素以内
for (int i = ps->size;i > pos ; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
//顺序表从后往前,一直到pos位置,将pos位置及以后的数据往后移动一位
ps->arr[pos] = x;
ps->size++;
//记得增加了一个元素,size要++
}
void SLErase(SL* ps, int pos)
{
assert(ps);
//检测顺序表
assert(pos >= 0 && pos <= ps->size);
//确保pos的值在顺序表所限定的元素以内
for (int i = pos;i < ps->size - 1;i++)
{
ps->arr[i] = ps->arr[i + 1];
}
//从pos开始,直接让pos以后的元素往前移动一位,直接覆盖了pos,实现了删除
ps->size--;
//减少了一个元素,记得size要--
}
//int SLFind(SL* ps, SLdata x)
//{
// assert(ps);
// //检测顺序表
// for (int i = 0;i < ps->size;i++)
// {
// if (ps->arr[i] == x)
// {
// return i;
// }
// }
// //遍历顺序表,如果有就返回元素下标,没有就返回-1
// return -1;
//}
seq.h:
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include "contact.h"
//typedef int SLdata;
typedef PI SLdata;
typedef struct seqlist
{
SLdata* arr;
int size;
int capacity;
}SL;
void SLInit(SL * ps);
void SLDestroy(SL* ps);
void SLPushBack(SL* ps, SLdata x);
void SLPushFront(SL* ps, SLdata x);
void SLprint(SL s);
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLInsert(SL* ps, int pos, SLdata x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLdata x);
contact.h:
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}PI;
//前置声明
typedef struct seqlist Contact;//前置声明struct Seqlist
void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);
contact.c:
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 100
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}PI;
//前置声明
typedef struct seqlist Contact;//前置声明struct Seqlist
void ContactInit(Contact* con);
void ContactDestroy(Contact* con);
void ContactAdd(Contact* con);
void ContactDel(Contact* con);
void ContactModify(Contact* con);
void ContactFind(Contact* con);
void ContactShow(Contact* con);
test.c:
#include "seq.h"
//void test01()
//{
// SL s1;
// SLInit(&s1);
// SLPushBack(&s1, 1);
// SLPushBack(&s1, 2);
// SLPushBack(&s1, 3);
// SLPushBack(&s1, 4);
// SLPushBack(&s1, 5);
// SLprint(s1);
// int find = SLFind(&s1, 4);
// if (find < 0)
// {
// printf("没有找到\n");
// }
// else
// {
// printf("找到了,下标是%d\n", find);
// }
// SLDestroy(&s1);
//}
//void test01()
//{
// Contact con;
// ContactInit(&con);
// ContactAdd(&con);
// ContactShow(&con);
// ContactDestroy(&con);
//}
void menu()
{
printf("************************************\n");
printf("*** 1.增加联系人 ** 2.删除联系人 ***\n");
printf("*** 3.修改联系人 ** 4.查找联系人 ***\n");
printf("*** 5.展示联系人 ** 0.退出 ***\n");
printf("************************************\n");
}
int main()
{
int input = -1;
Contact con;
ContactInit(&con);
do
{
menu();
printf("请选择你的操作:\n");
scanf("%d", &input);
switch (input)
{
case 1:
ContactAdd(&con);
break;
case 2:
ContactDel(&con);
break;
case 3:
ContactModify(&con);
break;
case 4:
ContactFind(&con);
break;
case 5:
ContactShow(&con);
break;
case 0:
printf("退出通讯录!\n");
break;
default:
printf("给出错误,重新选择!\n");
break;
}
} while (input!=0);
ContactDestroy(&con);
return 0;
}

4616

被折叠的 条评论
为什么被折叠?



