2010-03-29 3 views
9

호환되지 않는 포인터 : 다음과 같은 유형의나는 다음과 같은 서명 기능이 유형

void box_sort(int**, int, int) 

변수 :

int boxes[MAX_BOXES][MAX_DIMENSIONALITY+1] 

내가 함수를 호출하고

box_sort(boxes, a, b) 

GCC 나를 제공을 두 가지 경고 :

103.c:79: warning: passing argument 1 of ‘box_sort’ from incompatible pointer type (string where i am calling the function) 
103.c:42: note: expected ‘int **’ but argument is of type ‘int (*)[11] (string where the function is defined) 

질문이 인 이유는? int x [] []와 int ** x (실제로 int * x [])는 C에서 같은 타입이 아닌가?

+0

'MAX_BOXES' 및'MAX_DIMENSIONALITY '은 무엇입니까? 그것들은 매크로인가, 상수인가 ...? – Jacob

답변

13

나는이 질문을 거의 며칠 전과 같은 것으로 알고 있습니다 ... 지금은 그것을 찾을 수 없습니다.

대답은 int[size][] (하단 참고 참조)이며 int**은 분명히 같은 유형이 아닙니다. int[]int*을 많은 경우에 사용할 수 있습니다. 특히 함수에 전달할 때 배열이 첫 번째 요소에 대한 포인터로 붕괴하기 때문에 이와 같은 경우에 특히 그렇습니다. 그러나 2 차원 어레이의 경우, 이것들은 매우 다른 저장 방법입니다. 이 같은

int a[2][2]: 

__a[0][0]__|__a[0][1]__|__a[1][0]__|__a[1][1]__ 
    (int)  (int)  (int)  (int) 

int **a (e.g. dynamically allocated with nested mallocs) 

__a__ 
(int**) 
    | 
    v 
__a[0]__|__a[1]__ 
    (int*) (int*) 
    |  | 
    |  | 
    v  ------------------> 
__a[0][0]__|__a[0][1]__  __a[1][0]__|__a[1][1]__ 
    (int)  (int)    (int)  (int) 

당신이 만들 수있는 두 번째 :

int **a = malloc(2 * sizeof(int*)); 
a[0] = malloc(2 * sizeof(int)); 
a[1] = malloc(2 * sizeof(int)); 

주 : 다른 사람이 언급했듯이, int[][] ISN을 여기

은 2 × 2 배열 메모리에 같이 줄거야 '진짜 타입; 크기 중 하나만 지정 될 수 없습니다. 그러나 여기서 핵심은 2 차원 배열과 이중 포인터가 같은지 여부입니다.

+0

쿨 ASCII 아트를 참조하십시오. 그러나 화살표가 가리키는 상자의 첫 번째 인덱스가 잘못 생각한 것 같습니다. –

+0

@RaphaelISP : 감사합니다. 분명히 복사 붙여 넣기 오류입니다. – Cascabel

+0

나는 시각적 인 설명을 좋아한다. 나는 그들이 *와 []가 * {n}과 [] {n}을 위해 왜 상호 교환 적으로 일할 수있게 만들었는지 궁금합니다. 그것은 너무 어려웠습니까? – NomeN

1

서명에 필요한 포인터의 배열을 만들지 않았습니다.

C에서 2D 배열을 수행하는 데는 두 가지 방법이 있습니다. 한 가지 경우에는 방금 많은 것이 있으며 컴파일러에 차원이 무엇인지 알려줍니다. 행 인덱스에 열 수를 곱하여 행의 시작을 계산 한 다음 열 색인을 추가하여 해당 행의 요소를 찾습니다.

다른 방법은 포인터의 벡터를 사용하는 것입니다. 여기서 컴파일러는 행의 시작을 찾기 위해 벡터를 역 참조하지만 컴파일러가 자동으로이를 수행하지는 않습니다. 직접 수행해야합니다.

실제 개체는 첫 번째 종류 중 하나이지만 함수 프로토 타입은 두 번째 종류를 요구하고 있습니다.

따라서 프로토 타입을 개체와 일치하도록 변경하거나 함수에 전달할 행 포인터 벡터를 구성해야합니다.

+1

잘 설명해, DigitalRoss. 자세한 내용은 http://c-faq.com/aryptr/index.html –

1

int[][]과 같은 유형이 C에 없으며 다차원 배열의 첫 번째 부분 만 지정 될 수 없습니다. 그래서 int[][5]은 괜찮습니다.당신이 C99을 사용할 수 있다면, 당신은 당신이 원하는 것을 달성하기 위해 변수 배열을 사용할 수 있습니다, 여기에 게시 다른 답변에 추가

:

void box_sort(int N, int M, int x[M][N]); 

이 마이크로 소프트의 비주얼 C++를 제외하고 대부분의 플랫폼에서 작동합니다.

0

배열 표현식이 대부분의 컨텍스트에 나타나면 해당 유형이 "T의 N 요소 배열"에서 "T 포인터"로 암시 적으로 변환되며 해당 값은 배열의 첫 번째 요소 주소로 설정됩니다. 이 규칙의 예외는 배열 표현식이 sizeof 또는 address-of (&) 연산자의 피연산자이거나 배열식이 선언의 다른 배열을 초기화하는 데 사용되는 문자열 리터럴 인 경우입니다. 이 코드의 맥락에서 의미

box_sort로 호출, 식 boxes의 유형을 암시 그래서 당신의 기능과 같은 매개 변수 유형을 기대해야 M-element array of N-element array of int에서 pointer to N-element array of int, 또는 int (*)[MAX_DIMENSIONALITY+1]로 변환된다는 점이다 :

void box_sort(int (*arr)[MAX_DIMENSIONALITY+1], int x, int y) 
{ 
    ... 
} 
int *a 이후

int a[]int (*a)[N]int a[][N]과 동의어입니다 다음, 그래서 당신은

로 위를 작성할 수, 함수 매개 변수 선언의 동의어
void box_sort(int arr[][MAX_DIMENSIONALITY+1], int x, int y) 
{ 
} 

비록 내가 개인적으로 포인터 표기법을 선호하지만, 정확히 무엇이 진행되고 있는지를 반영하기 때문에. 함수에서, 당신은 정상으로 arr 첨자 것이 주 : 표현 arr[x]*(arr + x)에 해당합니다

arr[x][y] = ...; 

때문에, 포인터는 암시 적으로 역 참조. 당신은 임의의 크기의 배열을 작업 할 box_sort하려면

(즉, 두 번째 차원은 반드시 MAX_DIMENSIONALITY + 1없는 배열), 다음 한 가지 방법은 다음을 수행하는 것입니다 : 기본적으로

int boxes[X][Y]; 
... 
box_sort (&boxes[0], X, Y, x, y); 
... 
void box_sort(int *arr, size_t rows, size_t cols, int x, int y) 
{ 
    ... 
    arr[x*cols + y] = ...; 
} 

, 당신은 boxes을 int의 1-d 배열로 취급하고 수동으로 오프셋을 계산합니다.