1. 程式人生 > >C語言中動態分配陣列

C語言中動態分配陣列

摘要的重要性是不言而喻的,每次發文章我都很糾結如何寫出一個有特色的摘要來,能夠以最為簡短的文字向讀者描述出我所要表達的東西。但是常常出現的問題是,摘要寫得太簡短了,讀者看了不清楚文章究竟要講啥;摘要寫得稍微長點的話自然能夠描述清楚所要表達的東西,但是卻也出現了另外一個問題,就是讀者看到大段的文字描述,覺得枯燥無味,直接二話不說給文章判了個“死刑”,導致這種情況下願意真正的花時間看完摘要的讀者屈指可數,更不用說文章的正文部分了,所以時長感慨寫文章最頭疼的莫過於摘要了。

很多人在編寫C語言程式碼的時候很少使用動態陣列,不管什麼情況下通通使用靜態陣列的方法來解決,在當初學習C語言的時候我就是一個典型的例子,但是現在發現這是一個相當不好的習慣,甚至可能導致編寫的程式出現一些致命的錯誤。尤其對於搞嵌入式的人來所,嵌入式系統的記憶體是寶貴的,記憶體是否高效率的使用往往意味著嵌入式裝置是否高質量和高效能,所以高效的使用記憶體對我們來說是很重要的。那麼我們在自己編寫C語言程式碼的時候就應該學會使用動態陣列,這也就是我這篇部落格要給大家講的,我盡我所能的用一些簡單的程式碼來講解動態陣列,希望我所講的對你有所幫助。

那麼我們首先來看看什麼是動態陣列,動態陣列是相對於靜態陣列而言,從“動”字我們也可以看出它的靈活性,靜態陣列的長度是預先定義好的,在整個程式中,一旦給定大小後就無法改變。而動態陣列則不然,它可以隨程式需要而重新指定大小。動態陣列的記憶體空間是從堆動態分配的。是通過執行程式碼而為其分配儲存空間。當程式執行到我們編寫的分配語句時,才為其分配。對於靜態陣列,其建立非常方便,使用完也無需釋放,要引用也簡單,但是建立後無法改變其大小是其致命弱點!對於動態陣列,其建立麻煩,使用完必須由程式設計師自己釋放,否則將會引起記憶體洩露。但其使用非常靈活,能根據程式需要動態分配大小。所以相對於靜態陣列的來說我們對於使用動態陣列有很大的自由度。

在建立動態陣列的過程中我們要遵循一個原則,那就是在建立的時候從外層往裡層,逐層建立;而釋放的時候從裡層往外層,逐層釋放。這個話你讀了可能理解並不深刻,不過不要急,接下來我們看看兩段程式碼。

一維動態陣列的建立:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int n1,i;
int *array;
printf("請輸入所要建立的一維動態陣列的長度:");
scanf("%d",&n1);
array=(int*)calloc(n1,sizeof(int));
for(i=0;i<n1;i++)
{
 printf("%d\t",array[i]);
}
printf("\n");
for(i=0;i<n1;i++)
{
 array[i]=i+1;
 printf("%d\t",array[i]);
}
 free(array);//釋放第一維指標 
return 0;
}

執行結果為:

特此說明:在以後的執行結果部分,我均會附上文字結果,以防圖片開啟失敗。

請輸入所要建立的一維動態陣列的長度:4
0       0       0       0
1       2       3       4       Press any key to continue

在此我使用的是calloc()函式來分配的,同時也使用兩個for語句來列印陣列元素,我們發現第一個列印輸出的陣列元素值均為0,在此也是為了加深讀者對於calloc()函式的印象我特地使用了它來分配,如果對於calloc()、malloc()、realloc()函式的區別還是很清楚的讀者可以去看看我的另外一篇部落格------C語言的那些小祕密之記憶體分配。

二維陣列的建立:

#include <stdio.h> 
#include <stdlib.h> 
int main() 

int n1,n2; 
int **array,i,j; 
printf("請輸入所要建立的動態陣列的第一維長度:");
scanf("%d",&n1);
printf("請輸入所要建立的動態陣列的第二維長度:");
scanf("%d",&n2); 
array=(int**)malloc(n1*sizeof(int*)); //第一維 
for(i=0;i<n1; i++) 

