2012-07-20 235 views
0

我可以使用一維數組的指針作爲函數的指針,但是我不知道對於二維數組使用相同的技巧。C:二維數組的指針

這裏是我的示例代碼:

 int main(){ 
      int b[10]; //initialize b 
      Print(b); 
      int a[10][10]; //initialize a 
      Print2(a); 
     } 

     void Print(int*b){ 
      for(int i=0; i<10; i++) 
       printf("%d\n",*(b+i)); 
     } 

    // I want to use same technique here 
    // but i have met error 

     void Print2(int*a){ 
      for(int i=0; i<10; i++) 
       for(int j=0; j<10; j++) 
        printf("%d\n",*(*(a+i)+j)); // error at this line 
     } 

請幫助我如何使用一維數組的相同的技術二維數組。

謝謝:)

回答

1

損壞內部*並用10乘以我再添加J任務

printf("%d\n",*((a+i*10)+j)); 

,因爲在一個二維矩陣要 「向下」,你在這個經歷尺寸-1(10例如)元素。

用於3D:

printf("%d\n",*(a+i*100+j*10+k)); 

用於N-尺寸:

*(a+i*(size of i-dimension)+j*(size of j dim)+......+last index) 
1

b是整數數組,所以它的第一個元素是一個int。當b衰減到指向其第一個元素的指針時,結果因此爲int*(這就是您的Print函數接受的內容)。

a是一個數組的數組,因此它的第一個元素是一個數組。當a衰減到一個指向它的第一個元素,其結果因此是一個指針到陣列的-10-整數:

void Print2(int (*a)[10]){ // pointer-to-array type 
    for(int i=0; i<10; i++) 
     for(int j=0; j<10; j++) 
      printf("%d\n",a[i][j]); 
} 

多維數組只能得到在C到目前爲止,因爲當你通過他們只有第一維是可變的。其餘維度需要在編譯時知道,因爲它們是指針類型的一部分。如果你需要多維可變的東西,你可以像tuğrulbüyükışık的回答那樣「變平」,並使用一維數組。

1

事情是,一個數組衰減到一個指針,但是一個二維數組衰減到一個指向特定大小數組的指針。

#include "stdio.h" 

void print(int *arr); 
void print2D(int (*arr)[]); 

int main() { 
    int data[5] = {1, 2, 3, 4, 5}; 
    print(data); 

    int data2D[5][5]; 
    for (int i = 0; i < 5; i++) { 
     for (int j = 0; j < 5; j++) { 
      data2D[i][j] = (i + 1) * 10 + (j + 1); 
     } 
    } 
    print2D(data2D); 
} 

void print(int *arr) { 
    for (int i = 0; i < 5; i++) { 
     printf("%d\n", arr[i]); 
    } 
} 

void print2D(int (*arr)[5]) { 
    for (int i = 0; i < 5; i++) { 
     for (int j = 0; j < 5; j++) { 
      printf("%d\n", arr[i][j]); 
     } 
    } 
} 

在這裏,您可以看到,我在二維函數中將數組聲明爲一個指向5個元素數組的指針。現在當我增加i時,編譯器知道我想跳過五個元素。您可以run this example at Ideone

當然,您可以手動完成。在這種情況下,你將不得不自己計算地址。在這種情況下,該功能將是這樣的:

void print2D(int *arr) { 
    for (int i = 0; i < 5; i++) { 
     for (int j = 0; j < 5; j++) { 
      printf("%d\n", *(arr + (i * 5) + j)); 
     } 
    } 
} 

你將不得不這樣調用它:

print2D(data2D[0]); 

The second example on Ideone

+0

我不清楚最後一個例子是否有效。我認爲它可能是,但詹姆斯Kanze(C + +大師)認爲它可能不是。 IIRC的理由是它違反了嚴格的走樣。它還在指針算術表達式中使用指向data2D [0]的第一個元素的指針,該表達式超出data2D [0]的範圍。 – 2012-07-20 09:02:06

+0

@SteveJessop如果你想要最後一個例子是絕對正確的,使用'&data2D [0] [0]'。這是第一個元素的純粹地址。至於什麼樣的選擇,我同意最好使用第一個例子,這就是爲什麼它是第一個例子。指針運算只能在真正需要時才使用。 – Malcolm 2012-07-20 09:17:13

+0

@SteveJessop你有一個關於詹姆斯的帖子在這個問題上的鏈接。這令我感到驚訝,因爲大多數人會同意你的觀點:「data2D [0]」是正確的(或者大多數已經被教導過,因爲它返回一個整數數組,像任何數組一樣,它衰變成指向其第一個元素的指針, 「int」) – Larry 2012-07-20 12:26:19

1
 #include <stdio.h> 

     void Print(int*b) 
     { 
     int i; 
      for(i=0; i<10; i++) 
       printf("%d\n",*(b+i)); 
     } 


     void Print2(int*a) 
     { 
      int i,j; 
      for(i=0; i<10; i++) 
      { 
       printf("\n"); 
       for(j=0; j<10; j++) 
        printf("%d\t",*(a+(i*10)+j)); // Modification done here. 
      } 
     } 

     int main() 
     { 
      int b[10]; //initialize b 
      Print(b); 
      int a[10][10] = {}; //initialize a 0 
      Print2((int*)a); 
      return 0; 
     } 

我修改了Print2()。

添加(1D陣列的大小*哪個1D陣列將被訪問(I))+ 特別是在一維陣列(j)的元素陣列的基地址。