2011-12-15 2 views
7

문제의 코드입니다C 포인터 산술는 sizeof (구조체) 여기

#include <stdio.h> 

struct test { 
    unsigned char t; 
    unsigned short u; 
    unsigned char v; 
}; 


int main() 
{ 
    struct test * a = (void *) 0x1000; 

    printf("%x %p %p\n", 
      sizeof(struct test), 
      a + sizeof(struct test), 
      a - sizeof(struct test)); 

    return 0; 
} 

sizeof의 (구조체 테스트) 6 인쇄, 그래서 나는 을 기대 :

6 0xffa 0x1006

대신 내가 얻을

6 0x1024 0xfdc 

지난 시간 I c 0x24, 또는 36은 여섯과 같지 않았습니다. 내가 말할 수있는 어떤 것과조차 일치하지 않습니다. 나는 완전한 상실감에 처해있다.

누군가이 값을 얻는 이유를 설명해 줄 수 있습니까?

답변

16

문제는 포인터 연산을 수행 할 때 데이터 단위 크기의 복수만큼 증가한다는 것입니다.

그럼 효과적으로하는 것은 sizeof(struct test)의 제곱으로 추가하는 것입니다.

sizeof(struct test) = 6부터 주소를 6 * 6 = 36까지 증가시킵니다. 따라서 0x10060xffa 대신 0x10240xfdc이 나오는 이유는 무엇입니까? (당신은 또한 +- 전환,하지만 작은 일입니다.)

를 대신 그냥이 수행

printf("%x %p %p\n", 
     sizeof(struct test), 
     a + 1, 
     a - 1); 
1

입력 포인터가 있습니다.

내 1을 늘리면 (즉, a + 1) 이는 a + sizeof(type)을 의미합니다.

그래서 = a + sizeof(type) * sizeof(type) = a + 6 * 6a + sizeof(type) (귀하는 sizeof (시험 등의 경우) = 6)

당신이에서 0x24 36를 얻고있는 곳입니다

.

2

난 당신이 a + 1a - 1을 찾고 생각합니다.

(a + x)&a[x]입니다.

+2

'* (a + x)'가'a [x]'와 같거나'(a + x)'가'& a [x]'와 같다고 말하고 싶을 것입니다. –

4

이와 같이 포인터 연산을 수행하면 해당 변수가 배열에있는 것처럼 해당 수만큼 앞이나 뒤로 이동합니다. 따라서 실제로는 a + 1a - 1을 사용하려고합니다. 매번 6 바이트 씩 진행해야합니다.

중요 : 컴파일러는 정렬에 도움이되도록 구조체에 패딩을 추가 할 수 있습니다. 그냥 2 바이트의 1 바이트 문자와 2 바이트 길이의 구조체가 4 바이트 크기가되기 때문에 가정하지 마십시오. 여기서는 그렇지 않습니다. (사실 char 또는 short의 크기를 알고 있다고 가정하지 말고 이전에 2 바이트 문자를 보았습니다.)

+3

실제로 그것은 정확하지 않습니다.배열 요소 사이에 패딩을 추가 할 수 없습니다. 그것이 할 수있는 일은 구조체의 요소들 사이와 구조체의 마지막 요소 뒤에 패드를 두는 것입니다 (이것은 아마도 당신이 언급하고있는 비트 일 것입니다). 그러나 정렬 요구 사항이있는 경우 구조체 자체가 올바른 크기로 채워집니다. 여기서는 6 바이트가 'char (1), pad (1), short (2), char (1), pad (1)'이지만 마지막 패딩은 단일 구조체 요소에 속하며, 그 구조체로 구성된 배열의 요소 중 _ 요소가 아닙니다. Nitpick 모드 해제 :-) – paxdiablo

+1

감사합니다. C99 사양을 살펴본 후 제 응답을 다시 언급했습니다. –