2014-07-20 1 views
2

'c/C++에서 매개 변수로 2 차원 배열을 사용하는 방법'을 검색했지만 이상한 점이 있습니다.** 연산자가 2 차원 배열에서 매개 변수로 작동하지 않습니다.

void print2darr3 (int row, int column, int **arr){ 
    int i,j; 
    for(i = 0; i<row ;i++){ 
      for(j=0 ; j<column ;j++){ 
       printf("%d ", **(arr++)) ; //printf("%d ", *(arr++)); WORKS WELL. 
      } 
      printf("\n"); 
    } 
} 

int main(void){ 
    int arr[3][3] = { 
         {10,20,30}, 
         {40,50,60}, 
         {70,80,90} 
        }; 

    print2darr3(3,3, arr); 
return 0; 
} 

이것은 내가 작성한 것입니다. 나는 이와 같은 결과를 내었다.

10 20 30 

40 50 60 

70 80 90 

그러나 내 코드는 작동하지 않는다.

놀랍게도, 내가 코드 printf("%d ", * (arr++));을대신 5 행으로 변경하면 잘 작동합니다.

이 상황을 이해할 수 없습니다.

arr[3][3]이 2 차원 배열이기 때문에 매개 변수로 int **arr을 작성했습니다.

따라서 각 요소를 인쇄하려면 printf("%d ", **(arr++))을 사용했습니다.

*이이 코드에서 왜 잘 작동하나요? ** 대신? (당신이 태그)

+7

C 스타일 2 차원 배열이 포인터를 가리키는 포인터가 아니기 때문에 이런 식으로 작동하지 않습니다. –

+1

코드에 컴파일러 경고 메시지가 표시되지 않습니까? – mafso

+1

'sizeof (int) == sizeof (int *)'일 때 작동합니다. 아마, 그것은 시스템이 아닌 경우에는 작동하지 않습니다. – BLUEPIXY

답변

4

배열. 이 기능이 더 일반적인하고 포인터 - 투 - 포인터 - 투 - INT (또는 int**) 유형에 대해 작업하려면

void print2darr3 (int col, int *arr[3]); // removed row because it is known to be 3. 

, 당신은을 만들어야합니다 : 당신은에 함수 헤더를 변경해야 배열을 동적으로. 이것은 malloc()/free() (C 언어)이고 new/delete (C++)입니다. 기술적으로 C++에서 malloc()을 사용할 수는 있지만 이것은 권장하지 않습니다.

int 
    nrows = 3, 
    ncols = 3; 

int **arr = malloc(nrows * sizeof(int*)); 
int i; 

for(i = 0; i < nrows; ++i) { 
    arr[i] = malloc(ncols * sizeof(int)); 
} 

// now you can use the arr as a 2D array in your original function 

print2darr3(nrows, ncols, arr); 

편집 @Neil이 코멘트에 지적

, 당신이 할당 한 메모리를하는 것이 중요합니다 :

여기 (C 아니라 C++에 대한) 예를 들어 입니다 malloc(). 그렇지 않으면 memory leak을 만듭니다. 이를 위해 free()을 사용합니다. 그건 당신이 사용하고 무엇처럼 나에게 보였다 때문에

for(i = 0; i < nrows; ++i) { 
    free(arr[i]); 
} 

free(arr); 

내가 C에 대한 대답 이유입니다. C++에서는 malloc()을 사용하는 것이 효과가 없습니다. 명시 적 캐스트가 필요하고 C/C++과 같은 언어가 없기 때문에 거의 호환되지만 완전히 호환되지는 않습니다.

+0

메모리를 확보하는 방법을 보여주지 않습니다. –

+0

나는 지금 당장 그것에 관해서 이야기 할 것이다. 코멘트 주셔서 감사합니다! –

2

C++ 솔루션 첫 번째 차원을 넘어 포인터에 적응하지 않는 함수 인수로 전달

void print2darr3 (const vector<vector<int>>& arr){ 
    int i,j; 
    for(i = 0; i<arr.size() ;i++){ 
      for(j=0 ; j<arr[i].size() ;j++){ 
       printf("%d ", arr[i][j]) 
      } 
      printf("\n"); 
    } 
} 

int main(void){ 
vector<vector<int>> arr = { 
        {10,20,30}, 
        {40,50,60}, 
        {70,80,90} 
       }; 

print2darr3(arr); 
} 
+2

