C/C++實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的示例詳解
動(dòng)態(tài)數(shù)組相比于靜態(tài)數(shù)組具有更大的靈活性,因?yàn)槠浯笮】梢栽谶\(yùn)行時(shí)根據(jù)程序的需要?jiǎng)討B(tài)地進(jìn)行分配和調(diào)整,而不需要在編譯時(shí)就確定數(shù)組的大小。這使得動(dòng)態(tài)數(shù)組非常適合于需要?jiǎng)討B(tài)添加或刪除元素的情況,因?yàn)樗鼈兛梢栽诓焕速M(fèi)空間的情況下根據(jù)需要?jiǎng)討B(tài)增加或減少存儲(chǔ)空間。
動(dòng)態(tài)數(shù)組的內(nèi)存空間是從堆(heap)上分配的,動(dòng)態(tài)數(shù)組需要程序員手動(dòng)管理內(nèi)存,因?yàn)樗鼈兊膬?nèi)存空間是在程序運(yùn)行時(shí)動(dòng)態(tài)分配的。程序員需要在使用完動(dòng)態(tài)數(shù)組后手動(dòng)釋放其內(nèi)存空間,否則可能會(huì)導(dǎo)致內(nèi)存泄漏的問(wèn)題,進(jìn)而導(dǎo)致程序崩潰或者運(yùn)行緩慢。因此,在使用動(dòng)態(tài)數(shù)組時(shí),程序員需要特別注意內(nèi)存管理的問(wèn)題。
讀者需自行創(chuàng)建頭文件dynamic.h
并拷貝如下動(dòng)態(tài)數(shù)組代碼實(shí)現(xiàn);
#include <stdlib.h> #include <string.h> struct DynamicArray { void **addr; // 存放元素或結(jié)構(gòu)體的首地址 int curr_size; // 存放當(dāng)前元素?cái)?shù)量 int max_size; // 存放當(dāng)前最大元素?cái)?shù) }; // 初始化動(dòng)態(tài)數(shù)組,初始化后直接返回?cái)?shù)組的首地址 struct DynamicArray *InitDynamicArray(int size) { // 如果小于0則說(shuō)明沒(méi)有元素,返回NULL if (size <= 0) { return NULL; } // 分配結(jié)構(gòu)指針,此處分配的是結(jié)構(gòu)體指針,并沒(méi)有分配空間 struct DynamicArray *ptr = malloc(sizeof(struct DynamicArray)); if (ptr != NULL) { // 將當(dāng)前元素索引設(shè)置為0 ptr->curr_size = 0; // 默認(rèn)最大數(shù)組元素?cái)?shù)為size ptr->max_size = size; // 實(shí)際分配存儲(chǔ)空間大小是max_size最大元素 ptr->addr = malloc(sizeof(void *) * ptr->max_size); return ptr; } return NULL; } // 將元素插入到指定位置 void InsertDynamicArray(struct DynamicArray *ptr, int index, void *data) { // 判斷如果數(shù)組不為空,或者是data不為空,則繼續(xù)執(zhí)行 if (ptr != NULL || data != NULL) { // 如果插入位置小于當(dāng)前0,或者大于當(dāng)前元素總個(gè)數(shù) if (index < 0 || index > ptr->curr_size) { // 就自動(dòng)把它插入到元素的末尾位置 index = ptr->curr_size; } // 緊接著判斷當(dāng)前元素?cái)?shù)是否大于最大值,大于則分配空間 if (ptr->curr_size >= ptr->max_size) { // 分配一塊更大的空間,這里分配原始空間的2倍 int new_max_size = ptr->max_size * 2; void **new_space = malloc(sizeof(void *) * new_max_size); // 接著將原來(lái)空間中的數(shù)據(jù)拷貝到新分配的空間 memcpy(new_space, ptr->addr, sizeof(void *) * ptr->max_size); // 釋放原來(lái)的內(nèi)存空間,并更新指針的指向?yàn)樾驴臻g的地址 free(ptr->addr); ptr->addr = new_space; ptr->max_size = new_max_size; } // 開(kāi)始移動(dòng)元素,給ins元素騰出空來(lái) for (int x = ptr->curr_size - 1; x >= index; --x) { // 從后向前,將前一個(gè)元素移動(dòng)到后一個(gè)元素上 ptr->addr[x + 1] = ptr->addr[x]; } // 設(shè)置好指針以后,開(kāi)始賦值 ptr->addr[index] = data; ptr->curr_size++; return 1; } return 0; } // 遍歷數(shù)組中的元素,這里的回調(diào)函數(shù)是用于強(qiáng)制類(lèi)型轉(zhuǎn)換,自定義輸出時(shí)使用 void ForeachDynamicArray(struct DynamicArray *ptr, void(*_callback)(void *)) { if (ptr != NULL || _callback != NULL) { for (int x = 0; x < ptr->curr_size; x++) { // 調(diào)用回調(diào)函數(shù)并將數(shù)組指針傳遞過(guò)去 _callback(ptr->addr[x]); } } } // 根據(jù)位置刪除指定元素,index = 元素的下標(biāo)位置 void RemoveByPosDynamicArray(struct DynamicArray *ptr, int index) { if (ptr == 0) return 0; // 判斷當(dāng)前插入位置index必須大于0且小于curr_size if (index > 0 || index < ptr->curr_size - 1) { for (int i = index; i < ptr->curr_size - 1; ++i) { // 每次循環(huán)都將后一個(gè)元素覆蓋到前一個(gè)元素上 ptr->addr[i] = ptr->addr[i + 1]; } // 最后當(dāng)前元素?cái)?shù)量應(yīng)該減去1 ptr->curr_size--; } } // 按照元素的指定值進(jìn)行元素刪除,這里需要回調(diào)函數(shù)指定要?jiǎng)h除元素的值是多少 void RemoveByValueDynamicArray(struct DynamicArray *ptr, void *data, int(*compare)(void*, void *)) { if (ptr != NULL && data != NULL && compare != NULL) { for (int i = 0; i < ptr->curr_size; ++i) { if (compare(ptr->addr[i], data)) { RemoveByPos_DynamicArray(ptr, i); break; } } } } // 銷(xiāo)毀數(shù)組 void DestroyDynamicArray(struct DynamicArray *ptr) { if (ptr != NULL) { if (ptr->addr != NULL) { free(ptr->addr); ptr->addr = NULL; } free(ptr); ptr = NULL; } }
上述代碼的使用很容易,如下代碼實(shí)現(xiàn)了動(dòng)態(tài)數(shù)組的基本操作,包括創(chuàng)建動(dòng)態(tài)數(shù)組、插入元素、刪除元素、遍歷元素和銷(xiāo)毀動(dòng)態(tài)數(shù)組。其中定義了一個(gè)自定義結(jié)構(gòu)體Student
,用于作為動(dòng)態(tài)數(shù)組的元素。在使用InitDynamicArray
函數(shù)創(chuàng)建動(dòng)態(tài)數(shù)組之后,使用InsertDynamicArray
函數(shù)將四個(gè)元素插入到動(dòng)態(tài)數(shù)組中,其中第三個(gè)元素插入的位置為3
。然后使用RemoveByPosDynamicArray
函數(shù)根據(jù)下標(biāo)移除第一個(gè)元素,使用RemoveByValueDynamicArray
函數(shù)根據(jù)元素的值移除第二個(gè)元素,其中使用myCompare
回調(diào)函數(shù)對(duì)比元素。最后使用ForeachDynamicArray
函數(shù)遍歷所有元素,并使用MyPrint
回調(diào)函數(shù)輸出元素的值。最終銷(xiāo)毀動(dòng)態(tài)數(shù)組,釋放內(nèi)存。
#include "dynamic.h" // 自定義結(jié)構(gòu)體 struct Student { int uid; char name[64]; int age; }; // 回調(diào)函數(shù)用于輸出元素 void MyPrint(void *data) { // 強(qiáng)制類(lèi)型轉(zhuǎn)換,轉(zhuǎn)成我們想要的類(lèi)型 struct Student *ptr = (struct Student *)data; printf("Uid: %d --> Name: %s \n", ptr->uid, ptr->name); } // 回調(diào)函數(shù)用于對(duì)比元素 int myCompare(void *x, void *y) { struct Student *p1 = (struct Student *)x; struct Student *p2 = (struct Student *)y; if (strcmp(p1->name, p2->name) == 0) { return 1; } return 0; } int main(int argc, char *argv[]) { //創(chuàng)建動(dòng)態(tài)數(shù)組 struct DynamicArray *ptr = InitDynamicArray(5); // 創(chuàng)建元素 struct Student stu1 = { 1001, "admin1", 22 }; struct Student stu2 = { 1002, "admin2", 33 }; struct Student stu3 = { 1003, "admin3", 44 }; struct Student stu4 = { 1004, "admin4", 55 }; // 將元素插入到數(shù)組 InsertDynamicArray(ptr, 0, &stu1); InsertDynamicArray(ptr, 1, &stu2); InsertDynamicArray(ptr, 3, &stu3); InsertDynamicArray(ptr, 4, &stu4); // 根據(jù)下標(biāo)移除元素 RemoveByPosDynamicArray(ptr, 0); // 刪除元素是p_delete的數(shù)據(jù) struct Student p_delete = { 1002, "admin2", 33 }; RemoveByValueDynamicArray(ptr, &p_delete, myCompare); // 遍歷元素 ForeachDynamicArray(ptr, MyPrint); // 銷(xiāo)毀順序表 DestroyDynamicArray(ptr); system("pause"); return 0; }
到此這篇關(guān)于C/C++實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的示例詳解的文章就介紹到這了,更多相關(guān)C++動(dòng)態(tài)數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++之std::vector刪除元素的幾種方式及區(qū)別說(shuō)明
這篇文章主要介紹了C++之std::vector刪除元素的幾種方式及區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Qt實(shí)現(xiàn)編寫(xiě)SMTP客戶(hù)端的示例詳解
這篇文章主要介紹了如何通過(guò)Qt實(shí)現(xiàn)編寫(xiě)SMTP客戶(hù)端,可以實(shí)現(xiàn)通過(guò)SMTP發(fā)送電子郵件(有文本,html,附件,內(nèi)聯(lián)文件等的MIME)。并支持SSL和SMTP身份驗(yàn)證,感興趣的可以學(xué)習(xí)一下2022-11-11Visual Studio2019調(diào)試DLL的實(shí)現(xiàn)
本文主要介紹了Visual Studio2019調(diào)試DLL的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01C++實(shí)現(xiàn)String與UF8互轉(zhuǎn)
這篇文章介紹了C++實(shí)現(xiàn)String與UF8互轉(zhuǎn)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05