文章目錄
-
- 1.模拟實作通訊錄總體架構一覽圖
- 2.檔案執行任務
- 3.分子產品實作
-
- 測試子產品 test.c
- 頭檔案 功能函數聲明 contact.h
- 功能函數逐一實作 contact.c
-
- 1.初始化通訊錄
- 2.添加聯系人
- 3.顯示聯系人資訊
- 4.删除聯系人
- 4.查找聯系人
- 5.修該聯系人資訊
- 6.排序聯系人姓名
- 7.清空聯系人
- 8.退出通訊錄
1.模拟實作通訊錄總體架構一覽圖

2.檔案執行任務
3.分子產品實作
測試子產品 test.c
1.為了更好地展示,制作一個菜單,在菜單中有 添加,删除,查找,修改,排序,清空,退出的選項。
2.因為起先要進入程式一趟,是以用do····while循環(輸入選項來看具體操作,退出還是其他操作)
#include "contact.h"
void menu()
{
printf("*****************************************\n");
printf("******** Contact ******\n");
printf("******** 1.add 2. del ******\n");
printf("******** 3.search 4.modify ******\n");
printf("******** 5.print 6.empty ******\n");
printf("******** 7.sort 0.exit ******\n");
printf("*****************************************\n");
}
enum Option
//為什麼要使用枚舉
//因為這樣可以防止命名污染,而且使用枚舉,枚舉成員有預設初始值,預設從0開始,這樣省去的諸多的代碼量
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
PRINT,
EMPTY,
SORT,
};
int main()
{
//先列印菜單,展示通訊錄功能
int input = 0;
//先進行設定一個通訊錄
//設定每個人的資訊
//初始化通訊錄
//通訊錄中的一個元素
contact con;
//contact 是自定義資料類型,包括一個聯系人的基本資訊
InitContact(&con);
do
{
menu();//設定菜單
printf("請選擇>");
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 PRINT:
//顯示
PrintContact(&con);
break;
case SORT:
//實作名字排序
SortContact(&con);
break;
case EMPTY:
//實作清空
EmptyContact(&con);
break;
case EXIT:
//退出程式
ExitContact(&con);
break;
default:
printf("輸入錯誤,請重新輸入\n");
}
} while (input);
return 0;
}
頭檔案 功能函數聲明 contact.h
1.聲明各類功能函數
2.定義各個常量,把常量定義成通俗易懂的變量,便于在多處使用。
3.定義結構體,自定義類型中,有一個聯系人的基本資訊。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20 //定義姓名字元串的大小為20
#define MAX_SEX 10 //定義性别字元串的大小為10
#define MAX_TELE 12 //定義電話字元串的大小為12
#define MAX_ADDR 20 //定義位址字元串的大小為20
#define MAX 1000 //定義通訊錄的最大容量為1000
#define IN_NUM 3 //在動态申請空間時預設空間為3
#define SET_NUM 2 //當基本資訊大于3份時,開辟兩個空間
//設定每一個人的資訊
//通訊錄規定要求一共有1000個人
typedef struct base
{
char name[MAX_NAME]; //姓名
char sex[MAX_SEX]; //性别
int age; //年齡
char tele[MAX_TELE]; //電話
char addr[MAX_ADDR]; //住址
}base;
//設定1000人的通訊錄
//靜态版
//typedef struct contact
//{
//
// int sz; //計算目前通訊錄中聯系人的個數
// base data[MAX]; //存放聯系人的資訊
//
//}contact;
//動态初始化通訊錄
typedef struct contact
{
//有個結構體類型中需要,監視通訊錄人數的一項,還有當聯系人為3人時,這時候要進行增容
int sz; //計算目前聯系人的個數
base* data; //指向動态申請的空間,存放聯系人的資訊
int capciaty; //計算目前通訊錄中的最大容量
}contact;
//初始化通訊錄
void InitContact(contact* pc);
//添加聯系人
void AddContact(contact* pc);
//顯示
void PrintContact(contact* pc);
//删除聯系人
void DelContact(contact* pc);
//查找聯系人
void SearchContact(contact* pc);
//修改資訊
void ModifyContact(contact* pc);
//排序聯系人資訊
void SortContact(contact* pc);
//清空聯系人資訊
void EmptyContact(contact* pc);
//退出程式時,釋放空間
void ExitContact(contact* pc);
功能函數逐一實作 contact.c
1.初始化通訊錄
動态申請空間
預設在動态空間中存放3個基本機關資訊
void InitContact(contact* pc)
{
pc->data = (base*)malloc(sizeof(base) * IN_NUM);
if (pc->data == NULL)
//如果空間開辟失敗
//退出程式
{
perror("InitContact");
return;
}
//把每個成員都設定為0
pc->sz = 0;
pc->capciaty = IN_NUM;
}
2.添加聯系人
當預設的空間被裝滿時,然後以後的每一次都開辟兩個基本空間
void AddContact(contact* pc)
{
//先判斷通訊錄中是否滿了
//if (pc->sz == MAX)
//{
// printf("通訊錄已滿,無法添加\n");
// return;
//}
//動态判斷人的個數是否滿足3
if (pc->sz == pc->capciaty)
{
printf("開始增容:\n");
//從新設定一個指針,存放新開辟的記憶體
base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base));
//判斷是否開辟成功
if (ptr == NULL)
{
printf("開辟失敗\n");
perror("AddContact");
return;
}
else
{
printf("開辟成功\n");
//開辟成功的話,把ptr轉交給data來維護,這樣在記憶體釋放的時候隻需要釋放pc->data
pc->data = ptr;
//增加基本資訊數量
pc->capciaty += SET_NUM;
}
printf("增容完畢\n");
}
//添加
printf("姓名是>");
scanf("%s", pc->data[pc->sz].name);
printf("年齡是>");
scanf("%d", &pc->data[pc->sz].age);
printf("性别>");
scanf("%s", pc->data[pc->sz].sex);
printf("電話>");
scanf("%s", pc->data[pc->sz].tele);
printf("住址>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
3.顯示聯系人資訊
逐一列印聯系人資訊,注意之間的距離(保持美觀)
//顯示
void PrintContact(contact* pc)
{
//顯示标題
printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年齡", "電話", "住址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s %-10s %-5d %-15s %-20s\n",
pc->data[i].name,
pc->data[i].sex,
pc->data[i].age,
pc->data[i].tele,
pc->data[i].addr);
}
}
4.删除聯系人
在删除聯系人之前,首先要查找要删除聯系人的名字,然後進行删除,注意如何删除
讓删除的這個機關的後一個機關去覆寫這個删除的機關(這樣原來要删除的地方變成了後面一個值) i = i+1
當通訊錄中有被删除着的名字時,傳回這個機關的下标
當通訊錄中沒有時,傳回-1
//查找聯系人
static int Find_name(contact* pc, char name[])
{
int i = 0;
for ( i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
//删除聯系人
void DelContact(contact* pc)
{
//如果通訊錄是空的
if (pc->sz == 0)
{
printf("通訊為空,無需删除\n");
return;
}
//下進行查找被删除聯系人的名字
char name[MAX_NAME];
printf("請輸入要删除聯系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯系人不存在\n");
return;
}
//删除
//删除項後邊的一項,覆寫前面的一項
for (int i = ret; i < pc->sz; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
4.查找聯系人
在删除聯系人的時候有查找函數,在這裡直接引用,并列印。這個人的資訊。
//查找聯系人
void SearchContact(contact* pc)
{
char name[MAX_NAME];
printf("請輸入要查找聯系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯系人不存在\n");
return;
}
printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年齡", "電話", "住址");
printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[ret].name,
pc->data[ret].sex,
pc->data[ret].age,
pc->data[ret].tele,
pc->data[ret].addr);
}
5.修該聯系人資訊
還是現在通訊錄中查找這個聯系人,在進行輸入修改
//修改資訊
void ModifyContact(contact* pc)
{
char name[MAX_NAME];
printf("請輸入要修改聯系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯系人不存在\n");
return;
}
printf("姓名是>");
scanf("%s", pc->data[ret].name);
printf("年齡是>");
scanf("%d", &pc->data[ret].age);
printf("性别>");
scanf("%s", pc->data[ret].sex);
printf("電話>");
scanf("%s", pc->data[ret].tele);
printf("住址>");
scanf("%s", pc->data[ret].addr);
}
6.排序聯系人姓名
利用冒泡排序對聯系人的名字進行排序(也可以使用快排)
//排序
//交換名字,但是名字要和聯系人的資訊比對
//先比較名字,根據名字的大小,再排序
static void SwapByname(base* pa, base* pb)
{
base b;
b = *pa;
*pa = *pb;
*pb = b;
}
void SortContact(contact* pc)
{
printf("開始排序\n");
//使用冒泡排序對聯系人的名字進行排序
int i = 0;
int j = 0;
for (i = 0; i < pc->sz; i++)
{
for (j = 0; j < pc-> sz - i - 1; j++)
{
if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
{
//實作交換姓名
SwapByname(&pc->data[j], &pc->data[j + 1]);
}
}
}
printf("排序結束\n");
}
7.清空聯系人
在這裡直接使用sz–,就可以删除
//清空
void EmptyContact(contact* pc)
{
//如果原來的通訊錄是空的就無須清空
if (pc->sz == 0)
{
printf("通訊錄為空,無需清空\n");
return;
}
printf("開始清除資料:\n");
int num = pc->sz;
for (int i = 0; i < num; i++)
{
pc->sz--;
}
printf("清空完畢\n");
}
8.退出通訊錄
手動開辟,手動釋放
//退出程式,釋放空間
void ExitContact(contact* pc)
{
//釋放空間
free(pc->data);
pc->data = NULL;
pc->sz = 0;
pc->capciaty = 0;
}
運作展示: