#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3

    Qsort(): Do i need to convert to void myself ?


    >>convert*

    I've read an example of using qsort, in which the prototype shows us that the function is waiting for a void pointer to the first element of the array to be sorted.

    But i don't see where exactly they converted the pointer of values[] to a void pointer- it's just passed AS IT IS. Whereas the function is awaiting the "void *base".

    The same thing with the function that compares, which is passesd to qsort. It also awaits "const void*" whereas i pass integers to it.


    Code:
    void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
    Code:
    #include <stdlib.h>
    
    int values[] = { 88, 56, 100, 2, 25 };
    
    int cmpfunc (const void * a, const void * b)
    {
       return ( *(int*)a - *(int*)b );
    }
    
    int main()
    {
    
       qsort(values, 5, sizeof(int), cmpfunc);
    
     
      return(0);
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    > qsort(values, 5, sizeof(int), cmpfunc);
    Is the same as
    qsort(&values[0], 5, sizeof(int), cmpfunc);
    is the same as
    qsort((void*)&values[0], 5, sizeof(int), cmpfunc);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3
    But values is initially NOT a pointer to void. Then why is it still the same ?
    Doesn't it mean that i need to convert it to void ?
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,392
    Rep Power
    1871
    C supports round-trip T* -> void* -> T* without you having to do any explicit casting of pointer types.

    Recall that an array name (as an r-value) is just a pointer to the first element of the array.

    So the T* -> void* happens when you call qsort, and the void* -> T* happens in your compare function. You can then compare two elements of your original array knowing what type they are.

    qsort itself doesn't actually care what you have an array of. All it needs is a pointer to the start of the array, how many elements the array has, and how big each element is (that's why you pass sizeof(int)).



    Also, your compare code should look like this.
    Code:
    #include <stdlib.h>
    
    int values[] = { 88, 56, 100, 2, 25 };
    
    int cmpfunc (const void * a, const void * b)
    {
      const int *pa = a;
      const int *pb = b;
      if ( *pa < *pb ) return -1;
      if ( *pa > *pb ) return +1;
      return 0;
    }
    
    int main()
    {
      qsort(values, 5, sizeof(int), cmpfunc);
      return(0);
    }
    Your 1-liner might seem nice, but it will give you the wrong answer on numeric overflow.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3
    Thanks ! :)

IMN logo majestic logo threadwatch logo seochat tools logo