그것이 문제를 해결하는 동안 OP의 코드가 작동하지 않는 이유를 설명하지 못합니다. 그걸 설명하고 싶지 않을까요? – Borgleader

1

당신이 함수에 전달 배열

int arr[3][3]; 

에게있는 경우는 첫 번째 차원 포인터에 "붕괴"를 의미한다.그것은 쇠퇴하는 첫 번째 차원 일 뿐이므로 int **arr (포인터에 대한 포인터 또는 포인터 배열) 대신 매개 변수로 int (*arr)[3] (3 개 요소의 배열에 대한 포인터 또는 각각의 배열에 대한 포인터 그 중 3 개 요소 포함).

좀 더 자세한 내용은 here이 있고 Question 6.18 of the comp.lang.c FAQ은 훨씬 더 좋습니다.)하지만 배열 배열/포인터 배열과 배열 간의 차이점을 이해하는 것이 중요합니다. 포인터/포인터 - 투 - 포인터.

0

배열은 포인터가 아닙니다!

그들은 단지 자동으로 첫 번째 요소에 대한 포인터로 강등됩니다. 우리가 int arr[2]이있는 경우 예를 들어


은 다음 arr 메모리에 두 개의 연속하는 int를 나타냅니다, 그리고 첫 번째 요소에 대한 포인터로 강등됩니다 (그래서 int*를 입력했다) :

  arr ---+  +--- arr + 1 
       v  v 
memory: ... | arr[0] | arr[1] | ... 


그러나 우리가 int arr[2][2] 인 경우 arr은 메모리에서 네 개의 연속 int를 나타내며 첫 번째 요소에 대한 포인터로 강등됩니다 (따라서 형식은,463,210) 한편, 우리는 명확성을 위해 추가 int *(arr[2]) 괄호()를 가지고 있다면, arr 메모리에 두 개의 연속 INT 포인터 배열을 나타내고,이 강등 도착

  arr ---+   arr + 1 ---+ 
        v      v 
memory: ... | arr[0][0] | arr[0][1] | arr[1][0] | arr[1][1] | ... 


첫 번째 요소의 포인터 (그래서 갖는다 int** 입력)

  arr ---+  +--- arr + 1 
       v  v 
memory: ... | arr[0] | arr[1] | ... 
       |  |  
      ... -+  +- ... 



,174,

print2darr3은 세 번째 예제와 비슷하지만 두 번째 예제와 비슷한 것을 제공합니다.

#include <stdio.h> 

void print2darr3(int rows, int columns, int *arr) { 

    int i,j; 

    for (i = 0; i < rows ; i++) { 
     for (j = 0; j < columns; j++) { 
      printf("%d ", arr[i * columns + j]); 
     } 
     printf("\n"); 
    } 
} 

int main(void) { 

    int linear_array[3][3] = { 
     {10,20,30}, 
     {40,50,60}, 
     {70,80,90}, 
    }; 

    print2darr3(3, 3, (int*)linear_array); 
    return 0; 
} 


또는 :

#include <stdio.h> 

void print2darr3(int rows, int columns, int **arr) { 

    int i,j; 

    for (i = 0; i < rows ; i++) { 
     for (j = 0; j < columns; j++) { 
      printf("%d ", arr[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main(void) { 

    int linear_array[3][3] = { 
     {10,20,30}, 
     {40,50,60}, 
     {70,80,90}, 
    }; 

    int *pointer_array[3] = { 
     (int*)(linear_array + 0), 
     (int*)(linear_array + 1), 
     (int*)(linear_array + 2), 
    }; 

    print2darr3(3, 3, pointer_array); 
    return 0; 
} 
또한


이, C (그러나 C++에서)에서 당신이 할 수있는

당신은 어느 길을 갈 수 있습니다 :

#include <stdio.h> 

void print2darr3(int rows, int columns, int arr[rows][columns]) { 

    int i,j; 

    for (i = 0; i < rows ; i++) { 
     for (j = 0; j < columns; j++) { 
      printf("%d ", arr[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main(void) { 

    int linear_array[3][3] = { 
     {10,20,30}, 
     {40,50,60}, 
     {70,80,90}, 
    }; 

    print2darr3(3, 3, linear_array); 
    return 0; 
} 
관련 문제