2017-02-06 4 views
0
#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    float *pf; 
    float m[][3]={ 
     {0.1, 0.2, 0.3}, 
     {0.4, 0.5, 0.6}, 
     {0.7, 0.8, 0.9} 
    }; 
    printf("%d \n",sizeof(m)); 
    pf=m[1]; 
    printf("%f %f %f \n",*pf, *(pf+1), *(pf+2)); 
    printf("%f %f %f \n",*pf, *(pf++), *(pf++)); 
} 

두 번째 마지막 printf의 출력을 이해합니다. 내가 틀렸다면 나를 바로 잡아주세요. 포인터 pf는 m [1]의 첫 번째 요소의 주소를 저장합니다. * pf는 첫 번째 요소로 이동하여 0.4, * (pf + 1) 증분을 출력하고 다음 요소 주소로 점프하고 그 요소를 출력합니다. 내가 얻지 못하는 것은 마지막 printf입니다. 비슷한 것이 아니어야합니다. 마지막으로 printf * pf가 pf에 저장된 주소 (m [1]의 첫 번째 요소와 동일)로 이동하므로 출력은 0.4가되어야하지만 대신 출력은 0.6입니다. * (pf ++)는 다음 요소로 증가하고 두 번째 요소, 즉 0.5를 출력하고 마지막 요소는 (pf ++)는 0.5를 출력해야하지만 대신 0.4를 출력해야합니다. 내가 정말로 혼란 스럽다고 설명해주세요.포인터가 1,2,3 또는 배열 증가 후 증가합니다.

+0

배열 크기는 항목 수가 아닌 바이트로보고됩니다. 귀하의 (더블) 배열은 각각 4 바이트에 9 개의 항목이 있습니다. – kaylum

+3

배열'm'에서 th 번째 항목을 얻으려면'sizeof (m)/sizeof (* m)'를 사용하십시오. –

+0

"* 나는 정말로 혼란 스럽다. *"그러나 포인터 때문이 아니라'++ '연산자가 어떻게 작동하는지 이해하지 못하는 것 같다. 그것에 대해 읽고'int', 배열 없음, 포인터가없는 간단한 예제로 돌아가십시오. – alk

답변

1

컴파일러는 어떤 순서로든 함수의 인수를 자유롭게 평가할 수 있습니다. 귀하의 경우, 컴파일러는 다음과 같은 순서로 인수를 평가하기로 결정했습니다 :

*pf, *(pf++), *(pf++) 
3rd 2nd  1st 
  1. 두 번째 *(pf++)가 먼저 평가됩니다. pf은 0.4를 가리키며, 이는 표현식의 값이며, 그 다음에 pf이 증가합니다.

  2. 첫 번째 *(pf++)은 두 번째로 평가됩니다. pf이 0.5를 가리키면 그 값이 표현식의 값이되고 pf이 증가합니다.

  3. *pf이 세 번째로 평가됩니다. pf은 0.6을 가리 킵니다.

  4. printf() 인쇄

    0.6 0.5 0.4 
    

코드는 정의되지 않은 동작의 고전적인 예이다.

+0

이러한 작업 사이에는 시퀀스 포인트가 없으므로 컴파일러는 코드 충돌 및 레코딩을 자유롭게하거나 고양이 사진을 인쇄 할 수 있습니다. 함수 인수의 평가 순서는 지정되지 않은 동작이지만이 코드에 정의되지 않은 동작이 포함 된 이유는 아닙니다. – Lundin

+0

그래서 그러한 진술의 결과를 예측할 방법이 없습니까? – peace9000

+0

@ peace9000 : 아니요. 함수 인수의 평가 순서 나 연산자의 피연산자 평가 순서가 중요한 경우에는 구조를 피하십시오. – AlexP