The qsort () declaration looks like this:

void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); 

How do you work with the base pointer inside this function? The usual pointer can be shifted;

  a += 5// a += 5 * sizeof(*a); 

How can this be done knowing the size of the elements (size)?

  • a += 5 * size ? - VladD
  • But I do not think that there is a guarantee that the pointer will point to the element of the array, and not to its copy. So that address arithmetic doesn't make much sense. - VladD
  • Hmm .. Stop. Inside what kind of function? Inside the comparator or inside the inside of the qsort itself? - Qwertiy

3 answers 3

Actually, the void itself is not shifted, but lead it to a type that can be shifted - to a pointer to char.

Accordingly, your code becomes so

  char *pa = (char*)a; // вначале сделаем приведение a = a + 5 * sizeof(элемент); // а теперь можно свободно двигать 

In fact, everything can be viewed and studied independently. For example, here https://android.googlesource.com/platform/bionic.git/+/eclair-release/libc/stdlib/qsort.c

    It does not need to move. You just need to bring it to the pointer to the desired type (the one to which the compared objects belong) and continue to work with them.

      Here I wrote a small simple example on the example of "Custom sorting".

       #include <stdio.h> //выборочная сортировка void ssort(void* base, size_t num, size_t size, int (*cmp)(const void*,const void*)){ size_t t, i; char* a, *b, *p, *e, c; e = (char*)base + (size * num); for(a = (char*)base; a < e; a += size){ b = a; for(p = (char*)a + size; p < e; p += size){ if((*cmp)((const void*)p, (const void*)b) < 0) b = p; } if(a == b) continue; if(sizeof(size_t) == size){ t = *(size_t*)a; *(size_t*)a = *(size_t*)b; *(size_t*)b = t; } else { for(i = 0; i < size; ++i){ c = *(a + i); *(a + i) = *(b + i); *(b + i) = c; } } } } int icmp(const void* a, const void* b){//int return *(int*)a - *(int*)b; } int ccmp(const void* a, const void* b){//char return *(char*)a - *(char*)b; } int dcmp(const void* a, const void* b){//double double d1 = *(double*)a; double d2 = *(double*)b; if(d1 < d2) return -1; return (d1 > d2) ? 1 : 0; } int main(void){ int i; int a[] = { 4, 8, 3, 2, 0, 2, 1 }; int n1 = sizeof(a)/sizeof(a[0]); char b[] = { 'E', 'Z', 'C', 'F', 'B', 'D', 'A' }; int n2 = sizeof(b)/sizeof(b[0]); double c[] = { 1.2, 5.4, 1.2, 0.9, 0.2, 3.3, -7.1, 1.9, 1.2 }; int n3 = sizeof(c)/sizeof(c[0]); ssort(a, n1, sizeof(a[0]), &icmp);//int for(i = 0; i < n1; ++i) printf("%d ", a[i]); putchar('\n'); ssort(b, n2, sizeof(b[0]), &ccmp);//char for(i = 0; i < n2; ++i) printf("%c ", b[i]); putchar('\n'); ssort(c, n3, sizeof(c[0]), &dcmp);//double for(i = 0; i < n3; ++i) printf("%lg ", c[i]); return 0; } 

      ps an example without optimization, just cited for clarity