Originally Posted by
bvkim
Something I'm curious
1. why do i need to cast from void* to char*?
Because you cannot move a void pointer. For example, if p is a void*, then the compiler cannot evaluate the expression `p + i', because it has no information on p, and thus it would not know how many bytes to move.
On the other hand, char* represents a byte pointer. Therefore, you can move it exactly as many bytes as you need it. That's why you need to pass the size of the data type as the third parameter in qsort. It moves a byte pointer in multiples of `size' to access a particular element.
2. how can I compare the values in those `base` memory while I don't know what kind of type they are?
The user supplies a function to perform the comparison (Fourth argument in qsort). The function takes 2 void pointers and returns an integer: 0 if both arguments compare equal, a negative value if the first argument compares less than the second and a positive, non-zero value if the first argument compares greater than the second.
3. Would you mind giving me some samples?
Sure.
Code:
#include <stdio.h>
void compare_first_to_rest(void *ptr, size_t nelem,
size_t size, int (*cmp)(const void*, const void*)) {
unsigned i;
for(i = 1; i < nelem; ++i)
{
int res = cmp(ptr, (char*)ptr + i * size);
if(res < 0)
printf("First element is less than element at %u\n", i);
else if(res > 0)
printf("First element is greater than element at %u\n", i);
else
printf("First element is equal to element at %u\n", i);
}
}
int icmp(const void *x, const void *y) {
return *(int*)x - *(int*)y;
}
int main()
{
int x[] = { 5, 3, 6, 2, 4, 8, -1, 10 };
compare_first_to_rest(x, 8, sizeof(int), icmp);
}
As you can see, `compare_first_to_rest' doesn't know about the type of the elements it receives in its first argument. But knowing the size of each one, it can get a pointer to every one of them, and let the function pointer do the job.