摘要:二靜態(tài)通訊錄接口函數(shù)實(shí)現(xiàn)文件名功能通訊錄函數(shù)接口的實(shí)現(xiàn)宏定義,頭文件,接口函數(shù)的聲明函數(shù)接口測(cè)試靜態(tài)通訊錄的基本結(jié)構(gòu)通訊錄是一個(gè)結(jié)構(gòu)體。
前言:之前,博主已經(jīng)寫(xiě)過(guò)兩個(gè)有意思的小項(xiàng)目:三子棋和掃雷,接下來(lái),博主繼續(xù)更新一個(gè)小項(xiàng)目-通訊錄,包括3種版本,靜態(tài)版,動(dòng)態(tài)版,文件保存版。接下來(lái),我們先講解如何實(shí)現(xiàn)靜態(tài)版。
目錄
二.靜態(tài)通訊錄接口函數(shù)實(shí)現(xiàn)
靜態(tài)通訊錄:使用的是定長(zhǎng)數(shù)組,即數(shù)組的長(zhǎng)度不能發(fā)生改變。我們可以設(shè)置通訊錄可以記錄的成員個(gè)數(shù)為1000個(gè)。
文件名 | 功能 |
Contact.c | 通訊錄函數(shù)接口的實(shí)現(xiàn) |
Contact.h | 宏定義,頭文件,接口函數(shù)的聲明 |
test.c | 函數(shù)接口測(cè)試 |
通訊錄是一個(gè)結(jié)構(gòu)體。
包含:1.通訊錄成員數(shù)組,每一個(gè)通訊錄成員又是一個(gè)結(jié)構(gòu)體,包括:地址,姓名,年齡,性別,地址,電話。
? ? ? ? ? 2.標(biāo)志通訊錄成員個(gè)數(shù)的變量。
注意:為了方便后序更改通訊錄的各種大小,推薦使用宏定義
//注意宏定義后面不要跟分號(hào)?。。?!不然會(huì)有問(wèn)題#define NAME_MAX 30 //名字最大長(zhǎng)度#define SEX_MAX 5 //性別最大長(zhǎng)度#define TELE_MAX 12 //電話最大長(zhǎng)度#define ADDR_MAX 30 //地址最大長(zhǎng)度#define MAX 1000 //通訊錄數(shù)組的成員總數(shù)typedef struct PeoInfo{ char name[NAME_MAX]; int age; char sex[SEX_MAX]; char addr[ADDR_MAX]; char tele[TELE_MAX];}PeoInfo;struct Contact //通訊錄{ PeoInfo data[MAX]; //結(jié)構(gòu)體成員數(shù)組 int size; //標(biāo)志通訊錄中所含成員個(gè)數(shù), 控制數(shù)組下標(biāo)};
enum Option{ EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, DESTORY,};void menu(){ printf("******************************/n"); printf("**** 1. add 2. del *****/n"); printf("**** 3. search 4. modify****/n"); printf("**** 5. show 6. Destory ***/n"); printf("**** 0. exit **/n"); printf("******************************/n");}int main(){ int input = 0; struct Contact con; //創(chuàng)建通訊錄,內(nèi)含MAX個(gè)結(jié)構(gòu)體成員 InitContact(&con); //初始化通訊錄 do { menu(); printf("請(qǐng)選擇->/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 DESTORY: DesContact(&con); break; case EXIT: printf("退出成功!歡迎再次使用!/n"); break; default: printf("選擇錯(cuò)誤,請(qǐng)重新選擇/n"); break; } } while (input); return 0;}
使用memset初始化通訊錄成員數(shù)組
寫(xiě)法1:每個(gè)成員的大小*成員個(gè)數(shù)?
void InitContact(struct Contact* ps){ assert(ps); //最初沒(méi)有數(shù)據(jù) memset(ps->data, 0, sizeof(PeoInfo) * MAX); //通訊錄成員數(shù)組初始化為0 ps->size = 0;//默認(rèn)成員為0}
寫(xiě)法2:數(shù)組多帶帶放在sizeof內(nèi)部->計(jì)算的是整個(gè)數(shù)組的大小?
//寫(xiě)法2void InitContact(struct Contact* ps){ memset(ps->data, 0, sizeof(ps->data)); //ps->data拿到了通訊錄中PenInfo數(shù)組的數(shù)組名//數(shù)組名多帶帶放在sizeof內(nèi)部,計(jì)算的是整個(gè)數(shù)組的大小 ps->size = 0;}
為了更直觀,我們可以把標(biāo)題也進(jìn)行打印。通過(guò)遍歷通訊錄成員數(shù)組,即可把成員打印出來(lái)。
//這是右對(duì)齊 如果想要左對(duì)齊-> -%30d前面加符號(hào) 在%前面數(shù)字加負(fù)號(hào)void ShowContact(struct Contact* ps){ int i = 0; //打印標(biāo)題 printf("%15s/t%5s/t%8s/t%15s/t%30s/t/n/n", "name", "age", "sex", "tele", "addr"); //打印數(shù)組中每個(gè)結(jié)構(gòu)體成員的內(nèi)容 for (i = 0; i < ps->size; i++) { printf("%15s/t%5d/t%8s/t%15s/t%30s/n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].addr); }}
寫(xiě)法1:直接對(duì)通訊錄成員數(shù)組進(jìn)行操作
void ADDContact(struct Contact* ps){ //先判斷通訊錄是否滿了 if (ps->size == MAX) { printf("通訊錄已滿/n"); } else { printf("請(qǐng)輸入名字:"); scanf("%s", ps->data[ps->size].name); //數(shù)組名不用& printf("請(qǐng)輸入年齡: "); scanf("%d", &(ps->data[ps->size].age)); printf("請(qǐng)輸入地址:"); scanf("%s", ps->data[ps->size].addr); printf("請(qǐng)輸入號(hào)碼:"); scanf("%s", ps->data[ps->size].tele); printf("請(qǐng)輸入性別:"); scanf("%s", ps->data[ps->size].sex); printf("添加成功/n"); ps->size++; //添加了一個(gè)成員,size++ }}
?寫(xiě)法2:先創(chuàng)建一個(gè)臨時(shí)結(jié)構(gòu)體成員,然后賦值后,賦給通訊錄結(jié)構(gòu)體數(shù)組中ps->size位置
//增加成員的寫(xiě)法2:void ADDContact(struct Contact* ps){ PeoInfo tmp = { 0 }; //先判斷通訊錄是否滿了 if (ps->size == MAX) { printf("通訊錄已滿/n"); } else { printf("請(qǐng)輸入名字:"); scanf("%s", tmp.name); //數(shù)組名不用& printf("請(qǐng)輸入年齡: "); scanf("%d", &(tmp.age)); printf("請(qǐng)輸入地址:"); scanf("%s", tmp.addr); printf("請(qǐng)輸入號(hào)碼:"); scanf("%s", tmp.tele); printf("請(qǐng)輸入性別:"); scanf("%s", tmp.sex); ps->data[ps->size] = tmp; printf("添加成功/n"); ps->size++; }}
因?yàn)閟ize 標(biāo)志的是通訊錄中的成員個(gè)數(shù),所以只要判斷size是否為0即可知道通訊錄是否為空
//如果為空,判斷成立,返回1bool EmptyContact(struct Contact* ps){ return ps->size == 0;}
因?yàn)楹罄m(xù)刪除指定聯(lián)系人,更改指定聯(lián)系人的信息都需要進(jìn)行查找,所以可以把查找函數(shù)多帶帶封裝
找到了,返回對(duì)應(yīng)的下標(biāo),找不到返回-1
因?yàn)椴蛔餍薷?,所以可以加上const修飾
方法:遍歷結(jié)構(gòu)體成員數(shù)組進(jìn)行查找
int FindContactByName(const struct Contact* ps,const char*name ){ //遍歷查找 int i = 0; for(i = 0;i< ps->size;i++) { if( strcmp(name,ps->data[i].name) == 0) { //返回下標(biāo) return i; } } return -1;}
注意:刪除聯(lián)系人->從該位置開(kāi)始后面的數(shù)據(jù)往前覆蓋
如通訊錄為空,則不刪除,直接返回.
void DelContact(struct Contact* ps){ if (EmptyContact(ps)) { printf("通訊錄為空,無(wú)法刪除/n"); return ; } char name[NAME_MAX] = { 0 }; //用來(lái)存儲(chǔ)要?jiǎng)h除的指定聯(lián)系人的名字 printf("請(qǐng)輸入要?jiǎng)h除人得名字:>"); scanf("%s",name); //查找 int pos = FindContactByName(ps, name); if (pos == -1) { printf("指定的聯(lián)系人不存在/n"); } else { //刪除操作 //從pos位置開(kāi)始,后面的往前覆蓋 int i = 0; for (i = pos; i < ps->size - 1; i++) { ps->data[i] = ps->data[i + 1]; } //刪除了元素,size-- ps->size--; printf("刪除成功/n"); }}
方法:輸入要查找的聯(lián)系人名字,調(diào)用查找函數(shù)進(jìn)行查找,若找到,返回對(duì)應(yīng)下標(biāo),就把該下標(biāo)對(duì)應(yīng)的聯(lián)系人對(duì)應(yīng)信息打印出來(lái)
void SearchContact(const struct Contact* ps){ char name[NAME_MAX] = {0}; printf("輸入要查找的聯(lián)系人:>"); scanf("%s",name); int pos =FindContactByName(ps,name); if(pos == -1) { printf("要查找的聯(lián)系人不存在/n"); } else { // 打印該聯(lián)系人對(duì)應(yīng)的信息 //打印標(biāo)題 printf("%15s/t%5s/t%8s/t%15s/t%30s/t/n/n", "name", "age", "sex", "tele", "addr"); printf("%15s/t%5d/t%8s/t%15s/t%30s/n", ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].addr); } }}
方法:輸入要查找的聯(lián)系人名字,調(diào)用查找函數(shù)進(jìn)行查找,找到了返回對(duì)應(yīng)下標(biāo),然后修改對(duì)應(yīng)數(shù)組下標(biāo)的內(nèi)容
void ModifyContact(struct Contact* ps){ char name[NAME_MAX] = { 0 }; printf("請(qǐng)輸入要修改人名字:>"); scanf("%s", name); int pos = FindContactByName(ps, name); if (-1 == pos) { printf("查無(wú)此人/n"); } else { printf("請(qǐng)輸入新名字:"); scanf("%s", ps->data[pos].name); //數(shù)組名不用& printf("請(qǐng)輸入新年齡: "); scanf("%d", &(ps->data[pos].age)); printf("請(qǐng)輸入新地址:"); scanf("%s", ps->data[pos].addr); printf("請(qǐng)輸入新號(hào)碼:"); scanf("%s", ps->data[pos].tele); printf("請(qǐng)輸入新性別:"); scanf("%s", ps->data[pos].sex); }}
相當(dāng)于字符串比較->使用strcmp
這里可以使用兩種方法:冒泡排序或者qsort排序
關(guān)于qsort:qsort函數(shù)詳解
?比較的是通訊錄成員數(shù)組中的成員名字?。?!
void SortContact(struct Contact* pcon){ int i, j; struct PeoInfo tmp; for(i = 0; i < pcon->sz - 1; i++) { for(j = 0; j < pcon->sz - 1 - i; j++) { if(0 < strcmp(pcon->data[j].name, pcon->data[j + 1].name)) { tmp = pcon->data[j]; pcon->data[j] = pcon->data[j + 1]; pcon->data[j + 1] = tmp; } } }}
void SortContactByName(struct Contact* ps){ qsort(ps->data, ps->size, sizeof(ps->data[0]), cmp_ContactByName);}int cmp_ContactByName(const void* e1, const void* e2){ return strcmp( ((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);}//注意// ((struct PeoInfo*)e1)->name 要括起來(lái),// (struct PeoInfo*)e1->name 這樣寫(xiě)是錯(cuò)誤的
注意排序的是通訊錄里面的成員數(shù)組ps->data:每個(gè)元素的類型為struct PenInfo ( 結(jié)構(gòu)體成員類型)要排序的個(gè)數(shù)為ps->size
size標(biāo)志的是通訊錄成員個(gè)數(shù)
比較函數(shù):比較的是成員的年齡
void SortContact(struct Contact* ps){ qsort(ps->data, ps->size, sizeof(ps->data[0]), cmp_ContactbyAge);}int cmp_ContactbyAge(const void* e1, const void* e2){ return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;}
清空通訊錄:相當(dāng)于堆通訊錄重新初始化.
void ClearContact(Contact* pcon){ InitContact(pcon);}
成員有限:容易造成空間浪費(fèi)/空間不夠的情況。
為了解決這個(gè)問(wèn)題,下一篇文章,博主將會(huì)帶大家了解動(dòng)態(tài)通訊錄.
很感謝你能看到這里,~如果感覺(jué)對(duì)你有幫助,歡迎給博主一個(gè)三連呀~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/121541.html
摘要:那么我們首先來(lái)改造儲(chǔ)存空間也就是通訊錄結(jié)構(gòu)體靜態(tài)版本人信息存放在數(shù)組中統(tǒng)計(jì)存放的人數(shù)動(dòng)態(tài)版本統(tǒng)計(jì)存放的人數(shù)有效容量我們將原本的結(jié)構(gòu)體數(shù)組改為一個(gè)結(jié)構(gòu)體指針,以此來(lái)維護(hù)用以儲(chǔ)存?zhèn)€人信息的空間。 上一期我們編寫(xiě)了一個(gè)C語(yǔ)言版本的簡(jiǎn)易通訊錄,但是我們的之前的通訊錄是沒(méi)有記憶功能的,也就是說(shuō),一旦關(guān)...
摘要:之前的通訊錄在程序退出后內(nèi)部的數(shù)據(jù)就會(huì)消失,再次打開(kāi)程序后只能重新輸入數(shù)據(jù),為此我們?cè)黾恿艘粋€(gè)保存功能來(lái)保存信息。 前言: 由于之前實(shí)現(xiàn)的通訊錄在存儲(chǔ)方面只能支持靜態(tài)的1000人的存儲(chǔ)量,但是如果聯(lián)系人較少,則會(huì)造成較大的內(nèi)存浪費(fèi)。而當(dāng)聯(lián)系人一旦超過(guò)1000時(shí),就不能再繼續(xù)存儲(chǔ)信息了。因...
??C語(yǔ)言通訊錄管理系統(tǒng)(簡(jiǎn)易版)?? ?一、通訊錄?二、菜單實(shí)現(xiàn)和用戶交互?三、主函數(shù)????1.enum選項(xiàng)????2.switch判斷 ?四、定義聯(lián)系人和通訊錄????1.定義聯(lián)系人結(jié)構(gòu)體????2.定義通訊錄結(jié)構(gòu)體????3.定義結(jié)構(gòu)體變量 ?五、通訊錄初始化?六、新增聯(lián)系人?七、查找聯(lián)系人?八、刪除聯(lián)系人?九、修改聯(lián)系人?十、查看所有聯(lián)系人?十一、清空所有聯(lián)系人?十二、以名字排序所有...
摘要:前言我們需要用語(yǔ)言模擬一個(gè)通訊錄可以用來(lái)存儲(chǔ)個(gè)人的信息每個(gè)人的信息包括姓名電話性別住址年齡功能包括新增聯(lián)系人查找聯(lián)系人刪除聯(lián)系人修改聯(lián)系人查看所有聯(lián)系人以名字排序所有聯(lián)系人注此版本不包含其他內(nèi)容,后續(xù)會(huì)出更加全面的升級(jí)版本通訊錄語(yǔ)言簡(jiǎn)易版 前言: 我們需要用C語(yǔ)言模擬一個(gè)通訊錄可以用來(lái)存...
閱讀 1919·2021-11-22 15:25
閱讀 4151·2021-11-17 09:33
閱讀 2603·2021-10-12 10:12
閱讀 1882·2021-10-09 09:44
閱讀 3303·2021-10-08 10:04
閱讀 1387·2021-09-29 09:35
閱讀 2015·2019-08-30 12:57
閱讀 1376·2019-08-29 16:22