array[i]=(int*)malloc(n2* sizeof(int));//第二維 
}
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++) 

array[i][j]=i*n2+j+1; 
printf("%d\t",array[i][j]); 

printf("\n");
}
for(i=0;i<n1;i++) 

free(array[i]);//釋放第二維指標 

free(array);//釋放第一維指標 
return 0; 
}

執行結果為:

 請輸入所要建立的動態陣列的第一維長度:3
請輸入所要建立的動態陣列的第二維長度:3
1       2       3
4       5       6
7       8       9
Press any key to continue

有了上面的程式碼我們再來說動態陣列的建立就簡單了,以二維為例,先說建立,還記得我們上面說的建立的原則嘛:從外層往裡層,逐層建立。

array=(int**)malloc(n1*sizeof(int*)); //第一維

以上是我們建立二維動態陣列的最外層,建立好了最外層那麼我們接下來就是要建立次外層了。

array[i]=(int*)malloc(n2* sizeof(int));//第二維

在建立次外層的過程中我們使用了一個for喜歡語句,千萬別忘了使用for迴圈語句,這是絕大多數人的一個易錯點。

建立好了接下來我們該講到釋放了,而釋放的時候從裡層往外層,逐層釋放。剛剛與我們上面的建立相反,在以上程式碼中我們首先使用了下面一個for迴圈來釋放裡層。

for(i=0;i<n1;i++) 

free(array[i]);//釋放第二維指標 
}

在通過以下語句來釋放外層。
free(array);//釋放第一維指標

如果出現多維的情況怎麼做呢,我們接下來再來看看一個三維動態陣列的建立和釋放,以加深下讀者的印象。程式碼如下:

#include <stdlib.h> 
#include <stdio.h> 
int main() 

int n1,n2,n3; 
int ***array; 
int i,j,k; 
printf("請輸入所要建立的動態陣列的第一維長度:");
scanf("%d",&n1); 
printf("請輸入所要建立的動態陣列的第二維長度:");
scanf("%d",&n2); 
printf("請輸入所要建立的動態陣列的第三維長度:");
scanf("%d",&n3); 
array=(int***)malloc(n1*sizeof(int**));//第一維 
for(i=0; i<n1; i++) 

array[i]=(int**)malloc(n2*sizeof(int*)); //第二維 
for(j=0;j<n2;j++) 

array[i][j]=(int*)malloc(n3*sizeof(int)); //第三維 


for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
for(k=0;k<n3;k++) 

array[i][j][k]=i+j+k+1; 
printf("%d\t",array[i][j][k]); 

printf("\n");
}
printf("\n");
}
for(i=0;i<n1;i++) 

for(j=0;j<n2;j++) 

free(array[i][j]);//釋放第三維指標 


for(i=0;i<n1;i++) 

free(array[i]);//釋放第二維指標 

free(array);//釋放第一維指標 
return 0; 
}

執行結果為:


請輸入所要建立的動態陣列的第一維長度:3
請輸入所要建立的動態陣列的第二維長度:3
請輸入所要建立的動態陣列的第三維長度:3
1       2       3
2       3       4
3       4       5

2       3       4
3       4       5
4       5       6

3       4       5
4       5       6
5       6       7

Press any key to continue

看了以上三維動態陣列的建立和釋放程式碼以後,我想讀者這個時候已經可以自己編寫任意維的動態陣列了。但是細心的讀者可能發現了一個問題,那就是我們所講的動態陣列都是一次性建立好的,如果接下來在使用的過程中我們使用的陣列需要擴充套件或者刪減一些不再使用元素該怎麼辦呢?!接下來我們先看一段關於動態陣列擴充套件的程式碼,在此以一維動態陣列的擴充套件為例,其它的以此類推。

#include <stdio.h>
#include <stdlib.h>
int main()
{
int*n,*p;
int i,n1,n2;
printf("請輸入所要建立的動態陣列的長度:");
scanf("%d",&n1); 
n=(int*)calloc(n1,sizeof(int));
printf("請輸入所要擴充套件的動態陣列的長度:");
scanf("%d",&n2); 
p=(int*)realloc(n,(n2)*sizeof(int));//動態擴充陣列
for(i=0;i<n2;i++)
{
p[i]=i+1;
if(i%5==0)
printf("\n");
printf("%d\t",p[i]);
}
free(p);
return 0;
}

