您好,登錄后才能下訂單哦!
這篇文章主要講解了“C語言靜態與動態通訊錄的實現方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言靜態與動態通訊錄的實現方法是什么”吧!
在我們學習完C語言的結構體、指針以及動態內存管理之后,我們就可以實現一些有意思的小項目了,通過這些小項目可以加深我們對于相關知識的理解。
靜態通訊錄主要要求有
靜態大小,可以記錄10個人的信息(大小自己定)
記錄的信息如下:名字、性別、年齡、電話、住址
可以實現聯系人的增刪查改
為了方便代碼的管理和維護,我們分文件實現以上的要求
contact.h 用于聲明相關的接口
contact.c 用于實現相關的接口
test.c 用于測試相關的接口
在contact.h中,我們統一用預處理指令來確定好通訊錄的大小,以及每一個聯系人信息的范圍大小,方便后續的修改
在確定好范圍后,我們通過定義結構體類型的方式來實現對數據的統一管理
結構體類型確定后,就是相關接口的聲明了
//首先引入需要用到的頭文件 #include<stdio.h> #include<stdlib.h> #include<string.h> //確定每一個聯系人名字、電話等信息的范圍大小 #define MAX_NAME 10 #define MAX_PHONE 20 #define MAX_ADDR 25 // 確定通訊錄的總大小 #define MAX_CAPACITY 10 //由于每一個聯系人都有多個信息,因此需要定義一個結構體類型來管理 //定義聯系人相關信息的結構體 typedef struct PeoInfo { char name[MAX_NAME]; char sex; int age; char phone[MAX_PHONE]; char address[MAX_ADDR]; }peo; //通訊錄內包含多個成員,因此也需要統一管理,所以還是使用結構體 //定義一個通訊錄結構體,管理通訊錄和記錄有效聯系人個數信息 typedef struct Contact { peo data[MAX_CAPACITY];//這里是一個數組,數組的每一個元素都是一個結構體 int size; }con; //------------------------------------------------------ //以下是相關接口的聲明 //菜單接口 void menu(); //對結構體變量進行初始化 void InitContact(con* con); //打印通訊錄信息 void Print(con* con); //實現增加聯系人的接口 void AddContact(con* con); //實現刪除聯系人的接口 void DelContact(con* con); //實現查找聯系人的接口 void SearchContact(con* con); //實現修改聯系人的接口 void ModifyContact(con* con);
contact.c是整個項目的關鍵,需要對相關接口進行定義
//通訊錄各個接口的實現 //首先引入.h文件 #include"Contact.h" //菜單接口 void menu() { printf("*******************************\n"); printf("********靜態簡易通訊錄*********\n"); printf("******* 0.退出通訊錄 ******\n"); printf("******* 1.增加聯系人 ******\n"); printf("******* 2.刪除聯系人 ******\n"); printf("******* 3.查找聯系人 ******\n"); printf("******* 4.修改聯系人 ******\n"); printf("******* 5.打印聯系人 ******\n"); printf("*******************************\n"); printf("\n"); } //對結構體變量進行初始化 void InitContact(con* con) { //結構體的初始化一般用memset //我們首先讓通訊錄結構體變量的數組一開始為0 memset(con->data, 0, sizeof(con->data)); con->size = 0;//同時由于此時一個聯系人的信息都沒有,所以size也是0 } //打印通訊錄信息 void Print(con* con){ int i = 0; if (con->size == 0) { printf("暫無可打印信息\n"); return ; } printf("name\tsex\tage\tphone\taddress\n"); for (i = 0; i < con->size; i++) { printf("%s\t%c\t%d\t%s\t%s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].phone, con->data[i].address); } } //實現增加聯系人的接口 void AddContact(con* con) { if (con->size == MAX_CAPACITY) { printf("容量已滿,無法增加\n"); return; } printf("請輸入姓名:\n"); scanf("%s", con->data[con->size].name); getchar(); printf("請選擇性別:(m表示男,w表示女)\n"); scanf("%c", &(con->data[con->size].sex)); printf("請輸入年齡:\n"); scanf("%d", &(con->data[con->size].age)); printf("請輸入手機號碼:\n"); scanf("%s", con->data[con->size].phone); printf("請輸入住址:\n"); scanf("%s", con->data[con->size].address); con->size++; } //實現刪除聯系人的接口 void DelContact(con* con) { if (con->size == 0) { printf("暫無可以刪除的信息"); return; } printf("請輸入你要刪除的聯系人的姓名:\n"); char name[MAX_NAME] = {0}; scanf("%s", name); int i = 0; for (i = 0; i < con->size; i++) { if (strcmp(name, (con->data)[i].name) == 0) { int j = 0; for (j = i; j < con->size - 1; j++) { memmove(&(con->data[j]), &(con->data[j + 1]), sizeof(con->data[0])); } con->size--; return; } } printf("你輸入的聯系人不存在\n"); } //實現查找聯系人的接口 void SearchContact(con* con) { if (con->size == 0) { printf("暫無查找的信息"); return; } printf("請輸入你要查找的聯系人的姓名:\n"); char name[MAX_NAME] = { 0 }; scanf("%s", name); int i = 0; for (i = 0; i < con->size; i++) { if (strcmp(name, (con->data)[i].name) == 0) { printf("%s\t%c\t%d\t%s\t%s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].phone, con->data[i].address); return; } } printf("你想要查找的聯系人不存在\n"); } //實現修改聯系人的接口 void ModifyContact(con* con) { if (con->size == 0) { printf("暫無可以修改的信息"); return; } printf("請輸入你要修改的聯系人的姓名:\n"); char name[MAX_NAME] = { 0 }; scanf("%s", name); int i = 0; for (i = 0; i < con->size; i++) { if (strcmp(name, (con->data)[i].name) == 0) { printf("請重新輸入姓名:\n"); scanf("%s", con->data[i].name); getchar(); printf("請重新選擇性別:(m表示男,w表示女)\n"); scanf("%c", &(con->data[i].sex)); printf("請重新輸入年齡:\n"); scanf("%d", &(con->data[i].age)); printf("請重新輸入手機號碼:\n"); scanf("%s", con->data[i].phone); printf("請重新輸入住址:\n"); scanf("%s", con->data[i].address); return; } } printf("你想要修改的聯系人不存在\n"); }
提示
我們在實現接口的時候,如果形參傳入的是指針,一般都需要先判斷一下傳入的指針是否為空指針,以免造成非法訪問,但是由于我的疏忽,就沒有寫上去了!
test.c就是用來測試相關接口的文件,可以根據自己的想法來設定
#include"Contact.h" int main() { //創建結構體并且初始化 con c; InitContact(&c); menu(); int input = 0; while (1) { printf("請輸入你的選擇:\n"); scanf("%d", &input); switch (input) { case 1: AddContact(&c); break; case 2: DelContact(&c); break; case 3: SearchContact(&c); break; case 4: ModifyContact(&c); break; case 5: Print(&c); break; case 0: printf("退出通訊錄\n"); break; default: printf("你的輸入有誤,請重新選擇\n"); break; } if (input == 0) { break; } } return 0; }
靜態通訊錄有一個缺點,那就是通訊錄的大小,也就是只能存儲的聯系人是要求確定大小的,大小給多了浪費空間,給少了又不夠用。
動態通訊錄就是通過動態內存管理的函數來實現動態開辟空間大小,以滿足需要的。
//動態版本通訊錄的實現 #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX_NAME 15 #define MAX_PHONE 15 #define MAX_ADDR 25 //給定通訊錄默認大小為5,不夠可以增容 #define DefaultSize 5 //聯系人結構體的聲明 typedef struct PeoInfo { char name[MAX_NAME]; char sex; short age; char phone[MAX_PHONE]; char addr[MAX_ADDR]; }peo; //通訊錄結構體的聲明 typedef struct Contact { peo* p;//我們通過指針的方式來管理聯系人數組 int capacity; int size; }con; //菜單函數 void menu(); //初始化通訊錄 void InitCon(con* c); //銷毀通訊錄 void DestoryCon(con* c); //檢查容量的接口 void CheckCapacity(con* c); //打印聯系人信息 void Print(con* c); //聯系人的增加 void AddCon(con* c); //聯系人的刪除 void DelCon(con* c); //聯系人的查找 void SearchCon(con* c); //聯系人的修改 void ModifyCon(con* c); //------------------------------------------- //下面是我通過快排的原理,手寫的快排來實現一下通過聯系人名字和年齡排序的接口 //通過名字來排序 void SortByname(con* c); //通過年齡來排序 void SortByage(con* c); void Swap(char* p1, char* p2, int width); void QSort(void* p, int num, int width, int(*cmp)(const void* , const void* )); int cmpbyname(const void* p1,const void* p2); int cmpbyage(const void* p1,const void* p2);
關鍵接口的實現和靜態通訊錄的大同小異,只不過我們需要多定義一個檢查空間的接口
每次增加聯系人的時候,就調用這個接口,做到滿了就增容
其中增容接口使用的時realloc函數
#include"contact.h" //菜單函數 void menu() { printf("******************************************\n"); printf("************* 動態版通訊錄 ***********\n"); printf("************* 1.增加聯系人 ***********\n"); printf("************* 2.刪除聯系人 ***********\n"); printf("************* 3.查找聯系人 ***********\n"); printf("************* 4.修改聯系人 ***********\n"); printf("************* 5.按名字排序 ***********\n"); printf("************* 6.按年齡排序 ***********\n"); printf("************* 7.打印聯系人 ***********\n"); printf("************* 0.退出通訊錄 ***********\n"); printf("******************************************\n"); } //初始化通訊錄 void InitCon(con* c) { //這里也可以用relloc函數來初始化,這樣的話就會有初始值 c->p = (con*)malloc(DefaultSize * sizeof(peo)); c->capacity = DefaultSize; c->size = 0; } //銷毀通訊錄 void DestoryCon(con* c) { free(c->p); c->p = NULL; c->capacity = 0; c->size = 0; } //檢查容量的接口 void CheckCapacity(con* c) { if (c->capacity == c->size) { //每次增容二倍 peo* tmp = (peo*)realloc(c->p, 2 * (c->capacity) * sizeof(peo)); if (tmp != NULL) { c->p = tmp; c->capacity = 2 * c->capacity; printf("增容成功\n"); } else { printf("增容失敗\n"); exit(1); } } } //打印聯系人信息 void Print(con* c) { if (c->size == 0) { printf("暫無可以打印的信息\n"); return; } printf("name\tsex\tage\tphone\taddress\n"); int i = 0; for (i = 0; i < c->size; i++) { printf("%s\t%c\t%d\t%s\t%s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].phone, c->p[i].addr); } } //聯系人的增加 void AddCon(con* c) { //每一次增加聯系人都要先檢查容量是否足夠 CheckCapacity(c); printf("請輸入名字:>\n"); scanf("%s", c->p[c->size].name); getchar(); printf("請輸入性別:>(m表示男,w表示女)\n"); scanf("%c", &(c->p[c->size].sex)); printf("請輸入年齡:>\n"); scanf("%d", &(c->p[c->size].age)); printf("請輸入電話:>\n"); scanf("%s", c->p[c->size].phone); printf("請輸入地址:>\n"); scanf("%s", c->p[c->size].addr); c->size++; printf("添加成功\n"); } //聯系人的刪除 void DelCon(con* c) { printf("請輸入你想要刪除的聯系人的名字\n"); char name[MAX_NAME]; scanf("%s", name); int i = 0; for (i = 0; i < c->size; i++) { if (strcmp(name, c->p[i].name) == 0) { int j = i; for (j = i; j < c->size - 1; j++) { memmove(&(c->p[j]), &(c->p[j + 1]), sizeof(c->p[0])); } c->size--; return; } } printf("你想要刪除的聯系人不存在\n"); } //聯系人的查找 void SearchCon(con* c) { printf("請輸入你想要查找的人的名字:\n"); char name[MAX_NAME]; scanf("%s", name); int i = 0; for (i = 0; i < c->size; i++) { if (strcmp(name, c->p[i].name) == 0) { printf("%s\t%c\t%d\t%s\t%s\n", c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].phone, c->p[i].addr); return; } } printf("你想要查找的聯系人不存在\n"); } //聯系人的修改 void ModifyCon(con* c) { printf("請輸入你想要修改的人的名字:\n"); char name[MAX_NAME]; scanf("%s", name); int i = 0; for (i = 0; i < c->size; i++) { if (strcmp(name, c->p[i].name) == 0) { printf("請重新輸入名字:>\n"); scanf("%s", c->p[i].name); getchar(); printf("請重新輸入性別:>(m表示男,w表示女)\n"); scanf("%c", &(c->p[i].sex)); printf("請重新輸入年齡:>\n"); scanf("%d", &(c->p[i].age)); printf("請重新輸入電話:>\n"); scanf("%s", c->p[i].phone); printf("請重新輸入地址:>\n"); scanf("%s", c->p[i].addr); return; } } printf("你想要修改的聯系人不存在\n"); } //通過名字來排序 void SortByname(con* c) { QSort(c->p, c->size, sizeof(c->p[0]),cmpbyname ); } //通過年齡來排序 void SortByage(con* c) { QSort(c->p, c -> size, sizeof(c->p[0]), cmpbyage); }
這是我根據快速排序的原理,手寫的快速排序
#include"contact.h" //快排的交換函數 void Swap(char* p1, char* p2, int width) { int i = 0; for (i = 0; i < width; i++) { char tmp = *p1; *p1 = *p2; *p2 = tmp; p1++; p2++; } } //手寫快排來進行通訊錄排序 void QSort(void* p, int num, int width, int(*cmp)(const void*, const void*)) { int i = 0; for (i = 0; i < num - 1; i++) { int j = 0; for (j = 0; j < num - 1 - i; j++) { if (cmp((char*)p + j * width, (char*)p + (j + 1) * width) > 0) { Swap((char*)p + j * width, (char*)p + (j + 1) * width, width); } } } } int cmpbyage(const void* p1, const void* p2) { return (*(peo*)p1).age - (*(peo*)p2).age; } int cmpbyname(const void* p1, const void* p2) { return strcmp(((peo*)p1)->name,((peo*)p2)->name); }
test.c用于測試相關的接口,可以根據自己的想法來測試
#include"contact.h" int main() { menu(); int input = 0; con c; InitCon(&c); while (1) { printf("請輸入你的選擇:\n"); scanf("%d", &input); switch (input) { case 1: AddCon(&c); break; case 2: DelCon(&c); break; case 3: SearchCon(&c); break; case 4: ModifyCon(&c); break; case 5: SortByname(&c); break; case 6: SortByage(&c); break; case 7: Print(&c); break; case 0: printf("退出通訊錄\n"); break; } if (input == 0) { DestoryCon(&c); break; } } return 0; }
感謝各位的閱讀,以上就是“C語言靜態與動態通訊錄的實現方法是什么”的內容了,經過本文的學習后,相信大家對C語言靜態與動態通訊錄的實現方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。