C語言編程動態內存開辟實現升級版通訊錄教程示例
前言
所謂動態內存開辟的通訊錄,就是我需要多少聯系人,就給多少聯系人,防止給定一個聯系人上限,需要增加聯系人無法擴容,而聯系人沒有上限那麼多又會造成內存浪費。
本文繼之前的靜態通訊錄作出改進,有興趣的同學可以看看之前的文章:C語言實現靜態通訊錄
一、存放聯系人信息
這裡是用struct PeoInfodata結構體指針指向通訊錄,而不再直接 struct PeoInfo data[Max]
用結構體數組定義通訊錄容量大小,其他都和之前的靜態通訊錄一樣
多種信息描述用結構體(struct PeoInfodata是動態,struct PeoInfo data[Max]是靜態)
#define Name_max 20 #define Sex_max 5 #define Tele_max 12 #define Addr_max 30 #define Max 1000 //用#define定義是為瞭方便將來如果需要對數組大小增減,直接改#define這裡的即可 struct PeoInfo { char name[Name_max];//姓名 int age;//年齡 char sex[Sex_max];//性別 char tele[Tele_max];//電話號碼 char addr[Addr_max];//地址 };//聲明一個通訊錄結構體類型 struct Contact { struct PeoInfo*data; int sz;//記錄已有聯系人數目 int capacity;//當前通訊錄最大容量,將來如果不夠可以自動擴容 };//struct Contact是一種結構體類型,它裡面可以存放其他類型,而struct PoeInfo也是一種類型,自然是可以存放的
二、通訊錄初始化
我們先來看一下,動態通訊錄運行原理:
我們聯系人結構體創建好之後data(結構體指針)這個成員是沒有指向一塊具體空間的,我們用初始化函數申請一塊空間,然後讓data指向那塊空間,假設我們現在開辟三塊空間
(開辟空間數由memset(pc->data, 0, Max * sizeof(struct PeoInfo));這句代碼中的Max控制,比如我現在是開辟3塊空間就把Max改成3即可)
(圖片來自比特就業課)
開辟完空間後,capacity(當前通訊錄最大容量)即是3,但是我們現在沒有放有效聯系人,所以sz(已有聯系人數目)還是0
當你放入一個聯系人張三的信息,sz變為1
再放入一個聯系人李四的信息,sz變為2,然後再放入聯系人王五的信息,sz變為3。後面的以此類推
代碼如下(示例):
#define Default_sz 3//默認初始聯系人容量為3 //這裡#define定義是方便其他使用者將來如果不想初始容量為3,可以直接在#define這裡修改 void InitContact(struct Contact*pc) { pc->sz = 0; pc->data = (struct PeoInfo*)malloc(Default_sz * sizeof(struct PeoInfo)); pc->capacity = Default_sz; }
一個聯系人結構體占用空間大小是sizeof(struct PeoInfo),我們這裡是初始給3個聯系人結構體大小空間(後面不夠再自動擴),你也可以用其他數字代替,malloc開辟出空間後,是返回值類型為void*,我們需要的pc->data是struct PeoInfo*型,我們強制轉換一下,然後開辟出來的空間會由struct PeoInfo *型的指針進行管理。
三、增加聯系人
void AddContact(struct Contact*pc)//動態增加聯系人 { if (pc->sz == pc->capacity) { //容量已達上限,如果增加聯系人需擴容 struct PeoInfo* ptr= (struct PeoInfo*)realloc(pc->data, (pc->capacity + 2)*sizeof(struct PeoInfo));//追加空間函數,詳情見筆者動態內存分配文章 //realloc第二個參數是字節為單位,pc->capacity + 2是容量個數,sizeof(struct PeoInfo)是每個聯系人結構體所占空間 if (ptr != NULL)//realloc函數有可能開辟空間失敗,失敗會返回空指針 { pc->data = ptr; pc->capacity += 2;//我們以每次增容+2為例,你也可以換其他數字 printf("增容成功\n"); } else//返回空指針說明開辟失敗 { return;//開辟失敗就結束程序 } } printf("請輸入聯系人姓名:\n"); scanf("%s", pc->data[pc->sz].name); //pc->data是結構體指針,我們之前很多文字說過一個知識點,假設a是一個指針,*(a+n)=a[n] //pc->data[pc->sz]=*(pc->data+pc->sz) printf("請輸入聯系人年齡:\n"); scanf("%d", &(pc->data[pc->sz].age)); //這裡年齡和前面的名字有什麼區別? //name在結構體裡是一個數組,數組單獨出現可以看成數組首元素地址,age是一個整形,要&進行取地址操作 printf("請輸入聯系人性別:\n"); scanf("%d", (pc->data[pc->sz].sex)); printf("請輸入聯系人電話:\n"); scanf("%d", (pc->data[pc->sz].tele)); printf("請輸入聯系人地址:\n"); scanf("%d", (pc->data[pc->sz].addr)); printf("該聯系人已添加\n"); pc->sz++;//添加完後,聯系人數目+1 }
四、銷毀通訊錄
void DestoryContact(struct Contact*pc) { free(pc->data); pc->data = NULL; pc->capacity = 0; pc->sz = 0; }
因為我們通訊錄是用結構體指針malloc出來的嘛,不再需要通訊錄我們就用free函數把那塊空間還給操作系統,然後要記得把指針置為空指針(就比如你去賓館,退房要把鑰匙還給賓館)
後記
對於靜態通訊錄改動態通訊錄也就是改一下它的初始化、增加聯系人(類比靜態通訊錄沒有上限,也避免浪費空間),還有通訊錄銷毀的一些小改動,對於完整通訊錄還有查找、刪除、修改、顯示聯系人等操作函數,但由於和靜態沒有改動,讀者可自行查看筆者以前的通訊錄文章 。
以上就是C語言編程動態內存開辟實現升級版通訊錄教程示例的詳細內容,更多關於C語言實現通訊錄的資料請關註WalkonNet其它相關文章!