執行結果如下:

請輸入所要建立的動態陣列的長度:6
請輸入所要擴充套件的動態陣列的長度:25

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
16      17      18      19      20
21      22      23      24      25      Press any key to continue

看了上面的程式碼讀者應該知道如何來擴充套件動態陣列了,可能有的讀者對於realloc()函式的使用有些陌生,如果有什麼疑惑的話可以參考我之前寫的一篇博文------C語言的那些小祕密之記憶體分配,在此我就不再做過多的講解了。

接下來如何縮小動態陣列。

#include <stdio.h>
#include <stdlib.h>
int main()
{
int*n,*p;
int i,n1,n2;
printf("請輸入所要建立的動態陣列的長度:");
scanf("%d",&n1); 
n=(int*)calloc(n1,sizeof(int));
for(i=0;i<n1;i++)
{
n[i]=i+1;
if(i%5==0)
printf("\n");
printf("%d\t",n[i]);
}
printf("\n請輸入所要縮小的動態陣列的長度:");
scanf("%d",&n2); 
p=(int*)realloc(n,(n2)*sizeof(int));
for(i=0;i<n2;i++)
{
if(i%5==0)
printf("\n");
printf("%d\t",p[i]);
}
printf("\n");
free(p);
return 0;
}

執行結果為:

請輸入所要建立的動態陣列的長度:25

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
16      17      18      19      20
21      22      23      24      25
請輸入所要縮小的動態陣列的長度:15

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
Press any key to continue

在這裡值得注意的一點就是在縮減動態陣列的時候,它是刪除了後面的元素,而前面的元素保持不變。在使用realloc()函式的時候要由其注意它的使用規則。

講到這兒就到了該說結束的時候了,由於本人水平有限,部落格中的不妥或錯誤之處在所難免,殷切希望讀者批評指正。同時也歡迎讀者共同探討相關的內容,如果樂意交流的話請留下你寶貴的意見。

相關推薦

C語言動態分配陣列

摘要的重要性是不言而喻的,每次發文章我都很糾結如何寫出一個有特色的摘要來,能夠以最為簡短的文字向讀者描述出我所要表達的東西。但是常常出現的問題是,摘要寫得太簡短了,讀者看了不清楚文章究竟要講啥;摘要寫得稍微長點的話自然能夠描述清楚所要表達的東西,但是卻也出現了另外一個問題,

C語言動態分配陣列指標的釋放問題

我們都知道要實現根據程式的需要動態分配儲存空間,在C中需要使用到stdlib.h中的兩個函式,malloc,free,兩個函式的介紹如下: malloc函式的原型為: void *malloc (u igned int size) 其作用是在記憶體的動態儲存區中分配一個長

C語言動態內存的分配

成功 col 釋放內存 否則 turn stdlib.h color span 數組名 動態內存分配:根據需要隨時開辟,隨時釋放的內存分配方式。分配時機和釋放時機完全由程序員決定,由於沒有數據聲明,這部分空間沒有名字。無法像使用變量或數組那樣通過變量名或數組名引用其中的數據

c語言獲得動態分配記憶體後的陣列記憶體大小

