2014-12-26 5 views
2

다음 코드 스 니펫은 K &에서 가져온 것입니다. 5-11 장 : 포인터 함수 :포인터 배열 (예 : * array [])을 캐스팅하는 경우 (void *) 대신에 (void *)를 사용하십시오.

qsort((void**) lineptr, 0, nlines-1, 
    (int (*)(void *, void *)(numeric ? numcmp : strcmp)); 

코드를 (void*)으로 컴파일/실행 할 수 있습니까? 그렇다면 (void **)으로 줄을 바꾸는 이유는 무엇입니까? 두 캐스트 사이에 내부적 인 차이점이 있습니까? 은 배열을 캐스팅하는 반면 (void **)은 배열과 저장된 포인터를 모두 캐스팅하고 있습니까?

나는 **lineptr*lineptr[]과 같음을 알고 있으며, void cast는 컴파일러를 행복하게 만드는 이유입니다.

+0

여기서 정렬은 배열에 저장된 포인터가 가리키는 데이터에 대해 수행됩니다. – haccks

+0

네, 캐스트가'(void **)'를 사용하여 포인터에 적용되는 것이지만'(void *)'캐스트는 배열에만 수행됩니까? – Kevin

+0

이 경우 캐스팅은'void **'로 수행됩니다. – haccks

답변

2

잘못된 것 같습니다.

void *는 가리키는 포인터입니다. 우리는 그것이 무엇을 가리키고 있는지 모른다. 모든 포인터를 void *로 캐스트 할 수 있습니다. qsort에 전달하는 비교 함수는 void *가 가리키는 실제 유형을 추측해야합니다. 네가 맞으면 괜찮아. 그것이 잘못되면, 일이 잘못 될 것입니다. 그것은 삶과 프로그래머의 책임입니다.

void **는 void * 배열에 대한 포인터입니다. 여기에 큰 차이가 있습니다 : 예를 들어 int *를 void *로 문제없이 변환 할 수있는 반면 int 배열은 이 아니며 void * 배열입니다. int *와 void *는 크기가 다를 수 있습니다! 는 C 표준은 매우 명확 포인터의 종류가 같은 표현이있는합니다 : 무효 *와 숯불 *의

  1. 어떤 변화 구조체에
  2. 모든 포인터 (무효 ** 하지 * 무효의 변형입니다)
  3. 노조에 대한 포인터
  4. 부호가 다른 기본 유형 (예 : int, unsigned int)에 대한 포인터입니다.

같은 그룹에없는 포인터는 다른 표현을 가질 수 있으므로 캐스트가 가능하지만 memcpy 또는 differnt 포인터 유형의 포인터를 통해 값을 읽는 것이 작동하지 않습니다.

+0

가장 틀린 말은 K & R에서 제공 한 코드를 말하는 것입니까? – Kevin

+0

두 번째 버전 인 [link] (http://www.iups.org/media/meeting_minutes/C.pdf)에있는 책을 읽었습니다. 또한'(void **) '캐스트는 배열의 포인터 만 캐스팅합니까? – Kevin

관련 문제