傳遞任意大小二維陣列
2008年9月8日 星期一 by Anati
通常傳遞一個陣列的時候,因為需要告訴函式,需要多少個col分成一組,也就是說要告訴它,除了第一個維度以外,所有維度的下標,但是C99支援了一種可傳遞任何陣列大小的方法,稱為VLAs(變動長度陣列)。
※ 適用Compiler
* gcc 3.4.2 (或更高)
* Dev-C++
* Mingw
※ 一般用法
Example:
#define COL 4
void show(int (*ar)[COL], int size) (size是指row大小)
{
int i, j;
for (i = 0; i < size; ++i)
{
for (j = 0; j < COL; ++j)
{
printf("%d", ar[i][j]);
}
}
}
int main()
{
show(array1, 5);
show(array2, 100);
return 0;
}
以上是我們最常見傳遞二維陣列的用法,此在函式傳遞有深入的介紹,看不懂的可以去看看那篇文章,這只提一下而已。
※ 使用VLAs
Example:
void show(int row, int col, int ar[row][col]); (VLAs的宣告)
int main()
{
show(3, 2, array1);//3 x 2維度
show(100, 5, array2);//100 x 5任意維度
return 0;
}
void show(int row, int col, int ar[row][col])
{
int i, j;
for (i = 0; i < row; ++i)
{
for (j = 0; j < col; ++j)
{
printf("%d", ar[i][j]);
}
}
}
由此可以看見VLAs的函式宣告也和一般不同,但是因為可以傳遞任何的維度,真的是非常好用,但是也有一些限制。
* VLAs必須是自動儲存類別,也就是說,它必須在「函式」裡面宣告,或是作為函式的「形式參數」
* 不可以在宣告時,對它進行初始化
* 一個陣列若宣告在函式外面,則為static且和程式共存亡
* 一個陣列有初值的話,也是為static且和程式共存亡
* VLAs宣告的順序必需要先將大小的變數宣告在前,而陣列宣告在後,如int a, int b為長和寬,而int ar[a][b]則為這個陣列的長寬設定。
* VLAs的宣告並不會實際產生一個陣列,而只是一個「指標」而已
※ 執行期配空間
Example:
void init(int a, int b, int ar[a][b]);
void show(int a, int b, int ar[a][b]);
int main()
{
int n1;
int n2;
scanf("%d%d", &n1, &n2);
int ar[n1][n2]; (執行的時候才決定二維大小)
init(n1, n2, ar);
show(n1, n2, ar);
return 0;
}
void init(int a, int b, int ar[a][b])
{
int i, j;
for (i = 0; i < a; ++i)
{
for (j = 0; j < b; ++j)
{
scanf("%d", &ar[i][j]);
}
}
}
void show(int a, int b, int ar[a][b])
{
int i, j;
for (i = 0; i < a; ++i)
{
for (j = 0; j < b; ++j)
{
printf("%d ", ar[i][j]);
}
printf("\n");
}
}
VLAs可以當成像是malloc動態配置空間使用,但是需要符合以上的求要,雖然看起來好像和malloc一樣,都可以配置動態的記憶體空間,但是兩個儲存的空間卻是完全不同的,傳統的陣列都是存在Global的空間,而VLAs存在Stack中,而malloc則是存在Heap中,所以生命的週期自然就不相同。
※ 適用Compiler
* gcc 3.4.2 (或更高)
* Dev-C++
* Mingw
※ 一般用法
Example:
#define COL 4
void show(int (*ar)[COL], int size) (size是指row大小)
{
int i, j;
for (i = 0; i < size; ++i)
{
for (j = 0; j < COL; ++j)
{
printf("%d", ar[i][j]);
}
}
}
int main()
{
show(array1, 5);
show(array2, 100);
return 0;
}
以上是我們最常見傳遞二維陣列的用法,此在函式傳遞有深入的介紹,看不懂的可以去看看那篇文章,這只提一下而已。
※ 使用VLAs
Example:
void show(int row, int col, int ar[row][col]); (VLAs的宣告)
int main()
{
show(3, 2, array1);//3 x 2維度
show(100, 5, array2);//100 x 5任意維度
return 0;
}
void show(int row, int col, int ar[row][col])
{
int i, j;
for (i = 0; i < row; ++i)
{
for (j = 0; j < col; ++j)
{
printf("%d", ar[i][j]);
}
}
}
由此可以看見VLAs的函式宣告也和一般不同,但是因為可以傳遞任何的維度,真的是非常好用,但是也有一些限制。
* VLAs必須是自動儲存類別,也就是說,它必須在「函式」裡面宣告,或是作為函式的「形式參數」
* 不可以在宣告時,對它進行初始化
* 一個陣列若宣告在函式外面,則為static且和程式共存亡
* 一個陣列有初值的話,也是為static且和程式共存亡
* VLAs宣告的順序必需要先將大小的變數宣告在前,而陣列宣告在後,如int a, int b為長和寬,而int ar[a][b]則為這個陣列的長寬設定。
* VLAs的宣告並不會實際產生一個陣列,而只是一個「指標」而已
※ 執行期配空間
Example:
void init(int a, int b, int ar[a][b]);
void show(int a, int b, int ar[a][b]);
int main()
{
int n1;
int n2;
scanf("%d%d", &n1, &n2);
int ar[n1][n2]; (執行的時候才決定二維大小)
init(n1, n2, ar);
show(n1, n2, ar);
return 0;
}
void init(int a, int b, int ar[a][b])
{
int i, j;
for (i = 0; i < a; ++i)
{
for (j = 0; j < b; ++j)
{
scanf("%d", &ar[i][j]);
}
}
}
void show(int a, int b, int ar[a][b])
{
int i, j;
for (i = 0; i < a; ++i)
{
for (j = 0; j < b; ++j)
{
printf("%d ", ar[i][j]);
}
printf("\n");
}
}
VLAs可以當成像是malloc動態配置空間使用,但是需要符合以上的求要,雖然看起來好像和malloc一樣,都可以配置動態的記憶體空間,但是兩個儲存的空間卻是完全不同的,傳統的陣列都是存在Global的空間,而VLAs存在Stack中,而malloc則是存在Heap中,所以生命的週期自然就不相同。