C陣列
文章推薦指數: 80 %
無論是幾維的陣列,C語言都以分配一塊連續的記憶體空間來處理。
int x[10];. 分配10*sizeof(int)個bytes int x[5][10];. 分配5* ...
說明:
陣列是一種結構性的資料儲存空間,其同一陣列裡的資料性質呈一致性,元素與元素之間的記憶位置是相鄰的,通常我們利用一個變數來代表整體的資料。
舉例而言,我們可以把陣列想成一群鳥窩,而陣列裡的變數個數代表鳥窩的數目,例如:麻雀[20],我們可以想成麻雀的窩總共有二十間,每一間住著一間麻雀,假如我們想要知道第三間麻雀的名字,只要把麻雀[2]的值取出,便可知道住在第三間麻雀的姓名。
C語言的陣列索引一定是從0的開始的。
格式:
根據陣列的結構而言,可以把陣列分為(1)一維陣列、(2)二維陣列、(3)多維陣列。
而其表示方法如下:
資料型態 陣列名稱[陣列大小];
資料型態 陣列名稱[陣列大小][陣列大小];
宣告陣列變數時,也可一併給與初始值:
intx[5]={1,2,3,4,5};
inty[]={1,2,3};
intz[3][4]={{1,2,3,4},{5,6,7,8},{0,1,2,3}};
inta[];
上面例子裡的y陣列大小,是由後面{}裡元素的個數決定。
inta[]並沒有分配儲存陣列內容的空間,因此可視為指標宣告。
引用方式:
陣列名稱[索引值]
陣列名稱[索引值][索引值]
圖示:
範例:(輸入3個實數,並求其平均值)
#include
intx[10];
分配10*sizeof(int)個bytes
intx[5][10];
分配5*10*sizeof(int)個bytes
intx[4][5][6];
分配4*5*6*sizeof(int)個bytes
voidfun(intx[]){
}
上面的x就沒有分配陣列的空間了,而是相當於int*x;這是因為C語言呼叫函數傳遞參數時,無法傳遞整個陣列(陣列可能大得不得了),而是傳遞陣列的開頭地址,也就是指標。
因此在參數宣告時,指標和沒有宣告大小的陣列是可以混用的。
既然無論是幾維的陣列,C語言都以分配一塊連續的記憶體空間來處理,那麼像是
intx[2][3];
x[0][2]=0;
中的x[0][2]被翻譯到哪一塊記憶體去了?C語言是使用rowmajor的方式來處理多維到一維的對應。
簡單的說,就是右邊的索引先變化:
OOOOOO
這六個整數的順序為x[0][0],x[0][1],x[0][2],x[1][0],x[1][1],x[1][2]。
array和pointer的對應關係如下:
intx[p][q];
inty[p][q][r];
intz[p];
int*po;
po=x;
x[i][j]=0;
*(po+i*q+j)=0;//samewithx[i][j];
po=y;
y[i][j][k]=0;
*(po+i*q*r+j*r+k)=0;//samewithy[i][j][k]
po=z;
z[i]=0;
*(po+i)=0;//samewithz[i]
陣列的參數傳遞
C語言只能傳遞指標,無法傳遞陣列的內容。
假設我們要傳遞一個二維陣列,則C會幫我們將該陣列的起頭位置傳入,但參數宣告部分則有如下不同的方式:
voidfoo1(intx[][]){//編譯過,但Compiler不知如何翻譯,還是用int*x自己計算地址比較好
x[2][2]=0;//編譯錯誤!,Compiler不知如何翻譯
}
voidfoo2(intx[][3]){//Compiler知道如何翻譯
x[1][1]=0;//Compiler知道要翻成*(x+1*3+1)
}
voidfoo3(intx[2][3]){//Compiler知道如何翻譯
x[1][1]=0;//Compiler知道要翻成*(x+1*3+1)
}
voidfoo4(intx[3][]){//編譯錯誤
}
voidfoo5(int*x){//反正只能傳pointer
*(x+1*3+1)=0;
}
intmain(){
intm[2][3];
int*p;
intk[4][4];
foo2(m);
foo2(p);//Compilerwarning,incompatiblepointertype
foo3(k);//Compilerwarning,incompatiblepointertype
foo5(m);//Compilerwarning,incompatiblepointertype
foo5(p);
foo5((int*)m);//強迫轉型,Compiler就不會抱怨了
}
動態空間分配
宣告陣列時,Ccompiler就已經分配好空間了。
例如
intmain(){
intx[10][20];
}
compiler會在進入main時於堆疊上分配給x放置200個整數所需的空間,而在離開main時將空間回收。
對指標來說,則只有分配紀錄指標的空間,但對於透過該指標所能存取的記憶體,卻沒有分配。
有許多情況是設計者無法事先預知所需空間的大小,必須等到runtime才能知道。
C語言提供了一系列的函數可於執行期間分配或釋放記憶體空間。
void*malloc(size_tsize);
void*calloc(size_tnelem,size_telsize);
voidfree(void*ptr);
使用以上函數必須#include
malloc會自heap(堆積)取得size個byte,並傳回該區塊的起始位置。
calloc分配nelem個大小為elsize個byte的空間,並把該區塊所有的內容設為0。
free則是釋放由malloc或calloc所分配的記憶體空間。
要特別提醒讀者的是,malloc和free要小心使用,如果malloc所得的空間沒有用free釋放,則應用程式就會一直佔住該記憶體,此一現象稱為memoryleakage。
如果同一空間free了兩次,或已經free了卻繼續使用,也都可能出問題。
範例
SelectionSort
#include
延伸文章資訊
- 1C陣列
無論是幾維的陣列,C語言都以分配一塊連續的記憶體空間來處理。 int x[10];. 分配10*sizeof(int)個bytes int x[5][10];. 分配5* ...
- 2二維(多維)陣列 - OpenHome.cc
一維陣列使用陣列名稱與一個索引值來指定存取陣列元素,二維陣列使用陣列名稱與兩個索引值來指定存取陣列元素,宣告方式與一維陣列類似: int maze[5][10]; ...
- 3擁抱「資料結構」的「演算法」(03) - 多維陣列 ... - iT 邦幫忙
昨天介紹的內容就是一維陣列,陣列可以 儲存 多個元素,我們可以宣告一個box 變數, ... 因為小美須要根據今天是 星期幾 以及今天是什麼 時段 ,才能決定要做什麼樣的 ...
- 4陣列
一維陣列的定義方式為: ... C語言對陣列的初始化給予值還有以下幾點規定: ... 前面介紹的陣列只有一個下標,稱為一維陣列,其陣列元素也稱為單下標變數。
- 5一維陣列 - C/C++
一個一維陣列,他使用的位元組大小計算如下: ... 針對可能的變化,C/C++提供了一個函式sizeof(data_type)來偵測系統究竟使用幾個bytes來表示某一資料型別。