实现动态内存分配的通讯录
2016-12-06 13:47
387 查看
实现一个通讯录;
通讯录可以用动态内存分配来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
首先要实现一个动态内存分配的通讯录,我们需要首先需要一个结构体来保存一个联系人的信息包含姓名性别年龄等,然后还需要一个结构体去保存所有联系人的信息,当前联系人的个数,扩大的容量。
二:另一种直接给这个结构体开辟内存则不用在调用时再指向它。
通讯录可以用动态内存分配来存储1000个人的信息,每个人的信息包括:
姓名、性别、年龄、电话、住址
提供方法:
1. 添加联系人信息
2. 删除指定联系人信息
3. 查找指定联系人信息
4. 修改指定联系人信息
5. 显示所有联系人信息
6. 清空所有联系人
7. 以名字排序所有联系人
首先要实现一个动态内存分配的通讯录,我们需要首先需要一个结构体来保存一个联系人的信息包含姓名性别年龄等,然后还需要一个结构体去保存所有联系人的信息,当前联系人的个数,扩大的容量。
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #define MAX_INIT 10 #define MAX_EXPAND 10 #define MAX_END 1000 void meau() { printf(" *******************************************\n"); printf(" *******************************************\n"); printf(" ##############My address book##############\n"); printf(" *1-Add 2-Delete 3-Find *\n"); printf(" *4-Empty 5-Modify 6-Sort *\n"); printf(" *0-Exit 7-Show *\n"); printf(" *******************************************\n"); printf(" *******************************************\n"); } enum Number//实际上是对一个变量取值范围的限定,花括号内则是它的取值范围如果不赋值,会从赋初值的常量开始依次加一,如果都没有赋值则\从0开始依次加一 { Exit, Add, Delete, Find, Empty, Modify, Sort, Show, } Number_Val; typedef struct Personal { char name[30]; char gender[10]; int age; int telephone; char address[100]; }Personal; typedef struct Contacts { Personal *data; //所有联系人的信息,定义一个指向Personal结构体的指针 int size; //当前联系人的个数 int capacity; }Contact, **contact; void Init(contact p) { (*p)->data = (Personal *)malloc(sizeof(Personal)*MAX_INIT); if ((*p)->data == NULL) { printf("out of memory"); exit(1); } else (*p)->size = 0; //初始化时联系人个数为0 (*p)->capacity = MAX_INIT; } void Add_linkman(contact p) { if ((*p)->size == (*p)->capacity) { Personal *temp = (Personal*)realloc((*p)->data, sizeof(Personal)*((*p)->capacity + MAX_EXPAND)); if (temp == NULL) { printf("OUT OF MEMORY"); exit(1); } else { (*p)->data = temp; (*p)->capacity += MAX_EXPAND; } } printf("请输入姓名:"); scanf("%s", (*p)->data[(*p)->size].name);//p->data一个指向Personal结构体的指针 // p->size联系人的个数其实相当于数组的\ //下标访问模式即输入的表示第几个联系人的信息\ // 不能写成p->data.name printf("请输入姓别:"); scanf("%s", (*p)->data[(*p)->size].gender); printf("请输入年龄:"); scanf("%d", &(*p)->data[(*p)->size].age); printf("请输入电话:"); scanf("%d", &(*p)->data[(*p)->size].telephone); printf("请输入地址:"); scanf("%s", (*p)->data[(*p)->size].address); (*p)->size++; } int Find_linkman(contact p, char *str); void Delete_linkman(contact p, char *str)//删除一个联系人的信息其实就是 //信息的覆盖,后一个信息覆盖要删除的信息的位置 { int i = 0; printf("请输入你要删除的联系人的信息:"); char name[30]; scanf("%s", name); int ret = Find_linkman(p, name); if (ret != -1) { for (i = ret; i < (*p)->size; i++) { (*p)->data[i] = (*p)->data[i + 1]; } (*p)->size--; } else printf("该联系人不存在"); } int Find_linkman(contact p, char *str) { int i = 0; for (i = 0; i < (*p)->size; i++) { if (strcmp((*p)->data[i].name, str) == 0) { printf("存在该联系人"); return i;//存在则返回对应的下标 } } printf("不存在该联系人"); return -1; } void Empty_linkman(contact p) { (*p)->size = 0; } void Modify_linkman(contact p) { printf("请输入你要修改的联系人的信息:"); char name[30]; scanf("%s", name); int ret = Find_linkman(p, name); if (ret != -1) { printf("请输入你要修改的联系人的name:"); scanf("%s", (*p)->data[ret].name); printf("请输入你要修改的联系人的gender:"); scanf("%s", (*p)->data[ret].gender); printf("请输入你要修改的联系人的age:"); scanf("%d", &(*p)->data[ret].age); printf("请输入你要修改的联系人的telephone:"); scanf("%d", &(*p)->data[ret].telephone); printf("请输入你要修改的联系人的address:"); scanf("%s", (*p)->data[ret].address); } } void show(contact p) { int i = 0; for (i = 0; i < (*p)->size; i++) { printf("name:%s gender:%s age:%d telephone:%d address:%s", \ (*p)->data[i].name, (*p)->data[i].gender, (*p)->data[i].age, (*p)->data[i].telephone, (*p)->data[i].address); printf("\n"); } } void bubbleSort(contact p) { int i = 0; for (; i < (*p)->size - 1; i++){ int j = 0; int flag = 0; for (j; j < (*p)->size - 1 - i; j++) { if (strcmp((*p)->data[j].name, (*p)->data[j + 1].name)>0) { Personal temp = (*p)->data[j]; (*p)->data[j] = (*p)->data[j + 1]; (*p)->data[j + 1] = temp; //这是将两个结构体之间进行交用 //创建一个临时结构体的方式变量的方式交换 } flag = 1;//如果一次都没有进行交换则直接跳出循环 } if (!flag) break; } } int main() { meau(); Contact p; //定义一个结构体变量 Contact *q = &p;//这结构体指针必须指向这个结构体变量否则它会成为一个野指针 Init(&p); int input = 0; while (1) { printf("请输入一个数字进行选择:"); scanf("%d", &input); switch (input) { case Exit: exit(1); printf("\n"); break; case Add: Add_linkman(w); printf("\n"); break; case Delete: { int num = 0; scanf("%d", &num); Delete_linkman(w, num); printf("\n"); }break; case Find: { char name[30]; scanf("%s", name); Find_linkman(w, name); }; printf("\n"); break; case Modify:Modify_linkman(w); printf("\n"); break; case Show:show(w); printf("\n"); break; case Empty:Empty_linkman(w); printf("\n"); break; case Sort:bubbleSort(w); printf("\n"); break; default:printf("输入错误!!!"); } } free(p); system("pause"); return 0; }
二:另一种直接给这个结构体开辟内存则不用在调用时再指向它。
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #define MAX_INIT 10 #define MAX_EXPAND 10 #define MAX_END 1000 void meau() { printf(" *******************************************\n"); printf(" *******************************************\n"); printf(" ##############My address book##############\n"); printf(" *1-Add 2-Delete 3-Find *\n"); printf(" *4-Empty 5-Modify 6-Sort *\n"); printf(" *0-Exit 7-Show *\n"); printf(" *******************************************\n"); printf(" *******************************************\n"); } enum Number { Exit, //实际上是对一个变量取值范围的限定,花括号内则是它的取值范围\ //如果不赋值,会从赋初值的常量开始依次加一,如果都没有赋值则\ // 从0开始依次加一 Add, Delete, Find, Empty, Modify, Sort, Show, } Number_Val; typedef struct Personal { char name[30]; char gender[10]; int age; int telephone; char address[100]; }Personal, *personal; typedef struct Contacts { Personal *data; //所有联系人的信息,定义一个指向Personal结构体的指针 int size; //当前联系人的个数 int capacity; }Contact, ** contact; void Init(contact p) //使用二级指针传参的方式在释放内存的时候不会造成内存的泄漏问题 { (*p) = (Contact *)malloc(sizeof(Contact));//相当于*(&p)=p; if (*p == NULL) { printf("out of memory"); exit(1); } (*p)->data = (Personal *)malloc(sizeof(Personal)*MAX_INIT); if ((*p)->data == NULL) { printf("out of memory"); exit(1); } else (*p)->size = 0; //初始化时联系人个数为0 (*p)->capacity = MAX_INIT; } void Destory(Contact *p) { free(p->data); p->data = NULL; p->capacity = 0; p->size = 0; free(p); p = NULL; } void Add_linkman(contact p) { if ((*p)->size == (*p)->capacity) { Personal *temp = (Personal*)realloc((*p)->data, sizeof(Personal)*((*p)->capacity + MAX_EXPAND)); if (temp == NULL) { printf("OUT OF MEMORY"); exit(1); } else { (*p)->data = temp; (*p)->capacity += MAX_EXPAND; } if ((*p)->capacity == MAX_END) { printf("已经有1000个人的通讯录了"); } } printf("请输入姓名:"); scanf("%s", (*p)->data[(*p)->size].name);//p->data一个指向Personal结构体的指针 // p->size联系人的个数其实相当于数组的\ //下标访问模式即输入的表示第几个联系人的信息\ // 不能写成p->data.name printf("请输入姓别:"); scanf("%s", (*p)->data[(*p)->size].gender); printf("请输入年龄:"); scanf("%d", &(*p)->data[(*p)->size].age); printf("请输入电话:"); scanf("%d", &(*p)->data[(*p)->size].telephone); printf("请输入地址:"); scanf("%s", (*p)->data[(*p)->size].address); (*p)->size++; } int Find_linkman(contact p, char *str); void Delete_linkman(contact p, char * str)//删除一个联系人的信息其实就是 //信息的覆盖,后一个信息覆盖要删除的信息的位置 { int i = 0; printf("请输入你要删除的联系人的信息:"); char name[30]; scanf("%s", name); int ret = Find_linkman(p, name); if (ret != -1) { for (i = ret; i < (*p)->size; i++) { (*p)->data[i] = (*p)->data[i + 1]; } (*p)->size--; } else printf("该联系人不存在"); } int Find_linkman(contact p, char * str) { int i = 0; for (i = 0; i < (*p)->size; i++) { if (strcmp((*p)->data[i].name, str) == 0) { printf("存在该联系人"); return i;//存在则返回对应的下标 } } printf("不存在该联系人"); return -1; } void Empty_linkman(contact p) { (*p)->size = 0; } void Modify_linkman(contact p) { printf("请输入你要修改的联系人的信息:"); char name[30]; scanf("%s", name); int ret = Find_linkman(p, name); if (ret != -1) { printf("请输入你要修改的联系人的name:"); scanf("%s", (*p)->data[ret].name); printf("请输入你要修改的联系人的gender:"); scanf("%s", (*p)->data[ret].gender); printf("请输入你要修改的联系人的age:"); scanf("%d", &(*p)->data[ret].age); printf("请输入你要修改的联系人的telephone:"); scanf("%d", &(*p)->data[ret].telephone); printf("请输入你要修改的联系人的address:"); scanf("%s", (*p)->data[ret].address); } } void show(contact p) { int i = 0; for (i = 0; i < (*p)->size; i++) { printf("name:%s gender:%s age:%d telephone:%d address:%s", \ (*p)->data[i].name, (*p)->data[i].gender, (*p)->data[i].age, (*p)->data[i].telephone, (*p)->data[i].address); printf("\n"); } } void bubbleSort(contact p) { int i = 0; for (; i < (*p)->size - 1; i++){ int j = 0; int flag = 0; for (j; j < (*p)->size - 1 - i; j++) { if (strcmp((*p)->data[j].name, (*p)->data[j + 1].name)>0) { Personal temp = (*p)->data[j]; (*p)->data[j] = (*p)->data[j + 1]; (*p)->data[j + 1] = temp; //这是将两个结构体之间进行交用 //创建一个临时结构体的方式变量的方式交换 } flag = 1; //如果一次都没有进行交换则直接跳出循环 } if (!flag) break; } } int main() { meau(); Contact *p; Init(&p); int input = 0; while (1) { printf("请输入一个数字进行选择:"); scanf("%d", &input); switch (input) { case Exit: exit(1); printf("\n"); break; case Add: Add_linkman(&p); printf("\n"); break; case Delete: { int num = 0; scanf("%d", &num); Delete_linkman(&p, num); printf("\n"); }break; case Find: { char name[30]; scanf("%s", name); Find_linkman(&p, name); }; printf("\n"); break; case Modify:Modify_linkman(&p); printf("\n"); break; case Show:show(&p); printf("\n"); break; case Empty:Empty_linkman(&p); printf("\n"); break; case Sort:bubbleSort(&p); printf("\n"); break; default:printf("输入错误!!!"); } } Destory(p); system("pause"); return 0; }
相关文章推荐
- 动态内存分配及Malloc/free的实现
- 嵌入式操作系统分析(六):浅析动态内存分配及Malloc/free的实现
- C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存
- 【课设】模拟实现动态内存分配—首次适应算法
- 【c语言】通讯录的简单实现文件版本(动态开辟内存)
- 链表的C语言实现(含动态内存分配)
- 嵌入式操作系统分析:浅析动态内存分配及Malloc/free的实现
- C++动态内存分配---allocator类的原理与实现(一)
- java开发C解释器:实现动态内存的分配和读写
- 动态内存分配及Malloc/free的实现
- C语言实现用程序数据段空间模拟内存的动态分配
- C/C++动态内存分配之用malloc和指针实现动态数组排序
- 内存动态分配函数malloc的基本实现原理
- 链表的C语言实现(含动态内存分配)
- C++动态内存分配---两级allocator设计与实现(二)
- 通过动态内存分配来实现类似于动态数组的功能
- 浅析动态内存分配及Malloc/free的实现
- 通讯录c语言实现(动态内存开辟&文件存储)
- 关于C++的动态内存分配的实现
- 内存动态分配的首先适应、最优适应、最坏适应算法的实现(java 版)