矩力集成2008年校園招聘筆試題:動態申請一個二維數組存儲圖像陣列
傳統的解決方案是分配一個指針數組, 然后把每個指針初始化為動態分配的 ``列"。 以下為一個二維的例子:
//typedef int (*arraypoiter)[ncolumns];
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
array[i] = (int *)malloc(ncolumns * sizeof(int));
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c30
array[1]=911bf0
array[2]=911bb0
test_allocate=911c70
*/
當然, 在真實代碼中, 所有的 malloc 返回值都必須檢查。你也可以使用 sizeof(*array) 和sizeof(**array) 代替 sizeof(int *) 和 sizeof(int)(因為*array的類型為int *,**array的類型為int)。
你可以讓數組的內存連續, 但在后來重新分配列的時候會比較困難, 得使用一點指針算術:
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
for(i = 1; i < nrows; i++)
array[i] = array[0] + i * ncolumns;
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c10
array[1]=911c20
array[2]=911c30
test_allocate=911c70
*/
在兩種情況下, 動態數組的成員都可以用正常的數組下標 arrayx[i][j] 來訪問 (for 0 <= i <nrows 和 0 <= j <ncolumns)。
另一種選擇是使用數組指針:
int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
但是這個語法變得可怕而且運行時最多只能確定一維。因為NCOLUMNS必須為定值
××××××××××××××××××××××××××××××××××××××
C語言里,數組名是被看作指針來使用的,一維數組是指針,二維數組是指向指針的指針,三維是......... 真的是這樣的嗎??看下面的例子:
void show (int * * info, int x, int y) //打印一個x*y的數組的內容
{
int i, j;
for (i=0;i<x;i++)
{
for (j=0;j<y;j++)
{
printf ("%d ",info[i][j]);
}
printf ("/n");
}
}
void Function (void)
{
int as[10][10];
show (as,10,10);
// error C2664: 'show' : cannot convert parameter 1 from 'int [10][10]' to 'int ** ' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
}
在C中沒有安全類型檢查,上述程序只是warning,但是程序運行會崩潰
在C++中,根本就無法編譯通過,即as[10][10]和int * *根本不是一個類型
為什么?在c中,二維數組雖然是定義為指向指針的指針,但是實際上被指向的指針是不存在的,即沒有一個內存來存儲這個指針,只是在執行as [n]時返回一個指針罷了,as所指的不過是存放數組內容的地址!!
實際上從上面**P和動態二維數組的使用即可看出來,**P和靜態二維數組的本質區別!