2011-10-06 5 views
5

나는 다음과 같은 테스트 응용 프로그램이 있습니다C에서 char *가 char **와 동일하게 취급되는 이유는 무엇입니까?

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 

int main(void){ 
    char buf[512]; 
    buf[0]= 0x1; 
    buf[1]= 0x2; 
    char *temp1 = &buf; 
    char *temp2 = buf; 
    char *temp3 = &buf[0]; 
    printf("temp1:%p, temp2:%p, temp3:%p\n",temp1,temp2,temp3); 
    printf("0 = %d, %d, %d\n",temp1[0],temp2[0],temp3[0]); 
    printf("1 = %d, %d, %d\n",temp1[1],temp2[1],temp3[1]); 
    return; 
} 

그것은 경고와 함께 컴파일 :

을하지만 그것을 실행할 때, 세 개의 포인터가 같은 동작합니다.

./testptr 
temp1:0x7fff3a85f220, temp2:0x7fff3a85f220, temp3:0x7fff3a85f220 
0 = 1, 1, 1 
1 = 2, 2, 2 

나는 buf == &buf[0],하지만 왜 &buf == &buf[0]을한다는 것을 알아? &bufchar**이 아니어야합니까?

+1

'& buf'는 실제로'char (*) [512]'(512 항목'char' 배열에 대한 포인터)입니다. 그들은 거의 같지 않습니다. –

+0

컴파일러 출력을 캡처하고 코드를 질문에 붙여 넣는 것 사이에서 코드를 변경했습니다. 문제는 9 번 라인에 있습니다. –

+0

죄송합니다. 새 라인을 추가했습니다. – austinmarton

답변

3

모든 포인터는 동일하게 동작합니다. C는 유형이 정적으로 유형 지정되므로 유형은 변수가 아닌 값에 바인드됩니다.

이제 동작 부분에 대해 설명 했으므로 실제로 (% p printf에 따라) 동일한 값을 갖는 이유를 알아야합니다. 글쎄, 이것은 GCC에 의해 메모리 주소로 구현되는 포인터의 인공물 일뿐입니다 (오프셋과 크기 조정은 ** 모든 것은 타입 시스템/컴파일러에 의해 처리됩니다).경고를 내리는 가장 의심스런 것들처럼, 이것은 정의되지 않은 행동이거나 나쁜 습관 일 가능성이 높습니다.

2

배열은 포인터가 아니며 대부분 동일한 방식으로 사용할 수 있습니다. 배열과 포인터의 의미가 다른면이 하나 있습니다.

+0

[recv] (http://linux.die.net/man/2/recv) 함수에 실수로'void *'형의 두 번째 인수로'buf' 대신에'& buf'를 전달했을 때 이것을 발견했습니다 . 위의 예에서 설명하지는 않았지만 이것이 문제를 일으킬 수 있습니까? – austinmarton

+0

@austinmarton : 나는 C 컴파일러 경고에 관해서 편집증의 편에서 실수하는 것을 선호한다 – hugomg

+0

@missingno : 공정한 호출. 원래 응용 프로그램에서는 실수가 void 포인터로 전달되어 경고가 생성되지 않았습니다. – austinmarton

1

*& 연산자의 대수에서 해결할 수 있습니다.

  • 우리 bufbuf 배열의 0 번째 요소의 주소 우리 &buf[0]는 정의에 의해 0 번째 요소

  • 주소임을 알

  • 것을 알고 buf[0]*(buf+0)

  • &(*(a))은와 동일합니다..

그래서, &buf[0]buf입니다 &(*(buf+0))이된다.

업데이트 여기

,의는 증거로 배치 할 수 있습니다.

  1. &buf[0] 주어진. C와 우선 순위 규칙
  2. &(buf[0])()의
  3. &((*(buf+0)))buf[0] == *(buf+0) 때문이다. 당신이 char*가 될 그들 모두를 선언하기 때문에
  4. &(*(buf+0)) 제거 불필요한 괄호
  5. buf QED
+3

나는 당신이 말하는 것에 동의한다. ('buf == & buf [0]') 그러나 이것은 내가 요구하는 것이 아니다. ('& buf == buf'?). – austinmarton

+0

@ austinmarton, 다음 단계를 따르십시오 : 그것들은 예,'& buf'가'buf'와 동일하다는 증거입니다. –

+1

@Charlie : 아니요, 증명에 따르면'& buf [0]'은'buf'와 동일합니다.'& buf'는'buf'와 동등하지 않습니다. 이것은 질문에 대한 질문이었습니다. – icktoofay

1

컴파일러가 실제로 어떤 코드를 생성하는지 생각해 보면 배열을 처리하면 더 명확 해집니다. buf라는 이름은 배열의 첫 번째 (0 번째) 요소의 주소 (문자를 포함하기위한 인접한 공간)를 참조합니다. 심볼 테이블의 "buf"항목에서 객체를 보면 첫 번째 요소의 주소를 찾을 수 있습니다. 예를 들어, buf [0]을 참조하면 컴파일러는 buf의 주소와 char의 크기의 0 배를 생성합니다. 이것은 buf 자체의 주소와 동일하게 발생합니다.

관련 문제