Start And Stick
通讯录的实现有很多种方式,今天我们将用结构体实现简单的通讯录项目功能。包括通讯录的增、删、查、改等功能。
思路:
此次代码文件分别为:
文件名 用途 sqlist.h 用于函数和结构体的声明 sqlist.c 用于函数的实现 test.c 用于通讯录的测验
建立单个联系人的结构体:
对于单个联系人的数据内容,我们可以根据自己的喜好进行定义,这篇文章中我们将其包括联系人的::姓名、年龄、性别、电话。
struct pereon
{char name[20];int age;char gender[2];char phone[13];
}
每一次利用该结构体时我们为了方便快捷,我们可以对结构体进行重命名:
这两种命名方式相等价,我们可以自由选择。
对于如何节省内存和提高代码机能:
创建单个联系人数据结构体后,我们就可以进行内存申请。但是为了节省内存,我们需要根据存储的联系人的多少进行申请。可是如果每增加一个联系人就重新申请一次内存就会降低代码的机能。
为此我们可以每次申请上一次申请内存空间的2倍。但是这样的话我们要什么时候申请内存空间呢?
为此我们可以在建立一个结构体,使其内部包含联系人的数量和我们我们申请内存空间最大可以储存的联系人的数量。当两者相等时我们就进行内存申请。
进行新的结构体建立:
这里我们利用numbers 表示存储联系人的个数,cp用表示可以储存最大联系人的个数。
到这里我们的准备工作就已经完毕了,接下来进行具体实现通讯录的函数实现。
通讯录的初始:
数据初始化:
//数据初始化
void SLinit(SL* p1)
{p1->a = NULL;p1->cp = p1->numbers = 0;
}
将创建的第一个数据结构的指针传入函数,对a的地址进行滞空,对cp和numbers的数据进行赋值0。这时我们已经有了通讯录的开始,接下来我们加入数据。
数据录入:
在每一次加入数据时我们要对联系人的姓名、年龄、性别、电话进行录入会很麻烦,这时我们可以将联系人的信息录入分装成一个函数:
//数据录入
PE inform()
{printf("请输入数据:");PE inof;printf("请输入name:");scanf("%s", inof.name);printf("请输入age:");scanf("%d", &inof.age);printf("请输入gender:");scanf("%s", inof.gender);printf("请输入phone number:");scanf("%s", inof.phone);return inof;
}
修改数据:
我们结构体通讯录数据的加入,是对WANG*a指向的内存空间的改变,同时对cp和numbers进行改变。也就是我们只需要创建一个SL类型的结构体就可以了,这与我们的链表通讯录有很大差异。
尾部插入数据:
//数据尾部插入
void SLdeposit(SL* p1)
{int mz = p1->cp == 0 ? 2 : 2 * p1->cp;if (p1->cp == p1->numbers) {p1->a = (WANG*)realloc(p1->a, mz * sizeof(WANG));p1->cp = mz;}assert(p1);p1->a[p1->numbers] = inform();p1->numbers++;
}
代码讲解:
这里我们需要注意这里的三目操作符的意思:如果cp的值为0则对mz赋值为2,否则对mz赋值为cp的2倍。
同时当我们的cp和numbers相等时对内存进行申请,之后将cp进行赋值。
在对数据进行录入后,将numbers进行增加。
查询数据:
我们查询数据的方式有很多种,例如联系人的姓名、年龄、电话等....。这里我们用姓名进行查询,在找到联系人后将数据进行打印,并返回联系人所占位置的下标。
int SLfind(SL*p1)
{assert(p1);printf("please write your name:");char name[20];scanf("%s", name);for (int i = 0; i < p1->numbers; i++){int m=strcmp(name, p1->a[i].name);if (m == 0)printf("%s %s %s %s\n", "姓名", "年龄", "性别", "电话");printf("%-s %-d %-s %-s\n",p1->a[i].name,p1->a[i].age,p1->a[i].gender,p1->a[i].phone);return i;}printf("查找失败\n");return -1;
}
代码讲解:
这里我们对名字进行比较时我们要利用字符串比较函数进行字符串比较,当两者相同时表示查找成功。
数据删除:
对数据进行删除,先要查询联系人数据,当存在该联系人数据时进行删除,同时将后面数据进行移动。
//数据删除
void SLdelete(SL* p1)
{assert(p1);int i = SLfind(p1);if(i>=0);{for (int m = i; m < p1->numbers-1; m++){p1->a[m] = p1->a[m + 1];}printf("删除成功\n");p1->numbers--;}if (i == -1) {printf("no people is this name\n");}
}
代码讲解:
这里我们也要注意一下,我们的数据下标和我们的numbers相差一(数组元素下标和元素的位置相差一)。
下期预告
到这里我们通讯录就有了一个基本的模型,下一篇文章我们将讲解通讯录的其它功能,并对其进行完善。