2011-04-10 2 views
38

포인터 값은 변수의 주소입니다. 왜 int pointer의 값이 int 포인터가 1 씩 증가한 후에 4 바이트 씩 증가 했는가?왜 int 포인터 '++'가 1이 아닌 4 씩 증가합니까?

제 의견으로는 포인터의 값 (변수의 주소)은 포인터 증가 이후에만 1 바이트 씩 증가한다고 생각합니다.

시험 번호 :

int a = 1, *ptr; 
ptr = &a; 
printf("0x%X\n", ptr); 
ptr++; 
printf("0x%X\n", ptr); 

예상 출력 :

0xBF8D63B8 
0xBF8D63B9 

실제로 출력 :

0xBF8D63B8 
0xBF8D63BC 

EDIT :

다른 질문 - int이 하나씩 4 바이트를 방문하는 방법?

답변

92

T*을 증가 시키면 sizeof(T) 바이트가 이동합니다. 다른 값을 이동하는 것이 의미가 없기 때문입니다. 예를 들어 int 크기가 4 바이트 인 경우 4를 늘리면 4를 버리시겠습니까? 일부 다른 데이터와 혼합 된 부분 int : 무의미합니다.


메모리에 이것을 고려 :

나는 그 포인터를 증가 할 때 더 의미가
[↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

?이 :

  [↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

또는이 :

 [↓  ] 
[...|0 1 2 3|0 1 2 3|...] 
[...|int |int |...] 

마지막 실제로 int의 어떤 종류를 가리 키지 않습니다. (기술적으로, 다음, 그 포인터를 사용하여 UB입니다.) 당신이 정말로이 한 바이트를 이동할 경우 char* 증가

:

int i = 0; 
int* p = &i; 

char* c = (char*)p; 
char x = c[1]; // one byte into an int 

: char의 크기는 항상 하나입니다 † void이 불완전한 유형이기 때문에 void*을 증가시킬 수 없다는 결론이 나옵니다. 포인터 포인트는 char 경우는 1234 바이트 구조체를 가리키는 경우

+0

"'void'는 불완전한 타입이기 때문에'void *'를 증가시킬 수 없습니다. - true이지만 gcc는'void *'를 확장으로 처리합니다 (마치'char *'처럼 취급합니다). –

+0

"거의 이해할 수 없다"정수의 경우, 가변 길이 구조의 배열과 같은 상황에서는 완벽한 의미를 갖습니다 ("버퍼가 가득 찼습니다. 다음 패킷으로 CurrentPacketPointer를 이동하려고합니다. 패킷"). –

+0

"실제로 1 바이트 이동하려면 char *를 증가 시키십시오. char의 크기는 항상 1입니다."아니 항상 1이 아니므로 대신 uint8_t를 사용해야합니다. – Winter

8

포인터 증가는 가리키는 유형의 크기를 기반으로합니다. int 형이게 2.

하여 그 값을 증가 (1)에 의해 짧은 * 증가, 단 2 바이트 인 경우 4.

하여 그 값을 증가 1의 int *를 증가, 4 바이트이면 C 포인터 연산에 대한 표준 동작.

+0

나는 그가 그 이론적 근거를 요구하고 있다고 생각한다. – GManNickG

+0

그 이유는 포인터 연산이 항상 pointee 유형의 단위로 작동한다는 것이 확실합니다. –

+0

이유는 * 왜 * 그럴 수 있습니다. – GManNickG

1

포인터가 증가한 후에 포인터는 메모리의 다음 int를 가리 킵니다. int는 4 바이트 폭이므로 4 바이트 씩 증가합니다. 일반적으로 T 타입에 대한 포인터는 sizeof (T)만큼 증가합니다.

1

int pointerint을 가리 킵니다. int은 일반적으로 4 바이트를 차지하므로 포인터를 증가 시키면 메모리의 "다음"int (즉 4 바이트 씩 증가)을 가리 킵니다. 그것은 모든 유형의 유형에 대해 이러한 방식으로 작동합니다. A을 입력 할 포인터가 있다면 A*으로 증가하고 sizeof(A)만큼 증가합니다.

생각해보십시오. 포인터를 1 바이트 씩 늘리면, int의 중간을 가리키며 원하는 곳에서 생각할 수 없습니다.

이 동작은 예를 들어 배열을 반복 할 때 매우 편리합니다.

2

포인터는, pointer++ 1로 포인터를 증가시킬 것이다, 그들이 가리키는 타입의 크기에 의해 증가, pointer++는 1234

하여 포인터를 증가합니다

이것은 처음 만날 때 혼란 스러울 지 모르지만 실제로는 상당한 프로세서 기능은 아니지만 컴파일러가 컴파일 중에 계산하므로 pointer+1을 쓸 때 컴파일러는 컴파일러를 pointer + sizeof(*pointer)

으로 컴파일합니다
관련 문제