2012-04-07 9 views
7

내 교과서를보고 있는데 거기에있는 코드에 대해 약간 혼란 스럽습니다. 한 부분에서, 그들은 다음과 같은 방법으로 포인터 연산을 수행 :void * 대 char * 포인터 산술

void* bp; 
... 
bp = (void*)((char*)(bp)+16); 
... 

하지만 나중에, 그들은 다음을 수행을 :

void* bp; 
... 
bp = bp+16; 
... 

가 다른 두 가지해야 같은 느낌하지만이 치료된다 그것은 같은 것을 좋아합니다. 당신이 (예를 들어 정수 배열) 배열 액세스를 수행하는 경우, 예를 들어, 당신이이 경우에 다음

int* a = malloc(n*sizeof(int)); 
... 
q = *(a+1); 
... 

할 것, 때문에 나는 나는 다음에 접근하지 않는,이 방법을 느낀다 정수 배열에서 다음 바이트가 아닌 4 바이트? 마찬가지로 void * a를 사용하면 * (a + 1)이 다음 4 바이트가되어야한다고 생각합니다. 아니면 그렇지 않습니까? 감사합니다.

+0

두 번째 예제는 컴파일하지 말아야합니다. –

+1

@OliCharlesworth : 준수 모드로 컴파일하면 컴파일되지 않습니다 (또는 최소한 경고를 트리거합니다). gcc는 기본적으로 적합하지 않으며 확장으로'void *'산술을 구현합니다. –

답변

11

슬립 업입니다. void *의 산술 연산은 표준에 의해 정의되지 않지만 일부 컴파일러는이를 확장으로 제공하며 산술 연산에 대해서는 char *과 동일하게 동작합니다. 두 번째는 공식적으로 유효하지는 않지만 C (틀린) 습관을 벗어난 것으로 추정됩니다.

+0

다음 16 바이트를 액세스하는 적절한 방법은 먼저 char *로 변환 한 다음 16을 더하는 것입니다. 롤, 좋은 양의 코드를 지금 변경해야합니다. 오, 나는 첫 번째 것을 약간 잘못 베꼈고, ​​나는 약간의 변화를 만들었지 만, 그것이 내 질문에 변화를 줄 것이라고 생각하지 않는다. – de1337ed

+0

또는 'uint64_t *'로 캐스팅하고 2를 추가 할 수 있습니다.) 그렇습니다. 이식성있는 방법은 알려진 크기의 유형에 대한 포인터로 캐스팅하고 해당 연산을 수행하는 것입니다. 이식성이 필요없고 컴파일러가'void *'산법이 특정 방식으로 작동한다는 것을 문서화한다면, 그것을 사용할 수 있습니다. 물론 어떤 시점에서 다른 컴파일러로 포팅해야합니다 ... –