2016-09-07 34 views
1

我在理解指針如何處理二維數組時遇到了一些麻煩。即使是錯誤信息也沒有幫助我。我有一個二維數組,我需要一個指針,所以我可以在函數內部操作它(我認爲這就是你應該怎麼做)。有人能指出我做錯了什麼,並指出我朝着正確的方向嗎?指向具有函數的二維數組

這裏是我的代碼:

#include <stdio.h> 
#include <time.h> 

void init(char *array); 

int main(int argc, char *argv[]) { 
    char grid[21][80]; 
    char (*grid_ptr)[80]; 
    grid_ptr = grid; 
    int i, j; 
    init(*grid_ptr); 

    for (i=0; i<21; i++) { 
    for (j=0; j<80; j++) { 
     printf("%c", grid_ptr[i][j]); 
    } 
    printf("\n"); 
    } 

    return 0; 
} 

void init(char *array) { 
    int i,j; 
    for (i=0; i<21; i++) { 
    for (j=0; j<80; j++) { 
     *array[i][j] = ' '; 
    } 
    } 
    for (i=0; i<21; i++) { 
    *array[i][0] = '|'; 
    *array[i][79] = '|'; 
    } 
    for (i=0; i<80; i++) { 
    *array[0][i] = '-'; 
    *array[20][i] = '-'; 
    } 
} 

的錯誤是這種性質的:

main.c:27:16: error: subscripted value is not an array, pointer, or vector 
     *array[i][j] = ' '; 
+2

'即使錯誤信息也沒有幫助我......但他們可能會幫助我們。你會得到什麼錯誤? –

回答

4

請允許我說,你是讓你的生活很難完全沒有理由! :)你看,當一個人想要操縱一個二維數組,他可以在陣列上直接合作,由陣列本身傳遞給函數,就像這樣:

#include <stdio.h> 
#include <time.h> 

void init(int n, int m, char array[n][m]); 

int main(int argc, char *argv[]) { 
    const int n = 21, m = 80; 
    char grid[n][m]; 
    int i, j; 
    init(n, m, grid); 

    for (i = 0; i < n; i++) { 
    for (j = 0; j < m; j++) { 
     printf("%c", grid[i][j]); 
    } 
    printf("\n"); 
    } 

    return 0; 
} 

void init(int n, int m, char array[n][m]) { 
    int i,j; 
    for (i = 0; i < n; i++) { 
    for (j = 0; j < m; j++) { 
     array[i][j] = ' '; 
    } 
    } 
    for (i = 0; i < n; i++) { 
    array[i][0] = '|'; 
    array[i][m - 1] = '|'; 
    } 
    for (i = 0; i < m; i++) { 
    array[0][i] = '-'; 
    array[n - 1][i] = '-'; 
    } 
} 

這給這個可愛的矩形:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
-------------------------------------------------------------------------------- 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
|                    | 
-------------------------------------------------------------------------------- 

現在可以看到我給你的代碼所做的更改:

  1. 我擺脫了那個指向數組指針的,因爲它是 多餘的。
  2. 我將該陣列本身作爲參數傳遞給該函數,如 描述的here
  3. 除了使用幻數(21和80),所有的地方,我 宣佈兩個新的變量不變,nm,這是你的二維數組,n行×m列 尺寸。 *
  4. 我使用這些尺寸來實現迄今爲止實現的與您實現的邏輯 完全相同的邏輯。請注意,我必須將它們作爲參數 參數傳遞。

至於錯誤,它意味着你沒有訪問你認爲你正在訪問!但是讓我不要在這裏展開,並保持最小化。 :)


*現在,如果你想改變你的二維數組的大小,你只需要在你的代碼改變n和/或m一次,而不是到處(這是錯誤容易)。

+1

謝謝!正是我在找什麼! –

+0

做得好,可能值得引入OP語法,它允許你指定參數'char array [n] [m]'作爲'char(* array)[m]',它反映了第一級的轉換當數組作爲參數傳遞時,間接指向一個指針。 (也明確了爲什麼在函數內使用'sizeof'的任何嘗試都會失敗) –

+0

儘管我同意@DavidC.Rankin,但M.M的答案似乎觸及了這一點,我的答案已經很大.. :)謝謝! – gsamaras

0

如果有些人使用不支持可選的「變長數組」的功能(例如微軟編譯器)C編譯器,這裏是另一種方式:

void init(int rows, char (*array)[80]); 

    // ... in main ... 
    char grid[21][80]; 
    init(grid);   // use of grid_ptr is not required 
    // ... 

void init(int rows, char (*array)[80]) 
{ 
    int i,j; 
    for (i = 0; i < rows; i++) { 
     for (j = 0; j < 80; j++) { 
     array[i][j] = ' '; 

j循環中,您可以取代80sizeof *array。或者您可以用memset的電話替換整個j循環(實際上,兩個循環)。

+0

在沒有標準編譯器的情況下,我認爲應該做一個具有可變維度的「mangled」二維數組,「init(int rows,int cols,char * array)」或硬編碼的「幻數」數組:'init(char [21] [80])'。這似乎是這兩者的混合體。 – Lundin