C語(yǔ)言使用realloc函數(shù)實(shí)現(xiàn)通訊錄源碼分析
一、ContactInit初始化
void ContactInit(Contact* ps)//初始化 { ps->size = 0; ps->capacity = 0; ps->data = NULL; }
初始化的時(shí)候,就不再使用memset函數(shù)了,因?yàn)槭侵羔?,所以要先把size,capacity置為0,data置為空。
二、ContactCheckCapacity檢查通訊錄內(nèi)存是否夠用
void ContactCheckCapacity(Contact* pc)//檢查通訊錄內(nèi)存是否夠用 { if (pc->size == pc->capacity) { int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2; Cont* tmp = (Cont*)realloc(pc->data, newcapacity * sizeof(Cont) * 4); if (tmp == NULL) { perror("realloc"); exit(-1); } pc->data = tmp; pc->capacity = newcapacity; printf("增容成功\n"); } }
當(dāng)size == capacity的時(shí)候,就證明通訊錄的內(nèi)存不夠了,需要增容,在這里直接用的realloc函數(shù)進(jìn)行增容。
三、ContactDistory釋放動(dòng)態(tài)開(kāi)辟的空間
void ContactDistory(Contact* pc)//釋放動(dòng)態(tài)開(kāi)辟的空間 { free(pc->data); pc->data = NULL; pc->capacity = pc->size = 0; }
使用動(dòng)態(tài)內(nèi)存分配的函數(shù)了之后,在退出通訊錄的時(shí)候,不要忘記把開(kāi)辟的空間給銷(xiāo)毀,不然會(huì)造成內(nèi)存泄漏。
四、源碼
.h文件
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #define MAX_SIZE 1000 #define MAX_NAME 5 #define MAX_TELE 100 #define MAX_SEX 5 #define MAX_ADDRESS 50 typedef struct Contact { char name[MAX_NAME]; int age; char sex[MAX_SEX]; char tele[MAX_TELE]; char address[MAX_ADDRESS]; }Cont; typedef struct C { Cont *data; int size; int capacity; }Contact; void ContactInit(Contact* ps);//初始化 void ContactAdd(Contact* ps);//添加聯(lián)系人 void ContactDel(Contact* ps);//刪除聯(lián)系人 void ContactShow(Contact* ps);//展示聯(lián)系人 void ContactFind(Contact* ps);//查找聯(lián)系人 void ContactSort(Contact* ps);//給聯(lián)系人排序 void ContactModify(Contact* ps);//修改聯(lián)系人 void ContactCheckCapacity(Contact* pc);//檢查通訊錄內(nèi)存是否夠用 void ContactDistory(Contact* pc);//釋放動(dòng)態(tài)開(kāi)辟的空間
.c文件
#include "contact.h" void ContactInit(Contact* ps)//初始化 { ps->size = 0; ps->capacity = 0; ps->data = NULL; } void ContactCheckCapacity(Contact* pc)//檢查通訊錄內(nèi)存是否夠用 { if (pc->size == pc->capacity) { int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2; Cont* tmp = (Cont*)realloc(pc->data, newcapacity * sizeof(Cont) * 4); if (tmp == NULL) { perror("realloc"); exit(-1); } pc->data = tmp; pc->capacity = newcapacity; printf("增容成功\n"); } } void ContactDistory(Contact* pc)//釋放動(dòng)態(tài)開(kāi)辟的空間 { free(pc->data); pc->data = NULL; pc->capacity = pc->size = 0; } void ContactAdd(Contact* ps)//添加聯(lián)系人 { assert(ps); ContactCheckCapacity(ps); //增加一個(gè)人的信息 printf("請(qǐng)輸入名字:>"); scanf("%s", ps->data[ps->size].name); printf("請(qǐng)輸入年齡:>"); scanf("%d", &(ps->data[ps->size].age)); printf("請(qǐng)輸入性別:>"); scanf("%s", ps->data[ps->size].sex); printf("請(qǐng)輸入地址:>"); scanf("%s", ps->data[ps->size].address); printf("請(qǐng)輸入電話:>"); scanf("%s", ps->data[ps->size].tele); ps->size++; } int FindByName(Contact* ps,const char *str) { int pos = 0; while (pos < ps->size) { if (strcmp(ps->data[pos].name, str) == 0) { return pos; } pos++; } return -1; } void ContactFind(Contact* ps)//查找聯(lián)系人 { assert(ps); printf("請(qǐng)輸入要查找的聯(lián)系人的姓名:"); char na[MAX_NAME]; scanf("%s", na); int ret = FindByName(ps, na); if (ret == -1) { printf("查無(wú)此人\n"); return; } printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年齡", "性別", "電話", "地址"); printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ps->data[ret].name, ps->data[ret].age, ps->data[ret].sex, ps->data[ret].tele, ps->data[ret].address); return ; } void ContactDel(Contact* ps)//刪除聯(lián)系人 { assert(ps); printf("請(qǐng)輸入要?jiǎng)h除的聯(lián)系人的姓名:"); char na[MAX_NAME]; scanf("%s", na); int ret = FindByName(ps, na); if (ret == -1) { printf("信息錯(cuò)誤,列表無(wú)該聯(lián)系人\n"); return; } else { for (int i = ret; i < ps->size - 1; i++) { ps->data[i] = ps->data[i + 1]; } } ps->size--; return; } void ContactShow(Contact* ps)//展示聯(lián)系人 { int i = 0; printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年齡", "性別", "電話", "地址"); for (i = 0; i < ps->size; i++) { printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ps->data[i].name, ps->data[i].age, ps->data[i].sex, ps->data[i].tele, ps->data[i].address); } } int CmpByName(const void* a,const void* b) { return strcmp(((Contact*)a)->data->name, ((Contact*)b)->data->name); } //return strcmp(((S*)a)->name, ((S*)b)->name); void ContactSort(Contact* ps)//給聯(lián)系人排序 { assert(ps); qsort(ps->data[0].name, ps->size, sizeof ps->data[0], CmpByName); printf("排序成功\n"); return; } void ContactModify(Contact* ps)//修改聯(lián)系人 { assert(ps); printf("請(qǐng)輸入要修改的聯(lián)系人的姓名:"); char na[MAX_NAME]; scanf("%s", na); int ret = FindByName(ps, na); if (ret == -1) { printf("查無(wú)此人,無(wú)法修改\n"); return; } printf("請(qǐng)輸入名字:>"); scanf("%s", ps->data[ret].name); printf("請(qǐng)輸入年齡:>"); scanf("%d", &(ps->data[ret].age)); printf("請(qǐng)輸入性別:>"); scanf("%s", ps->data[ret].sex); printf("請(qǐng)輸入地址:>"); scanf("%s", ps->data[ret].address); printf("請(qǐng)輸入電話:>"); scanf("%s", ps->data[ret].tele); printf("修改成功\n"); return; }
test.c文件
#include "contact.h" void menu() { printf("************************************\n"); printf("****** 1. 添加 2. 刪除 ******\n"); printf("****** 3. 查找 4. 修改 ******\n"); printf("****** 5. 展示 6. 排序 ******\n"); printf("****** 7.退出 ******\n"); printf("************************************\n"); } enum Function { ADD = 1, DEL, FIND, MODIFY, SHOW, SORT, EXIT }; int main() { int input = 0; Contact con; ContactInit(&con); do { menu(); printf("請(qǐng)輸入選項(xiàng):"); scanf("%d", &input); switch (input) { case ADD: ContactAdd(&con); break; case DEL: ContactDel(&con); break; case FIND: ContactFind(&con); break; case MODIFY: ContactModify(&con); break; case SHOW: ContactShow(&con); break; case SORT: ContactSort(&con); break; case EXIT: ContactDistory(&con); printf("退出\n"); break; default: printf("輸入錯(cuò)誤,請(qǐng)重新出入\n"); break; } } while (input != 7); return 0; }
到此這篇關(guān)于C語(yǔ)言使用realloc函數(shù)實(shí)現(xiàn)通訊錄源碼分析的文章就介紹到這了,更多相關(guān)C語(yǔ)言通訊錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt一個(gè)進(jìn)程運(yùn)行另一個(gè)進(jìn)程的實(shí)現(xiàn)方法
本文主要介紹了Qt一個(gè)進(jìn)程運(yùn)行另一個(gè)進(jìn)程的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04詳解QTreeWidget隱藏節(jié)點(diǎn)的兩種方式
本文主要介紹了QTreeWidget隱藏節(jié)點(diǎn)的兩種方式,一種是直接隱藏,一種是間接隱藏,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++實(shí)現(xiàn)LeetCode(135.分糖果問(wèn)題)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(135.分糖果問(wèn)題),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言putenv()函數(shù)和getenv()函數(shù)的使用詳解
這篇文章主要介紹了C語(yǔ)言putenv()函數(shù)和getenv()函數(shù)的使用詳解,用來(lái)進(jìn)行環(huán)境變量的相關(guān)操作,需要的朋友可以參考下2015-09-09CMake 生成靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的方法步驟
本文主要介紹了CMake 生成靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06C++?std::copy與memcpy區(qū)別小結(jié)
本文主要介紹了C++?std::copy與memcpy區(qū)別小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05