2013-05-25 3 views
2

다음 ode 세그먼트의 출력은 9입니다. 함수 foo의 인수 a가 값으로 전달됩니다. 제 가정은 정확합니까? 그렇다면 출력이 9가되는 방법은 무엇입니까?함수에 인수 전달

#include <stdio.h> 

void foo(int[][3]); 

int main(void) 
{ 
    int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; 

    foo(a); 
    printf("%d\n", a[2][1]); 

    return 0; 
} 

void foo(int b[][3]) 
{ 
    ++b; 
    b[1][1] = 9; 
} 
+3

C에서 배열은 절대로 값으로 전달되지 않습니다. "array of T"형식의 인수는 "T에 대한 포인터"로 조정됩니다. –

+0

코드를 실행하면 8이됩니다! [** 라이브 데모 **] (http://ideone.com/j4LuMJ#li_j4LuMJ) – johnchen902

+1

와우, 많은 잘못된 대답. –

답변

2

함수 매개 변수 유형에 대한 [] 구문은 구문 식 설탕입니다. 이 경우 포인터는 함수 호출 컨텍스트에서 다른 배열을 사용할 때처럼 전달됩니다.

입니다
void foo(int (*b)[3]) 

, 그것은 세 가지 정수 배열에 대한 포인터를 받아 들인다 : 그것은 당신의 foo() 함수의 서명이 동일합니다 의미합니다. 이를 염두에두고 구현 내용이 무엇인지 살펴 보겠습니다. 먼저, ++b다음의 3 개의 정수 배열을 메모리에 가리 키도록 포인터를 진행시킵니다. 즉, b3 * sizeof(int)으로 향상됩니다. 프로그램의 경우, 이는 중간 행 a - { 4, 5, 6 } 행을 가리키고 있음을 의미합니다.

다음으로 새 b의 요소 [2][1]에 액세스합니다. 즉, 행 2,이 새로운 오프셋 논리 배열의 요소 1입니다. 이로 인해 프로그램이 a의 끝에 지나지 않은 주소에 쓰게됩니다. 이는 정의되지 않은 동작입니다. 이 단계에서는 모든 배팅이 해제됩니다. 프로그램의 출력은 일 수 있습니다.입니다.

당신이 그 라인을 변경하여 다시 정의 행동 얻을 수 있습니다 : 예를 들어

b[1][2] = 157; 

. 그런 다음 a[2][2]을 인쇄하여 main() 기능의 컨텍스트에서 변경 사항을 확인하십시오.

+0

어떻게 알 수 있습니까? – argentum47

+0

[comp.lang.c FAQ] (http://c-faq.com/)를 읽었습니다. –

+0

ABI에 따라 스택에 아무 ​​것도 누를 수 없습니다. 정확히 무엇을 요구하고 있습니까? –

0

컴파일러는 전체 어레이를 복사하지 않습니다. 값으로 전달하면 100000 요소의 배열을 전달하는 방법. 그래서 그것은 "포인터"으로 전달됩니다. 주소는 사본으로 추측됩니다. 그래서 주소의 내용을 바꾸면 원래 물건도 바뀔 것입니다.

은 포인터로 참조로 전달되는 것처럼 보입니다. 따르면

0

: foo에 대한 호출에 6.2.3.1/3 & 6.7.5.3/7

는 배열 식 도착은 그 유형이 암시 "로 변환된다를 sizeof & 또는 하나의 피연산자 아니다 배열의 int "에"포인터를 int "에 따라. 따라서 foo는 배열 값이 아닌 포인터 값을받습니다. 당신이하고있는 예상치 못한 여기 사람을 expected.Nothing로

void foo((*b)[3]) 
+0

아닙니다. 그것은'int (* b) [3]'로 변환됩니다. –

+0

수정 사항으로 인해 작업이 향상되었습니다. 당신은 지금 그 유형을 놓치고 있습니다. –

-1

프로그램의 출력은 8입니다 :

그래서 당신은 수행 할 때

void foo(int b[][3]) 

그것은 암시 적으로 변환되고 b이 증가한 후 b[2][1]=9에 을 a[3][1]에 쓰고 있습니다.의 출력에는 영향을 미치지 않습니다 으로 남아있는은 foo()에 전화하기 전후입니다.

http://ideone.com/eWFxht

당신은 확실히 출력을 다시 확인해야합니다.

+0

이 답변은 정확한 답변이지만 9를'a [3] [1]'에 쓰는 것은 정의되지 않은 행동입니다. OP의 프로그램은 그 경우에 9을 출력 할 수 있습니다. 그러나 왜 그런 일이 일어날 지에 대한 좋은 설명이 필요합니다. –

+0

@CarlNorum 사실! –