C語(yǔ)言模擬實(shí)現(xiàn)動(dòng)態(tài)通訊錄
1.模擬實(shí)現(xiàn)通訊錄總體架構(gòu)一覽圖

2.文件執(zhí)行任務(wù)

3.分模塊實(shí)現(xiàn)
測(cè)試模塊 test.c
1.為了更好地展示,制作一個(gè)菜單,在菜單中有 添加,刪除,查找,修改,排序,清空,退出的選項(xiàng)。
2.因?yàn)槠鹣纫M(jìn)入程序一趟,所以用do····while循環(huán)(輸入選項(xiàng)來(lái)看具體操作,退出還是其他操作)
#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
//為什么要使用枚舉
//因?yàn)檫@樣可以防止命名污染,而且使用枚舉,枚舉成員有默認(rèn)初始值,默認(rèn)從0開(kāi)始,這樣省去的諸多的代碼量
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
PRINT,
EMPTY,
SORT,
};
int main()
{
//先打印菜單,展示通訊錄功能
int input = 0;
//先進(jìn)行設(shè)置一個(gè)通訊錄
//設(shè)置每個(gè)人的信息
//初始化通訊錄
//通訊錄中的一個(gè)元素
contact con;
//contact 是自定義數(shù)據(jù)類型,包括一個(gè)聯(lián)系人的基本信息
InitContact(&con);
do
{
menu();//設(shè)置菜單
printf("請(qǐng)選擇>");
scanf("%d", &input);
switch (input)
{
case ADD:
//實(shí)現(xiàn)添加功能
AddContact(&con);
break;
case DEL:
//實(shí)現(xiàn)刪除功能
DelContact(&con);
break;
case SEARCH:
//實(shí)現(xiàn)查找功能
SearchContact(&con);
break;
case MODIFY:
//實(shí)現(xiàn)修改功能
ModifyContact(&con);
break;
case PRINT:
//顯示
PrintContact(&con);
break;
case SORT:
//實(shí)現(xiàn)名字排序
SortContact(&con);
break;
case EMPTY:
//實(shí)現(xiàn)清空
EmptyContact(&con);
break;
case EXIT:
//退出程序
ExitContact(&con);
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
}
} while (input);
return 0;
}
頭文件 功能函數(shù)聲明 contact.h
1.聲明各類功能函數(shù)
2.定義各個(gè)常量,把常量定義成通俗易懂的變量,便于在多處使用。
3.定義結(jié)構(gòu)體,自定義類型中,有一個(gè)聯(lián)系人的基本信息。
#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 //在動(dòng)態(tài)申請(qǐng)空間時(shí)默認(rèn)空間為3
#define SET_NUM 2 //當(dāng)基本信息大于3份時(shí),開(kāi)辟兩個(gè)空間
//設(shè)置每一個(gè)人的信息
//通訊錄規(guī)定要求一共有1000個(gè)人
typedef struct base
{
char name[MAX_NAME]; //姓名
char sex[MAX_SEX]; //性別
int age; //年齡
char tele[MAX_TELE]; //電話
char addr[MAX_ADDR]; //住址
}base;
//設(shè)置1000人的通訊錄
//靜態(tài)版
//typedef struct contact
//{
//
// int sz; //計(jì)算當(dāng)前通訊錄中聯(lián)系人的個(gè)數(shù)
// base data[MAX]; //存放聯(lián)系人的信息
//
//}contact;
//動(dòng)態(tài)初始化通訊錄
typedef struct contact
{
//有個(gè)結(jié)構(gòu)體類型中需要,監(jiān)視通訊錄人數(shù)的一項(xiàng),還有當(dāng)聯(lián)系人為3人時(shí),這時(shí)候要進(jìn)行增容
int sz; //計(jì)算當(dāng)前聯(lián)系人的個(gè)數(shù)
base* data; //指向動(dòng)態(tài)申請(qǐng)的空間,存放聯(lián)系人的信息
int capciaty; //計(jì)算當(dāng)前通訊錄中的最大容量
}contact;
//初始化通訊錄
void InitContact(contact* pc);
//添加聯(lián)系人
void AddContact(contact* pc);
//顯示
void PrintContact(contact* pc);
//刪除聯(lián)系人
void DelContact(contact* pc);
//查找聯(lián)系人
void SearchContact(contact* pc);
//修改信息
void ModifyContact(contact* pc);
//排序聯(lián)系人信息
void SortContact(contact* pc);
//清空聯(lián)系人信息
void EmptyContact(contact* pc);
//退出程序時(shí),釋放空間
void ExitContact(contact* pc);
功能函數(shù)逐一實(shí)現(xiàn)
contact.c 1.初始化通訊錄
動(dòng)態(tài)申請(qǐng)空間
默認(rèn)在動(dòng)態(tài)空間中存放3個(gè)基本單位信息
void InitContact(contact* pc)
{
pc->data = (base*)malloc(sizeof(base) * IN_NUM);
if (pc->data == NULL)
//如果空間開(kāi)辟失敗
//退出程序
{
perror("InitContact");
return;
}
//把每個(gè)成員都設(shè)置為0
pc->sz = 0;
pc->capciaty = IN_NUM;
}
2.添加聯(lián)系人
當(dāng)默認(rèn)的空間被裝滿時(shí),然后以后的每一次都開(kāi)辟兩個(gè)基本空間
void AddContact(contact* pc)
{
//先判斷通訊錄中是否滿了
//if (pc->sz == MAX)
//{
// printf("通訊錄已滿,無(wú)法添加\n");
// return;
//}
//動(dòng)態(tài)判斷人的個(gè)數(shù)是否滿足3
if (pc->sz == pc->capciaty)
{
printf("開(kāi)始增容:\n");
//從新設(shè)置一個(gè)指針,存放新開(kāi)辟的內(nèi)存
base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base));
//判斷是否開(kāi)辟成功
if (ptr == NULL)
{
printf("開(kāi)辟失敗\n");
perror("AddContact");
return;
}
else
{
printf("開(kāi)辟成功\n");
//開(kāi)辟成功的話,把ptr轉(zhuǎn)交給data來(lái)維護(hù),這樣在內(nèi)存釋放的時(shí)候只需要釋放pc->data
pc->data = ptr;
//增加基本信息數(shù)量
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.顯示聯(lián)系人信息
逐一打印聯(lián)系人信息,注意之間的距離(保持美觀)
//顯示
void PrintContact(contact* pc)
{
//顯示標(biāo)題
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.刪除聯(lián)系人
在刪除聯(lián)系人之前,首先要查找要?jiǎng)h除聯(lián)系人的名字,然后進(jìn)行刪除,注意如何刪除
讓刪除的這個(gè)單位的后一個(gè)單位去覆蓋這個(gè)刪除的單位(這樣原來(lái)要?jiǎng)h除的地方變成了后面一個(gè)值) i = i+1
當(dāng)通訊錄中有被刪除著的名字時(shí),返回這個(gè)單位的下標(biāo)
當(dāng)通訊錄中沒(méi)有時(shí),返回-1
//查找聯(lián)系人
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;
}
//刪除聯(lián)系人
void DelContact(contact* pc)
{
//如果通訊錄是空的
if (pc->sz == 0)
{
printf("通訊為空,無(wú)需刪除\n");
return;
}
//下進(jìn)行查找被刪除聯(lián)系人的名字
char name[MAX_NAME];
printf("請(qǐng)輸入要?jiǎng)h除聯(lián)系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯(lián)系人不存在\n");
return;
}
//刪除
//刪除項(xiàng)后邊的一項(xiàng),覆蓋前面的一項(xiàng)
for (int i = ret; i < pc->sz; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("刪除成功\n");
}
4.查找聯(lián)系人
在刪除聯(lián)系人的時(shí)候有查找函數(shù),在這里直接引用,并打印。這個(gè)人的信息。
//查找聯(lián)系人
void SearchContact(contact* pc)
{
char name[MAX_NAME];
printf("請(qǐng)輸入要查找聯(lián)系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯(lián)系人不存在\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.修該聯(lián)系人信息
還是現(xiàn)在通訊錄中查找這個(gè)聯(lián)系人,在進(jìn)行輸入修改
//修改信息
void ModifyContact(contact* pc)
{
char name[MAX_NAME];
printf("請(qǐng)輸入要修改聯(lián)系人的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("該聯(lián)系人不存在\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.排序聯(lián)系人姓名
利用冒泡排序?qū)β?lián)系人的名字進(jìn)行排序(也可以使用快排)
//排序
//交換名字,但是名字要和聯(lián)系人的信息匹配
//先比較名字,根據(jù)名字的大小,再排序
static void SwapByname(base* pa, base* pb)
{
base b;
b = *pa;
*pa = *pb;
*pb = b;
}
void SortContact(contact* pc)
{
printf("開(kāi)始排序\n");
//使用冒泡排序?qū)β?lián)系人的名字進(jì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)
{
//實(shí)現(xiàn)交換姓名
SwapByname(&pc->data[j], &pc->data[j + 1]);
}
}
}
printf("排序結(jié)束\n");
}
7.清空聯(lián)系人
在這里直接使用sz–,就可以刪除
//清空
void EmptyContact(contact* pc)
{
//如果原來(lái)的通訊錄是空的就無(wú)須清空
if (pc->sz == 0)
{
printf("通訊錄為空,無(wú)需清空\(chéng)n");
return;
}
printf("開(kāi)始清除數(shù)據(jù):\n");
int num = pc->sz;
for (int i = 0; i < num; i++)
{
pc->sz--;
}
printf("清空完畢\n");
}
8.退出通訊錄
手動(dòng)開(kāi)辟,手動(dòng)釋放
//退出程序,釋放空間
void ExitContact(contact* pc)
{
//釋放空間
free(pc->data);
pc->data = NULL;
pc->sz = 0;
pc->capciaty = 0;
}
運(yùn)行展示:

