一、前言
基于已經學過的順序表,可以實現一個簡單的通訊錄。
二、通訊錄相關頭文件
//Contact.h
#pragma once#define NAME_MAX 20
#define TEL_MAX 20
#define ADDR_MAX 20
#define GENDER_MAX 20typedef struct PersonInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PsInFo;//struct SeqList;//前置聲明typedef struct SeqList Contact;//對順序表重命名為通訊錄//通訊錄的初始化
void ContactInit(Contact* pcon);//通訊錄的銷毀
void ContactDestroy(Contact* pcon);//添加聯系人
void ContactAdd(Contact* pcon);//刪除聯系人
void ContactDel(Contact* pcon);//查找聯系人
void ContactFind(Contact* pcon);//修改聯系人
void ContactModify(Contact* pcon);//展示聯系人
void ContactShow(Contact* pcon);
上述代碼中結構體是我們自己定義的通訊錄中聯系人的基本信息,通訊錄中的聯系人就相當于是順序表中的一個個數據,而通訊錄就相當于是順序表;
至于后面兩行代碼(前置聲明和重命名)需要結合以下代碼來理解
//SeqList.h
#pragma once
//順序表
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//引用通訊錄的頭文件來對數據類型進行重命名
#include"Contact.h"typedef PsInFo SeqDatatype;typedef struct SeqList
{SeqDatatype* arr;int size;int capacity;
}SL;//初始化順序表
void SeqInit(SL* ps);
//銷毀順序表
void SeqDestroy(SL* ps);
//順序表尾插
void SeqPushBack(SL* ps, SeqDatatype x);
//申請空間
void SeqCheckSpace(SL* ps);
//打印順序表的元素
void SeqPrint(SL* ps);
//順序表頭插
void SeqPushFront(SL* ps, SeqDatatype x);
//順序表尾刪
void SeqPopBack(SL* ps);
//順序表頭刪
void SeqPopFront(SL* ps);
//指定位置前插入數據
void SeqInsert(SL* ps, int pos, SeqDatatype x);
//刪除指定位置的數據
void SeqErase(SL* ps, int pos);
//尋找數據(以下標的形式返回)
//int SeqFind(SL s, SeqDatatype x);
這是順序表的頭文件,我們為了將聯系人PsInFo定義為新的數據類型需要引用Contact.h的頭文件,這是因為聯系人是在Contact.h中定義的;所以現在回到第一段本文展示的代碼中的那兩行代碼(前置聲明和重命名),我們為了讓SeqList等同于Contact,需要重命名,但是此時要使用SeqList不能直接包含SeqList.h這個頭文件,這時因為頭文件不能互相包含,此時我們需要進行前置聲明,也就是struct SeqList; 可以直接結合起來寫成typedef struct SeqList Contact;
值得注意的是,這里不能寫成typedef SL Contact;因為這相當于沒有進行前置聲明。解釋:雖然在順序表頭文件中,typedef strcut SeqList{·······}SL 看似是結構體和SL一起定義的,但實際上是結構體先定義的,也就是說,在這個結構體未定義的時候就使用SL是非法的,在Contact.h中寫成typedef SL Contact; 就是遇到了這種錯誤,所以要進行前置聲明,這樣就能規避這種問題。
三、通訊錄的具體實現
1、初始化
//初始化通訊錄
void ContactInit(Contact* pcon)
{assert(pcon);SeqInit(pcon);
}
2、銷毀
//通訊錄銷毀
void ContactDestroy(Contact* pcon)
{assert(pcon);SeqDestroy(pcon);
}
3、添加聯系人
//添加聯系人
void ContactAdd(Contact* pcon)
{assert(pcon);SeqCheckSpace(pcon);PsInFo info;//定義一個聯系人printf("輸入聯系人姓名:\n");scanf("%s", info.name);printf("輸入聯系人性別:\n");scanf("%s", info.gender);printf("輸入聯系人年齡:\n");scanf("%d", &info.age);printf("輸入聯系人電話:\n");scanf("%s", info.tel);printf("輸入聯系人地址:\n");scanf("%s", info.addr);SeqPushBack(pcon,info);
}
?把聯系人當成順序表中的數據,先把這個數據賦予確定的數值,在這里相當于是給聯系人輸入一個個屬性(姓名、性別、年齡······),最后進行順序表尾插的操作;
4、返回聯系人下標
int FindByName(Contact* pcon,char name[])
{for (int i = 0; i < pcon->size; i++){if (strcmp(name, pcon->arr[i].name)==0){return i;}}return -1;
}
這個函數是通過姓名比較的方式來返回即將進行一系列操作的聯系人的下標?
5、刪除聯系人
//刪除聯系人
void ContactDel(Contact* pcon)
{assert(pcon);assert(pcon->size);char name[NAME_MAX];printf("輸入要刪除的聯系人姓名:\n");scanf("%s", name);int rsl=FindByName(pcon,name);if (rsl == -1){printf("你要刪除的聯系人不存在\n");}else{SeqErase(pcon, rsl);}
}
首先判斷這個通訊錄里面有沒有聯系人,沒有聯系人則斷言錯誤,無法刪除。接著要輸入一個聯系人姓名,再在通過FindByName這個通訊錄里面進行遍歷看是否有沒有這個聯系人,如果沒有接收到錯誤的下標,進行不了后續操作;找到了返回這個姓名的聯系人的下標,然后使用SeqErase刪除這個下標處的聯系人;
6、查找聯系人
//查找聯系人
void ContactFind(Contact* pcon)
{assert(pcon);char name[NAME_MAX];printf("輸入要查找的聯系人姓名:\n");scanf("%s", name);int rsl = FindByName(pcon, name);if (rsl == -1){printf("你要查找的聯系人不存在\n");}else{printf("%s""%s""%s""%s""%s", "姓名 ", "性別 ", "年齡 ", "電話 ", "地址 ");printf("\n");printf("%s ""%s ""%d ""%s ""%s ", pcon->arr[rsl].name, pcon->arr[rsl].gender, pcon->arr[rsl].age, pcon->arr[rsl].tel, pcon->arr[rsl].addr);printf("\n");}
}
查找聯系人不同于返回聯系人下標,它要展示出所查找的這個聯系人的相關信息;
7、修改聯系人信息
//修改聯系人
void ContactModify(Contact* pcon)
{assert(pcon);char name[NAME_MAX];printf("輸入要修改信息的聯系人姓名:\n");scanf("%s", name);int rsl = FindByName(pcon, name);if (rsl == -1){printf("你要修改信息的聯系人不存在\n");}else{printf("開始輸入新的聯系人信息\n");printf("輸入聯系人姓名:\n");scanf("%s", pcon->arr[rsl].name);printf("輸入聯系人性別:\n");scanf("%s", pcon->arr[rsl].gender);printf("輸入聯系人年齡:\n");scanf("%d", &pcon->arr[rsl].age);printf("輸入聯系人電話:\n");scanf("%s", pcon->arr[rsl].tel);printf("輸入聯系人地址:\n");scanf("%s", pcon->arr[rsl].addr);}
}
同樣的,先通過姓名的比較來判斷該聯系人存不存在,若是有則重新在此聯系人下標處出入相關信息;
8、展示聯系人
//展示聯系人
void ContactShow(Contact* pcon)
{assert(pcon);printf("%s""%s""%s""%s""%s", "姓名 ", "性別 ", "年齡 ", "電話 ", "地址 ");printf("\n");for (int i = 0; i < pcon->size; i++){printf("%s ", pcon->arr[i].name);printf("%s ", pcon->arr[i].gender);printf("%d ", pcon->arr[i].age);printf("%s ", pcon->arr[i].tel);printf("%s ", pcon->arr[i].addr);printf("\n");}
}
通過遍歷通訊錄來展翅一個一個聯系人的相關信息。
四、設置操作面板
#include"Contact.h"
#include"SeqList.h"void menu()
{printf("********** 1.增加聯系人**********\n");printf("********** 2.刪除聯系人**********\n");printf("********** 3.查找聯系人**********\n");printf("********** 4.修改聯系人**********\n");printf("********** 5.展示聯系人**********\n");printf("********** 6.銷毀通訊錄**********\n");printf("********** 0.退出 **********\n");}
int main()
{menu();Contact con;ContactInit(&con);int option = -1;do{printf("輸入操作數:\n");scanf_s("%d", &option);switch (option){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactFind(&con);break;case 4:ContactModify(&con);break;case 5:ContactShow(&con);break;case 6:ContactDestroy(&con);break;case 0:printf("退出\n");return;default:printf("輸入錯誤,重新選擇\n");}} while (option);return 0;
}
?
?
完。