2011-08-23 6 views
4

C에서 다차원 배열에 대한 포인터 개념을 실험하고 있습니다. 함수를 통해 다차원 배열을 처리하려고한다고 가정합니다. 코드는 좀 다음과 같습니다 : 나는 proc_arr 내부 array에 액세스 할 때다차원 배열의 포인터가 C 언어로 작동하는 방법

#include <stdio.h> 

void proc_arr(int ***array) 
{ 
    // some code 
} 

int main(int argc, char **argv) 
{ 
    int array[10][10]; 
    for(int i = 0; i < 10; i++) 
    { 
     for(int j = 0; j < 10; j++) 
     { 
      array[i][j] = i * j; 
     } 
    } 

    proc_arr(&array); 

    return 0; 
} 

문제가있다, 난 할 수 없습니다.

void proc_arr(int ***array) 
{ 
    (*array)[0][1] = 10; 
} 

그래서 내가 그 주소로 이동하여 값을 얻으려면 컴파일러에게하는 array을 derefer : 나의 이해에서, 우리는 이런 식으로 접근해야한다. 그러나 어쨌든, 그것은 충돌합니다. *과 괄호의 여러 조합을 시도했지만 여전히 작동하지 않습니다. 나는 그것이 포인터와 포인터의 포인터를 이해하지 못하기 때문에 그것이라고 확신한다.

아, argv 및 envp와 마찬가지로 char ** (문자열 배열)로 작업하면 다르다는 것을 알았습니다. 하지만 envp에 대해서는 어떻게 든 (*envp)으로 액세스 할 수 있습니다. 왜?

여기 envp는을 procces 함수는 (그리고 일) :

int envplen(char ***envp) 
{ 
    int count = 0; 

    while((*envp)[count] != NULL) 
    { 
     count++; 
    } 

    return count; 
} 

또한, 나는 어떻게 든에만 envp으로 envplen 기능에 envp에 액세스,하지만 여전히 참조로 전달할 수 있습니까?

감사합니다.

답변

8

스택에 할당 된 int array[10][10]이 생각하는대로 메모리를 할당하지 않기 때문에 문제가 발생합니다. 이것은 배열이 포인터가 아니기 때문입니다. 메모리는 여전히 "2 차원"배열이 아닌 선형 배열로 배열됩니다 (위 첨자가 의미하는 바와 같음). 즉, int array[10][10]에 대한 메모리는 다음과 같습니다 : 당신이 암시 적으로 int***에 배열로 변환 한 다음 (* 배열)처럼 배열에 액세스하려고 그래서

starting address:         ending address: 
| Block_1 of 10 int | Block_2 of 10 int | ... | Block_10 of 10 int | 

[1] [10], 이것이 사실로 변환하는 것은 *(*((*array) + 1) + 10) 같은 것입니다, 이러한 작업의 메모리 레이아웃은 다음과 같이 메모리 설정을보고 싶어 :

int*** array 
| 
| 
| Pointer | 
| 
| 
| Pointer_0 | Pointer_1 | ... | Pointer 10 | 
     |   |     | 
     |   |     | Block of 10 int | 
     |   | 
     |   | Block of 10 int | 
     | 
     |Block of 10 int| 
+1

좋아, 나는 포인트를 가지고 있다고 생각한다 : 배열은 포인터가 아니다. 감사. – bertzzie

2

이 작동하지 않습니다 :

void proc_arr(int ***array) 
{ 
    (*array)[0][1] = 10; 
} 

장면 뒤에서 컴파일러는이를 배열 시작과 관련하여 메모리로의 오프셋으로 변경해야합니다. 즉, 배열의 크기를 알아야합니다. 함수 서명에 선언하지 않았습니다.

4

유형이 일치하지 않습니다. int array[10][10] 선언이 주어지면 &array 표현식의 유형은 int (*)[10][10], 이 아닌int ***이됩니다. 함수 프로토 타입을 읽으려는 경우

void proc_arr(int (*array)[10][10]) 

코드가 작성된대로 작동해야합니다.

다음 표는 특정 선언이있는 다양한 배열 식의 형식을 보여줍니다.

 
Declaration: T a[M]; 

Expression  Type    Decays To   
----------  ----    ---------   
     a  T [M]    T *    
     &a  T (*)[M]     

     *a  T       
     a[i]  T       

Declaration: T a[M][N]; 

Expression  Type    Decays To   
----------  ----    ---------   
     a  T [M][N]   T (*)[N]   
     &a  T(*)[M][N] 
     *a  T [N]    T * 
     a[i]  T [N]    T * 
     &a[i]  T (*)[N] 
     *a[i]  T 
    a[i][j]  T 

Declaration: T a[M][N][O]; 

Expression  Type    Decays To   
----------  ----    ---------   
     a  T [M][N][O]  T (*)[N][O] 
     &a  T (*)[M][N][O]  
     *a  T [N][O]   T (*)[O] 
     a[i]  T [N][O]   T (*)[O] 
    &a[i]  T (*)[N][O]  
    *a[i]  T [N]    T * 
    a[i][j]  T [N]    T * 
    &a[i][j]  T (*)[N] 
    *a[i][j]  T 
a[i][j][k]  T 

더 높은 차원의 배열 패턴은 명확해야합니다.

관련 문제