您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Java和C語言如何使用靜態(tài)語言實(shí)現(xiàn)動(dòng)態(tài)數(shù)組,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
JAVA版
JAVA自帶了一個(gè)集合類ArrayList,可以實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的功能,相比原生的數(shù)組,使用起來非常方便。在閱讀Tomcat源碼的時(shí)候,發(fā)現(xiàn)出于性能考慮使用了原生的數(shù)組,而沒有直接使用原生的ArrayList,自己實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)數(shù)組,下面的這個(gè)實(shí)現(xiàn)就是直接從Tomcat的源碼借鑒過來的。
實(shí)現(xiàn)思路
動(dòng)態(tài)添加元素
初始化一個(gè)數(shù)組,大小固定。
獲取源數(shù)組的大小,在方法區(qū)里面申請(qǐng)一個(gè)比原有數(shù)組大1位的數(shù)組。
關(guān)鍵的內(nèi)容是,調(diào)用System.arraycopy(src, 0, dest, 0, src.length),從src的0位復(fù)制src.length位到dest的0位,這里用系統(tǒng)自帶的方法比較方便,也可以自己寫一個(gè)循環(huán)進(jìn)行復(fù)制。
把要添加的元素放到新數(shù)組的最后一位。
返回元素,把新數(shù)組的指針復(fù)制到原數(shù)組變量,JAVA的數(shù)組是引用型的,執(zhí)行 src=dest 后,兩者實(shí)際上是指向同一個(gè)內(nèi)存地址。
動(dòng)態(tài)刪除元素
初始化一個(gè)數(shù)組,大小固定。
在方法區(qū)申請(qǐng)一個(gè)比原生數(shù)組小一位的數(shù)組
從index位開始,把后面的元素同時(shí)往前移動(dòng)一位,覆蓋要?jiǎng)h除的元素。
返回元素,把改變?cè)瓟?shù)組的指向到新數(shù)組
package demo; import java.util.Arrays; public class DiyArrayListDemo { public static void main(String[] args){ int[] arr = {5,8,10}; System.out.println(Arrays.toString(arr));//=>[5, 8, 10] arr = DiyArrayList.add(arr, 15); arr = DiyArrayList.add(arr, 20); arr = DiyArrayList.add(arr, 25); System.out.println(Arrays.toString(arr)); //=>[5, 8, 10, 15, 20, 25] arr = DiyArrayList.remove(arr, 1); System.out.println(Arrays.toString(arr)); //=>[5, 10, 15, 20, 25] } } class DiyArrayList{ public static int[] add(int[] src,Integer newData){ //定義目標(biāo)數(shù)組,長(zhǎng)度是比原始數(shù)組多一位 int[] dest = new int[src.length+1]; //從src的0位開始,復(fù)制到dest的0位置,復(fù)制長(zhǎng)度是src的長(zhǎng)度 System.arraycopy(src, 0, dest, 0, src.length); //填充最后一位的值 dest[src.length] = newData; return dest; } public static int[] remove(int[] src,Integer index){ //定義目標(biāo)數(shù)組,長(zhǎng)度是比原始數(shù)組少一位 int[] desc = new int[src.length-1]; for(int i=0; i<src.length; i++){ //超過索引index的數(shù)據(jù)往前移動(dòng)一位 if(i > index){ desc[i-1] = src[i]; }else{ desc[i] = src[i]; } } return desc; } }
C語言版
C語言中實(shí)現(xiàn)動(dòng)態(tài)數(shù)組相對(duì)比較復(fù)雜一點(diǎn),因?yàn)镃語言要對(duì)指針,內(nèi)存進(jìn)行操作。開始之前需要定義一個(gè)結(jié)構(gòu)體arrayList和結(jié)構(gòu)體變量ArrayList,里面包含兩個(gè)數(shù)組,一個(gè)是int類型的指針,用來指向存儲(chǔ)int型數(shù)組的內(nèi)存,還有一個(gè)count,用來記錄數(shù)組的長(zhǎng)度,因?yàn)橥ㄟ^malloc(),realloc()進(jìn)行動(dòng)態(tài)內(nèi)存分配(程序執(zhí)行的時(shí)候分配),用sizeof()是無法獲取到正確的內(nèi)存長(zhǎng)度的,所以必須要定義一個(gè)變量count去記錄到底向系統(tǒng)申請(qǐng)了多少內(nèi)存。為什么需要用malloc而不是像JAVA那樣直接用new int[] 來創(chuàng)建一個(gè)數(shù)組呢?這就涉及了JAVA和C內(nèi)存分配的一個(gè)區(qū)別,JAVA方法里面的數(shù)組是存放在堆中,而C函數(shù)里面的數(shù)組分配的內(nèi)存是存放在棧中的,函數(shù)執(zhí)行結(jié)束,數(shù)組的內(nèi)存空間就會(huì)被釋放,因此需要用malloc從棧申請(qǐng)空間。
實(shí)現(xiàn)思路
動(dòng)態(tài)添加元素
通過realloc() 重新申請(qǐng)一個(gè)新的內(nèi)存空間,空間比當(dāng)前數(shù)組的大一個(gè)int長(zhǎng)度,通過int*類型的指針指向該空間。
把數(shù)據(jù)放在數(shù)組的最后一位。
把記錄的數(shù)組長(zhǎng)度進(jìn)行++操作。
動(dòng)態(tài)刪除元素
判斷函數(shù)傳入的index是否有效。
把大于index的數(shù)組數(shù)據(jù)往前移動(dòng)一個(gè)索引。
重新申請(qǐng)空間,數(shù)組長(zhǎng)度縮減一個(gè)int長(zhǎng)度。
把記錄的數(shù)組長(zhǎng)度進(jìn)行--操作。
demo.h
//定義一個(gè)結(jié)構(gòu)體,data里面儲(chǔ)存的是int類型指數(shù)組,count存儲(chǔ)的是數(shù)組的長(zhǎng)度 typedef struct arrayList { int* data; int count; } ArrayList; void initArrayList(ArrayList* list); void arrayListAdd(ArrayList* list, int data); void arrayListRemove(ArrayList* list, int index); void printAll(ArrayList list); demo.c #include <stdio.h> #include <stdlib.h> #include "test.h" int main() { ArrayList arrayList; initArrayList(&arrayList); arrayListAdd(&arrayList, 10); arrayListAdd(&arrayList, 13); arrayListAdd(&arrayList, 15); arrayListRemove(&arrayList, 2); printAll(arrayList); } /******************************** 函數(shù)名:initArrayList() 功能:初始化ArrayList結(jié)構(gòu)體 輸入:ArrayList類型結(jié)構(gòu)體指針 輸出:無 */ void initArrayList(ArrayList* arrayList) { arrayList->data = NULL; arrayList->count = 0; } /******************************* 函數(shù)名:arrayListAdd() 功能:添加數(shù)據(jù)到ArrayList類型結(jié)構(gòu)體里面的數(shù)組 輸入:ArrayList類型結(jié)構(gòu)體指針,int類型數(shù)據(jù) 輸出:無 */ void arrayListAdd(ArrayList* list, int data) { int count = list->count; //重新申請(qǐng)空間,空間比現(xiàn)在的長(zhǎng)度大1個(gè)int長(zhǎng)度 int* newDataArr = (int*)realloc(list->data,sizeof(int) * (++count)); if (newDataArr != NULL) { list->data = newDataArr; list->data[count - 1] = data; list->count++; } else { puts("申請(qǐng)空間失敗"); } } /******************************* 函數(shù)名:arrayListRemove() 功能:根據(jù)index刪除ArrayList類型結(jié)構(gòu)體里面的數(shù)組元素 輸入:ArrayList類型結(jié)構(gòu)體指針,int類型索引 輸出:無 */ void arrayListRemove(ArrayList* list, int index) { if (index > list->count) { puts("超出數(shù)組索引"); exit(1); } //把大于index的數(shù)組數(shù)據(jù)往前移動(dòng)一個(gè)索引 for (int i = 0; i < list->count; i++) { if (i > index) { list->data[i - 1] = list->data[i]; } } int count = list->count; //重新申請(qǐng)空間,數(shù)組長(zhǎng)度縮減一個(gè)int長(zhǎng)度 int *newDataArr = realloc(list->data, sizeof(int) * (--count)); if (newDataArr != NULL) { list->data = newDataArr; list->count = count; } else { puts("申請(qǐng)空間失敗"); } } /******************************** 函數(shù)名:打印所有數(shù)組 輸入:ArrayList類型結(jié)構(gòu)體 */ void printAll(ArrayList list) { for (int i = 0; i < list.count; i++) { printf("%d \r\n", list.data[i]); } }
關(guān)于“Java和C語言如何使用靜態(tài)語言實(shí)現(xiàn)動(dòng)態(tài)數(shù)組”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。