2013-07-10 5 views
2

qsort인데 배열 v의 각 멤버가 sizeof(void *)을 차지하는 경우 qsortsizeof(int)을 사용해야하는 이유는 무엇입니까?qsort void 포인터에 대한 포인터가

#include <stdio.h> 
#include <stdlib.h> 

int comp(const void *pa, const void *pb) 
{ 
    int a = *(int *)pa; 
    int b = *(int *)pb; 

    if (a > b) 
     return +1; 
    else 
    if (b > a) 
     return -1; 
    else 
     return 0; 
} 

int main(void) 
{ 
    int i, a[] = {3, 1, 2, 0, 4}; 
    void **v; 

    v = malloc(sizeof(void *) * 5); 
    for (i = 0; i < 5; i++) { 
     v[i] = &a[i]; 
    } 
    for (i = 0; i < 5; i++) { 
     printf("%d\n", *(int *)v[i]); 
    } 
    qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void ** 
    printf("Sorted:\n"); 
    for (i = 0; i < 5; i++) { 
     printf("%d\n", *(int *)v[i]); 
    } 
    free(v); 
    return 0; 
} 
+0

David : 코드에서'v [i] = &a[i];'표현식을 이해하고 있습니까? 왜 이것이 필요하며 왜'v'가'void *'입니까? –

+0

@GrijeshChauhan, 다른 유형을 정렬하기 위해 void ** (일반 컨테이너의 추상화로서)를 사용해야합니다. –

+1

'[[]]을 정렬하기 때문에'v [i] = & a [i]'가 필요합니다. 'array, 그러나'qsort()'호출에서 배열'a [] '의 타입을 포함하지 않는'v'를 넘겨 주므로'a [i]'요소가'int'라는 내용 정보를 명시 적으로 전달합니다 . –

답변

6
qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void ** 

에게 메모리 블록의 시작 어드레스는 qsort 전달할 것으로 분류

v[0] = &a[0] 

a 초기 요소의 어드레스이기 때문에, 정렬 배열되었음을 될 a이고 초기 요소 인 v이 가리키는 블록이 아닙니다. a의 요소는 int입니다. 따라서 sizeof(int)이 올바른 크기입니다.

포인터의 배열을 정렬하려면 해당 배열의 첫 번째 요소 주소 인 &v[0] 또는 vqsort으로 전달해야합니다. 그리고 물론 크기 인수가 sizeof (void*)해야합니다 :

qsort(v, 5, sizeof(void*), cmp); 

하지만 대한

, 당신은 당신이 가지고있는 비교 기능을 사용할 수 없습니다, 당신은 유사한

int cmp(const void *pa, const void *pb) { 
    int a = *(int*)(*(void**)pa); 
    int b = *(int*)(*(void**)pb); 

    if (a > b) 
     return +1; 
    else 
    if (b > a) 
     return -1; 
    else 
     return 0; 
} 

또는 뭔가가 필요합니다. qsort에서 비교 함수로 전달되는 값은 비교할 항목의 주소이므로 비교할 포인터를 얻으려면 간접 참조가 필요하며 여기서부터는 포인터가 가리키는 값을 int 값으로 비교하기 위해 두 번째 포인터가 필요합니다. 지시를 받기위한 간접 참조 - int s.

+0

하지만 비교가 여전히 올바르지 않습니까? –

+0

아니요,'qsort'는'size' 매개 변수를 통해 계산 된'& a [i]'와'& a [j]'를'comp'에 전달하므로 맞습니다. 의도 된 것이 아닐 수도 있습니다 - 의도가 포인터의 배열을 정렬하는 것이라면 - 그러나 그것이 나온 것처럼 코드는 정확합니다. 아마도 실수로. –

+0

예, 나는 & a [i]'와'& a [j]'가 비교 자로 전달된다는 것을 알고 있습니다. * 정확하게 * 혼란 스럽습니다 ... 나는 그것이 어떻게 올바른지 보지 못합니다. 간접 ... 어쩌면 내가 주위에 교수형 대신 낮잠을해야한다 :) –

관련 문제