c語言獲得動態分配記憶體後的陣列記憶體大小 用一個函式 :_msize(); ★注意:該函式為Windows獨有★ int* s = (int*)malloc(sizeof(int));     int i;     for(i

C語言動態申請連續的二維陣列

      可以採用多申請一些指標,然後這一些指標分別指向後面資料區中對應的位置,如一個3*4的int型別陣列,我們先申請大小為sizeof(int*) * 3 + 3 * 4 * sizeof(in

C語言動態分配內存

第一個元素 sprint 擴大 for 可選 key 。。 css text 1. malloc()函數和free()函數 首先,我們應該知道。所有的程序都必須留出足夠的內存空間來存儲所使用的數據,所以我們常常會預先給程序開辟好內存空間,然後進行操作,

C語言一維陣列與二維陣列

int arr [4]  //定義了一個一維陣列,長度為4;說明以下三個分別是什麼型別; (1)arr //型別為int *,表示陣列元素首地址,即圖中箭頭指向的位置。 (2)arr+1 //型別為int *,表示陣列元素首地址+1,即圖中箭頭指向的位置。 (3)arr [0

C語言函式指標陣列的初始化和使用

不比多說上一個程式碼,就懂了! 程式碼一: #include <stdio.h> int func(int i) {     printf("%d\n",i);     return i*i; } int

C語言記憶體分配

一、static在C語言裡面可以用來修飾變數,也可以用來修飾函式。 1、 先看用來修飾變數的時候。變數在C語言裡面可分為存在全域性資料區、棧和堆裡。 其實我們平時所說的堆疊是棧而不是堆,不要弄混。 例如:在file.c中 int a ; int main() {

C語言的指標陣列陣列指標

可以將 *string看成陣列 a[] 下的a,即指標是指向陣列的首地址的; 指標陣列是陣列元素為指標的陣列(例如 int *p[3],定義了p[0],p[1],p[2]三個指標),其本質為陣列。 指

C語言二維陣列名與陣列地址、首行地址、首行首元素地址關係與區別詳解(初學者必須掌握)

C語言作為很多大學理工科都會學習的語言,作為一種程式設計入門語言。但是相對於其他高階程式語言來說相對是比較難,尤其是指針,不知道有多少莘莘學子都是因為它,從C語言入門到放棄。想當年,筆者在大一學習C語言

c語言的指標陣列

指標陣列,陣列元素是一個指標 附上程式碼 #include <stdio.h> #include <stdlib.h> /* run this program using th

C語言動態分配函式

      動態分配函式的核心是malloc()和free()。每次呼叫malloc()時,均分配剩餘的記憶體的一部分;每次呼叫free()時,均向系統返還記憶體。被分配的空記憶體區中的記憶體叫做堆(heap)。動態分配函式的原型在<stdlib.h>中。  

C 語言二維陣列指標詳解

C語言中,指標是一個複雜但又靈活多變的知識點,我們知道,在一維陣列中,對於一個數組a[],*a,a,&a,都表示a的首地址,但如果與二維陣列混合使用,就顯得更為複雜了。例如對於一個二維陣列  a[2][4]={{1,2.3},{4,5,6}}  a+i,&a

C語言對字元陣列的一些操作(字元陣列分割)

       在C\C++語言中,字元陣列經常被用到,但是,仍然有一些細節的地方是需要注意的。之前在做專案的時候,也碰到類似的問題。現在把這個知識點記錄下來,方便自己查詢,也方便大家交流。      

9、C語言二維陣列陣列名及指向二維陣列的指標變數

#include <stdio.h> #include <stdlib.h> //與二維陣列相關的指標變數([] 比 *優先順序高) //在一般指標變數指向二維陣列,或者n維陣列,要直接操作a[i][j],對指標的操作必須有兩個符號(其中不出現&,如果有&則相應的加

C語言如何將陣列作為函式引數傳遞

今天覆習到c語言的陣列,看到這麼一個問題: 現在,你的程式要讀入兩個多項式,然後輸出這兩個多項式的和,也就是把對應的冪上的係數相加然後輸出。 程式要處理的冪最大為100。 輸入格式: 總共要輸入兩個多項式,每個多項式的輸入格式如下: 每行輸入兩個數字,第一個表

C語言動態分配記憶體

1. malloc()函式和free()函式 首先,我們應該知道,所有的程式都必須留出足夠的記憶體空間來儲存所使用的資料,所以我們經常會預先給程式開闢好記憶體空間,然後進行操作,但其實還有一種選擇,能夠讓記憶體分配自動進行下去。 對於傳統陣列,會遇到這樣的問

c語言記憶體的動態分配與釋放(多維動態陣列構建)

一. 靜態陣列與動態陣列    靜態陣列比較常見,陣列長度預先定義好,在整個程式中,一旦給定大小後就無法再改變長度,靜態陣列自己自動負責釋放佔用的記憶體。    動態陣列長度可以隨程式的需要而重新指定大小。動態陣列由記憶體分配函式(malloc)從堆(heap

g++ 記憶體分配c 語言陣列越界問題 (一道有趣的面試題)

首先是一段程式: # include <stdio.h> int main(int argc, char* argv[]){ int i = 0; int arr[3] = {0}; for(; i<=3; i++){ arr[i]