赤峰专业的网站建设,python基础教程第三版pdf下载,租电信网站服务器,为什么wordpress有cookie通讯录
由于代码比较长#xff0c;为了增加可读性#xff0c;分成了contact.h#xff0c;contact.c#xff0c;test.c#xff0c;分别用来声明函数或者类型#xff0c;实现函数功能#xff0c;测试代码
contact.h 我们希望通讯录具有增加联系人#xff0c;删除联系人…通讯录
由于代码比较长为了增加可读性分成了contact.hcontact.ctest.c分别用来声明函数或者类型实现函数功能测试代码
contact.h 我们希望通讯录具有增加联系人删除联系人显示联系人找查联系人修改联系人排序的功能联系人的信息具有名字年龄性别电话地址的信息
由于每次对通讯录进行操作都要把data数组和存的联系人的个数sz传过去那干脆把他们两个打包到一个结构体类型struct contact里面
枚举类型是为了增加test.c里面switch语句选项的可读性默认第一个成员也就是EXIT就是0那么我们就可以把switch语句里面的0换成EXIT了。
test.c contact.c 首先把所有data数组的所有内容以及p-sz初始化成0
增加联系人的函数 一次性增加一个联系人的信息 数字表示打印多少位负号表示左对齐\t表示插入一个制表符能够让每一行对齐 在查找联系人删除联系人修改联系人信息的函数中我们都需要先找到某个联系人为了避免写三份类似的代码我们这里使用了一个函数。 查找联系人的函数 修改信息的函数 排序的函数 像这样静态版本的通讯录问题还是比较大的首先就是我们不管存多少个联系人的信息上来都创建了一个100个元素的数组这样对内存的开销就比较大如果我们存的信息少就浪费了内存如果存的太多又要去修改最大容量在我们学习了动态内存开辟之后我们可以对通讯录进行如下修改通讯录刚上来可以存放三个联系人的信息当通讯录满了之后自动扩充两个人的名额。于是我们就可以把data数组改成一个指针为了尽可能少的改动原来的代码我们把这个指针的名字也叫做data。这与原来数组名的含义都是地址现在data是一个people*类型的指针我们可以把使用mallocrealloc函数开辟的内存首地址存到里面去。
那么我们先对以前的contact类型进行以下修改 实际上需要修改的函数只有初始化通讯录的函数和增加联系人的函数。 首先使用malloc开辟一块能存放三个people类型变量的空间并返回首地址存到data里面去。这里申请了空间由于后面要用所以并没有及时释放掉最后关闭通讯录的时候再释放即可。
然后是增加联系人的函数在增加之前我们先要判断一下通讯录是不是已经满了我们使用下面的函数来实现这个功能 由于realloc增容可能会失败因此必须检查在增容完毕之后要应该更改掉当前的最大容量capacity。
然后在添加联系人的函数中调用这个检查容量的函数 由于以上所有动态内存开辟的空间都没有被释放掉因此我们在推出这个通讯录的时候应该及时释放掉在test函数这里调用一个用来释放内存的函数 这个函数也是需要我们自己编写的 这样我们的通讯录就是动态版本的了。
源代码
test.c
#define _CRT_SECURE_NO_WARNINGS
#includecontact.h
void menu() {printf(******1.add*****2.del***********\n);printf(******3.search**4.modify********\n);printf(******5.show****6.sort**********\n);printf(***********0.exit***************\n);
}
void test() {int input 0;//创建通讯录contact con {0};do {menu();printf(请选择功能\n);scanf(%d, input);switch(input) {case ADD: addcontact(con);break;case DEL:delcontact(con);break;case SEARCH:searchcontact(con);break;case MODIFY:modifycontact(con);break;case SHOW:showcontact(con);break;case SORT:sortcontact(con);break;case EXIT:release(con);printf(退出通讯录\n);break;default:printf(输入错误请重新选择\n);}} while (input);
}
int main() {test();return 0;
}
contact.c
#define _CRT_SECURE_NO_WARNINGS
#includecontact.h
//初始化通讯录的函数
void initcontact(contact* p) {p-data (people*)malloc(DEFAULT_NUM *sizeof(people));//刚上来容量是3if (p-data NULL) {perror(initcontact);return;}p-sz 0;p-capacity DEFAULT_NUM;
}
int check_capacity(contact*p) {if (p-capacity DEFAULT_NUM) {//扩大容量people* ptr(people*)realloc(p-data, (DEFAULT_NUM INC) * sizeof(people));//一个变量名为ptr的people*类型指针用来接收调整之后的空间首地址if (ptr NULL) {perror(check_capacity);return 0;}else {p-data ptr;//这个ptr可能是原来的data也可能不是增容成功之后赋给datap-capacity INC;return 1;}}return 1;//压根不需要增容也返回1
}
//添加联系人的函数动态版本
void addcontact(contact* p) {int ret check_capacity(p);if (0 ret) {return;}printf(请输入名字\n);scanf(%s, p-data[p-sz].name);printf(请输入年龄\n);scanf(%d, (p-data[p-sz].age));printf(请输入性别\n);scanf(%s, p-data[p-sz].sex);printf(请输入电话号码\n);scanf(%s, p-data[p-sz].tele);printf(请输入地址\n);scanf(%s, p-data[p-sz].address);p-sz;printf(增加联系人成功\n);
}
//显示联系人的函数
void showcontact(const contact* p) {int i 0;for (i 0; i p-sz; i) {//打印标题printf(%-10s\t,%-4s\t,%-5s\t,%-12s\t,%-30s\n, 名字, 年龄, 性别, 电话, 地址);printf(%-10s\t,%-4d\t,%-5s\t,%-12s\t,%-30s\n,p-data[i].name,p-data[i].age,p-data[i].sex,p-data[i].tele,p-data[i].address);}
}
//通过名字找查联系人的函数
// 由于在delcontactsearchcontactmodifycontact函数中都需要找查
// 为了避免写三份类似的代码我们使用函数来实现找查联系人的功能
int find_by_name(contact* p, char name[]) {//找查联系人int i 0;for (i 0; i p-sz; i) {if (strcmp(p-data[i].name, name) 0) {return i;//找到了返回下标}}return -1;//没有找到返回-1
}
//删除联系人的函数暂时不考虑两个人的名字相同的情况
void delcontact(contact* p) {char name[20] { 0 };printf(请输入要删除的人名字\n);scanf(%s, name);int i 0;int del 0;//记录要删除的人信息在data数组中的下标int flag 0;if (p-sz 0) {printf(通讯录为空无法删除\n);}//找查联系人del find_by_name(p, name);//删除联系人if (del -1) {printf(要删除的人不存在\n);return;}for (i del; i p-sz - 1; i) {p-data[i] p-data[i 1];//循环用后面的元素覆盖前面的元素}p-sz--;//如果要删除最后一个联系人也就是下标为sz-1的那个人的信息//由于刚上来del就是sz-1不会进入循环也就不会覆盖掉最后一个元素//但是sz--了就访问不到最后一个元素了效果上就好像删除了最后一个联系人printf(删除成功\n);
}
//查找某个联系人的函数
void searchcontact(contact* p) {char name[20] { 0 };printf(请输入要查找的人的名字\n);scanf(%s, name);int pos find_by_name(p, name);//返回的就是要找的这个人的信息在data数组中的下标 if (pos -1) {printf(查无此人\n);return;}else {//打印这一个人的信息printf(%-10s\t,%-4s\t,%-5s\t,%-12s\t,%-30s\n, 名字, 年龄, 性别, 电话, 地址);printf(%-10s\t,%-4d\t,%-5s\t,%-12s\t,%-30s\n,p-data[pos].name,p-data[pos].age,p-data[pos].sex,p-data[pos].tele,p-data[pos].address);}
}
//修改信息的函数
void modifycontact(contact* p) {char name[20] { 0 };printf(请输入要修改信息的人的名字\n);scanf(%s, name);int pos find_by_name(p, name);if (pos -1) {printf(查无此人\n);}else {printf(请输入名字\n);scanf(%s, p-data[pos].name);printf(请输入年龄\n);scanf(%d, (p-data[pos].age));printf(请输入性别\n);scanf(%s, p-data[pos].sex);printf(请输入电话号码\n);scanf(%s, p-data[pos].tele);printf(请输入地址\n);scanf(%s, p-data[pos].address);printf(修改联系人信息成功\n);}
}
//qsort需要的比较大小的函数
int cmp_by_name(void* str1,void* str2) {return strcmp(((people*)str1)-name, ((people*)str2)-name);
}
//根据名字对信息排序的函数
void sortcontact(contact* p) {qsort(p-data, p-sz, sizeof(p-data[0]), cmp_by_name);printf(排序成功\n);
}
void release(contact* p) {free(p-data);p-data NULL;//注意是data指向的空间被释放掉不是p指向的空间被释放掉p-capacity 0;p-sz 0;
}
contact.h
#pragma once
//用于各种函数或者类型的声明
#include stdio.h
#include string.h
#include stdlib.h
#define MAX 100 //通讯录能添加的最大人数
#define DEFAULT_NUM 3//刚上来的默认容量是3
#define INC 2//到达最大容量的时候一次性扩充的个数
typedef struct people {char name[20];int age;char sex[5];char tele[12];char address[30];
}people;//创建结构体类型并重命名为people
typedef struct contact {people* data;//一个名为data的指针变量int sz;//用来记录通讯录里面存了几个人的信息了int capacity;//记录当前最大容量
}contact;
//枚举类型增加可读性默认EXIT就是0
enum OPTION {EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT,
};
void initcontact(contact* p);//初始化通讯录的函数把通讯录中内容初始化为0
void addcontact(contact* p);//增加联系人的函数
void showcontact(const contact* p);//显示所有联系人的函数显示并不会修改p指向的内容因此加了const
void delcontact(contact* p);//删除联系人的函数
void searchcontact(contact* p);//找查某个联系人的函数
void modifycontact(contact* p);//修改信息的函数
void sortcontact(contact* p);//根据名字对信息排序的函数
void release(contact* p);//使用完成之后释放动态申请的那些空间的函数