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

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0

    Qsort parameters and compare function


    I have to sort the elements of an array using this function, but I'm having some trouble when it comes to the parameters.

    Let me show what I understood from some reading:

    The function should appear like this:

    void qsort (void* base, size_t num, size_t a, int (*compar)(const void*,const void*))
    Where, "base" is the pointer I used previously on malloc.

    "num" should be the number of elements in the array and "a" the size of each, in this case, structure in the array, where "a" received "a" = sizeof(structurename).

    My structure has a string, an integer and a double.

    But the last part, should be a function to compare two elements and decide wich one goes first. The thing is, I have some specific criterea to sort the array of structures using specific data as "tie-breakers", so basically, from what I've read, I'd want to put the tie-breakers in the case where it would return 0.

    The problem is, I can't get how to get the function to compare two structures because of the "const void*" part, whenever I try it, I get an error like if the conversion (from void to struct.type) would give a non-scalar value. I think it it's still being a pointer or something, but I can't figure out.

    int compar (const void * a, const void * b)
    {
    if ( *(stru.integer*)a < *(stru.integer*)b ) return -1;
    if ( *(stru.integer*)a > *(stru.integer*)b ) return 1;
    if ( *(stru.integer*)a == *(stru.integer*)b ) return 0; (gonna add the tie-brekaers with an "if" instead of return 0 later)
    }
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    It would be something like
    Code:
    int compar (const void * a, const void * b)
    {
        const structurename *pa = a;
        const structurename *pb = b;
        if ( pa->a < pb->b ) return -1;
    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
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0
    Originally Posted by salem
    It would be something like
    Code:
    int compar (const void * a, const void * b)
    {
        const structurename *pa = a;
        const structurename *pb = b;
        if ( pa->a < pb->b ) return -1;
    I tried this, but since I didn't understand the concept I couldn't write something that worked as I wished. From now, this is what I got, please if someone could explain me what concept is wrong at this, it'd be really helpful.

    The structure:
    Code:
    struct data {
        char string[8];
        int intnumber;
        double floatnumber;
    };
    typedef struct data data;
    In main: (Just to make sure I'm using the paremeters correctly and showing what is "r").
    Code:
        r = calloc(sizeof(data)*size); //Size is an int previously assigned.
        
        void qsort (void* r, size_t size, size_t sizeof(data), int (*compar)(const void*,const void*));
    Then the compare function:

    Code:
        int compar (const void * a, const void * b){
        const data *c = a;
        const data *d = b;
        if ( *c.intnumber <  *d.intnumber ) return -1;
        if ( *c.intnumber >  *d.intnumber ) return 1;
        if ( *c.intnumber == *d.intnumber ) return 0;
    }
    The parameters are void pointers, so I created new pointers c and d, wich are not void, but pointers to the "data" structure.

    Then I tried to access the "intnumber" variable in "data", from the structures pointed by c and d and compare them.

    I get the error: request for member 'intnumber' in something not a structure or union.
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    > if ( *c.intnumber < *d.intnumber ) return -1;
    Which is why I used the -> operator.

    You can either have
    c->intnumber
    or, if you use () to get the precedence right,
    (*c).intnumber
    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
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0
    Originally Posted by salem
    > if ( *c.intnumber < *d.intnumber ) return -1;
    Which is why I used the -> operator.

    You can either have
    c->intnumber
    or, if you use () to get the precedence right,
    (*c).intnumber
    It works now, thank you. So, the problem was trying to use *c.intnumber as a pointer to a data.intnumber, where it was declared as a pointer to data.

IMN logo majestic logo threadwatch logo seochat tools logo