到此這篇關(guān)于C語(yǔ)言模擬實(shí)現(xiàn)動(dòng)態(tài)通訊錄的文章就介紹到這了,更多相關(guān)C語(yǔ)言 動(dòng)態(tài)通訊錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++自主分配出現(xiàn)double free or corruption問(wèn)題解決
這篇文章主要為大家介紹了C/C++出現(xiàn)double free or corruption問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
使用C語(yǔ)言實(shí)現(xiàn)從avi視頻中提取圖片
這篇文章主要為大家詳細(xì)介紹了如何使用C語(yǔ)言實(shí)現(xiàn)從avi視頻中提取圖片,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2023-10-10
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序表和單鏈表
在數(shù)據(jù)結(jié)構(gòu)中,線性表是入門級(jí)數(shù)據(jù)結(jié)構(gòu),線性表又分為順序表和鏈表,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序表和單鏈表的相關(guān)資料,需要的朋友可以參考下2021-06-06
C++使用循環(huán)計(jì)算標(biāo)準(zhǔn)差的代碼實(shí)現(xiàn)
在C++中,計(jì)算標(biāo)準(zhǔn)差可以使用循環(huán)來(lái)實(shí)現(xiàn),本文給大家介紹了一個(gè)示例代碼,演示了如何使用循環(huán)計(jì)算標(biāo)準(zhǔn)差,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-12-12

