### Thread: Qsort parameters and compare function

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. 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;```
3. 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.
4. > 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
5. 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.