2013-08-08 2 views
2

여기서는 무슨 일이 일어나고 있는지 정확하게 해석하고 싶습니다. 32 비트 환경에서 컴파일되고 스택에 선언 된 다음 코드 스 니펫을 고려하십시오.포인터 포인터가 같은 포인터 (배열 첨자가 정수가 아님)

// Declares an array of integers with a length of 10. 
int arr[ 10 ] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

// Performs some pointer arithmetic. 
int result = arr[ arr + 2 ]; 

이제 C에서 대괄호를 사용하는 것은 다음에 대한 별칭 일뿐입니다.

*(...) 

이렇게 별칭을 지정하면 스 니펫이 다음과 같이 변환됩니다.

int result = *(arr + arr + 2); 

지금, 나의 해석은 포인터 연산이 편곡의 주소를 더한 정수의 크기를 곱한 2, 플러스 편곡의 주소로 평가하는 것입니다. 따라서, 결론은 arr이 할당하지 않은 메모리를 가리킨다는 것입니다. 결과는 약간의 가비지 값이됩니다.

그러나 clang과 gcc로 컴파일 할 때 "배열 첨자가 정수가 아닙니다."라는 오류 메시지가 나타납니다. 왜 이런 경우이고 내 해석은 어디에서 잘못 되었습니까?

+1

할 수 있습니다하지 인덱스 포인터와 배열. –

+1

크기 10의 배열에는 11 개의 요소가 있습니다. – Undefined

+0

(C가 표현식을 "평가"하는 방식과 유효한 구문을 고려한 것은 서로 다른 두 가지입니다.) –

답변

8

배열 첨자는 정수가 아닙니다. 포인터 (의 정수를 산출)

  • 포인터 + 정수 (포인터를 수득)
  • 포인터 - - 정수 (포인터를 수득)

    • 포인터 :

      포인터 연산은 제한된다.

    결과에 대해 합당한 의미가 없으므로 포인터 값을 두 개 추가 할 수 없습니다.

    arr[ arr + 2 ] 무엇을 할 것으로 예상 했습니까? 업데이트 : 나는 당신이 그것을 언급 한 것을 본다; 당신은 그것이 어떤 쓰레기 주소를 참조하기를 기대했습니다. 이것은 언어로 인해 가비지가 생성되는 것을 방지하는 경우입니다. 모든 경우에 그렇게하기를 기대하지 마십시오.

  • +0

    당신의 대답은 pointer + -/* 포인터 산술은 C에서 정의되지 않은 것으로 간주됩니다 (그리고 각각 컴파일러 레벨에서 처리됩니다)? –

    +0

    @JacobPollack : 예, 오류는 컴파일 타임에 처리됩니다. 구조체와 공용체를 추가하거나 정수를 호출하는 것과 같은 제약 조건 위반입니다. 당신은 그것을 "불법"이라고 생각할 수 있지만, 언어 표준은 그런 식으로 표현하지 않습니다. (준수하는 컴파일러는 제약 조건이나 구문 규칙을 위반하는 번역 단위에 대해 하나 이상의 진단 메시지를 발행해야합니다.이 진단은 단순한 경고 일 수 있습니다.) –

    +0

    감사합니다. 하나 더 질문을 명확히 할 수 있습니까? 그것이 두 포인터의 뺄셈을 수행하는 것이 타당한 것으로 보이는 이유는 무엇입니까? 둘 다 같은 무의미한 결과를 낳지는 않겠습니까? 그렇지 않다면 나를 반증 할 사건을 제공 할 수 있습니다. –

    0

    한 글자를 제외하고 코드가 작동해야합니다! 에서 [] 내의 요구 값은 정수 간접 참조하기 때문에 도착 + 2 =

    이 결과를 생성한다
    // Declares an array of integers with a length of 10. 
    int arr[ 10 ] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
    
    // Performs some pointer arithmetic. 
    int result = arr[ *(arr + 2) ]; 
    

    도착 [2]; 따라서 result = 2

    Eclipse/Microsoft C 컴파일러에서이 결과를 얻었습니다.

    마지막으로 arr + 2의 관습은 K & R에서 논의되었으므로 수행하려는 작업에는 전혀 문제가 없습니다. 그냥 재미있는 시도에 대한

    : int result = *(arr + *(arr + 2));