http://c.biancheng.net/cpp/html/2790.html
2015
C語言中,數(shù)組長度必須在創(chuàng)建數(shù)組時指定,并且只能是一個常數(shù),不能是變量。一旦定義了一個數(shù)組,系統(tǒng)將為它分配一個固定大小的空間,以后不能改變,稱為靜態(tài)數(shù)組。但在編程過程中,有時我們所需的內(nèi)存空間無法預(yù)先確定,對于這個問題,用靜態(tài)數(shù)組的辦法很難解決。
動態(tài)數(shù)組是相對于靜態(tài)數(shù)組而言。靜態(tài)數(shù)組的長度是預(yù)先定義好的,在整個程序中,一旦給定大小后就無法改變。而動態(tài)數(shù)組則不然,它可以隨程序需要而重新指定大小。動態(tài)數(shù)組的內(nèi)存空間是從堆(heap)上分配(即動態(tài)分配)的。是通過執(zhí)行代碼而為其分配存儲空間。當(dāng)程序執(zhí)行到這些語句時,才為其分配。程序員自己負(fù)責(zé)釋放內(nèi)存。
那么,如何創(chuàng)建動態(tài)數(shù)組,按照需要設(shè)置數(shù)組大小呢?
下面是一個創(chuàng)建動態(tài)數(shù)組的例子:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- int arrLen; // 數(shù)組長度
- int *array; // 數(shù)組指針
- int i; // 數(shù)組下標(biāo)
- printf("輸入數(shù)組長度:");
- scanf("%d", &arrLen);
-
- // 動態(tài)分配內(nèi)存空間,如果失敗就退出程序
- array = (int*)malloc( arrLen*sizeof(int) );
- if(!array){
- printf("創(chuàng)建數(shù)組失敗!\n");
- exit(1);
- }
- // 向內(nèi)存中寫入數(shù)據(jù)
- for(i=0; i<arrLen; i++){
- array[i] = i+1;
- }
-
- // 循環(huán)輸出數(shù)組元素
- for(i=0; i<arrLen; i++){
- printf("%d ", array[i]);
- }
-
- printf("\n");
- free(array);
-
- system("pause");
- return 0;
- }
運行結(jié)果:
輸入數(shù)組長度:10
1 2 3 4 5 6 7 8 9 10
請按任意鍵繼續(xù). . .
malloc()函數(shù)
這里重點說明的是malloc()函數(shù),這是一個非常重要和常用的函數(shù)。
malloc() 用來動態(tài)分配指定大小的內(nèi)存空間,以字節(jié)計,其原型為:
void *malloc( size_t size );
size_t 是一種自定義數(shù)據(jù)類型,在 stddef.h 頭文件中定義為:
typedef unsigned int size_t; // 無符號整型
malloc()返回值類型為 void *,這并不是說該函數(shù)調(diào)用后無返回值,而是返回一個內(nèi)存結(jié)點的地址,該地址的類型為void(無類型或類型不確定),即一段存儲區(qū)的首址,其具體類型無法確定,只有使用時根據(jù)各個域值數(shù)據(jù)再確定。可以用強(qiáng)制轉(zhuǎn)換的方法將其轉(zhuǎn)換為別的類型。例如:
- double*pd=NULL;
- pd=(double*)malloc(10*sizeof(double));
表示將向系統(tǒng)申請10個連續(xù)的double類型的存儲空間,并用指針pd指向這個連續(xù)的空間的首地址。并且用(double)對malloc()的返回類型進(jìn)行轉(zhuǎn)換,以便把double類型數(shù)據(jù)的地址賦值給指針pd。
sizeof
上面的代碼中,array = (int*)malloc( arrLen*sizeof(int) ); 用來分配arrLen*sizeof(int)個字節(jié)的內(nèi)存空間,并將返回的指針強(qiáng)制轉(zhuǎn)換為int。這里注意,int 類型的長度在不同平臺下可能不同,不要把int的長度指定為2或4,要用sizeof()來計算int的長度,以更好的跨平臺。
使用內(nèi)存中的數(shù)據(jù)
上面的代碼中,我們通過下標(biāo)(array[i])來引用數(shù)組元素,這個靜態(tài)數(shù)組沒有什么區(qū)別。另外還可以通過指針來引用數(shù)組元素,對上面的程序稍作修改:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- int arrLen; // 數(shù)組長度
- int *array; // 數(shù)組指針
- int *arrayCopy; // 數(shù)組指針副本
- int i; // 數(shù)組下標(biāo)
- printf("輸入數(shù)組長度:");
- scanf("%d", &arrLen);
-
- // 動態(tài)分配內(nèi)存空間,如果失敗就退出程序
- arrayCopy = array = (int*)malloc( arrLen*sizeof(int) );
- if(!array){
- printf("創(chuàng)建數(shù)組失??!\n");
- exit(1);
- }
- // 向內(nèi)存中寫入數(shù)據(jù)
- for(i=0; i<arrLen; i++){
- *arrayCopy++ = i+1;
- }
-
- // 循環(huán)輸出數(shù)組元素
- arrayCopy = array;
- for(i=0; i<arrLen; i++){
- printf("%d ", *arrayCopy++);
- }
-
- printf("\n");
- free(array);
-
- system("pause");
- return 0;
- }
可以發(fā)現(xiàn),我們必須另外定義一個指針變量 arrayCopy,用來指向具體的數(shù)組元素。數(shù)組賦值完成后,要將 arrayCopy 重置到數(shù)組首地址,以便后面循環(huán)輸出。
這里注意:free() 函數(shù)必須釋放整塊內(nèi)存,不能只釋放一部分,或者釋放不存在的內(nèi)存空間,否則程序會出錯。所以,要多定義一個變量 arrayCopy,不斷改變它的值,以指向不同的數(shù)組元素。這樣可以保證 array 變量的值不變,始終指向內(nèi)存首地址,用于free()整塊內(nèi)存。
例如,如果改變了 array 的值,使其指向第5個數(shù)組元素,那在free(array)時只釋放掉了后半部分內(nèi)存,而沒有釋放掉前半部分內(nèi)存,這將引起程序錯誤。