# Thread: how to use qsort

1. ## how to use qsort

Code:
```struct student
{
int id;
float score;
}s[3]{1,90},{2,80},{2,90}};
int cmp(const void *b,const void *a)
{
register struct  student *p1=(struct  student *)a;
register struct  student *p2=(struct  student *)b;

return (p1->id)>(p2->id)? 1:( (p1->id)<(p2->id) ? -1:0 );
}
qsort(s,10,sizeof(student),cmp);```
how to sort?
first: sort by id
second: if id equal. then sort by score

output:
2 90
2 80
1 90

2. zcrself 12-28-2009 12:45 PM
why no print?

train.h
Code:
//PARSEPARAarse para by step by step
int parseP(const char *a,float *p)
{
float start,end,step;
int pCount = 0;
int pNum = 0;
pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
//printf("start:[%f]\n",start);

if ( pNum < 3 )
{
printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
exit(0);
}
if ( end < start )
{
printf("Error: end must be more than start in [%s]\n",a);
exit(0);
} else if ( step <= 0 )
{
printf("Error: step must be more than 0 in [%s]\n",a);
exit(0);
}

//float j;
while ( start <= end )
{
*p = start;
start = start+step;
p++;
pCount++;
}

return pCount;
//printf("pNum:%f\n",step);
}
zero.cpp
Code:
#include "train.h"
int main( int argc,char *argv[])
{
float a[30] = {'\0'};
parseP("0-5-1",a);

for ( int i = 0; a[i] != '\0' ; i++ )
{
printf("a[%d]:%f\n",i,a[i]);
}
return 0;
}

If parseP("0-5-1",a); print is nothing
if parseP("1-5-1",a); print is as follows:
a[0]:1.000000
a[1]:2.000000
a[2]:3.000000
a[3]:4.000000
a[4]:5.000000

why ? how to solve this problem?

Use of for loop in the function main was incorrect

#include "stdio.h"
#include <stdlib.h>

int parseP(const char*,float*);

int main()// int argc,char *argv[])
{
int i;
float a[30] = {'\0'};
int count;
count = parseP("0-5-1",a);

for ( i = 0; i < count ; i++ )
{
printf("a[%d]:%f\n",i,a[i]);
}
return 0;
}

//PARSEPARAarse para by step by step
int parseP(const char *a,float *p)
{
float start,end,step;
int pCount = 0;
int pNum = 0;
pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
//printf("start:[%f]\n",start);

if ( pNum < 3 )
{
printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
exit(0);
}
if ( end < start )
{
printf("Error: end must be more than start in [%s]\n",a);
exit(0);
} else if ( step <= 0 )
{
printf("Error: step must be more than 0 in [%s]\n",a);
exit(0);
}

//float j;
while ( start <= end )
{
*p = start;
start = start+step;
p++;
pCount++;
}

return pCount;
//printf("pNum:%f\n",step);
}

3. You have not used the for loop correctly in the function main()

#include "stdio.h"
#include <stdlib.h>

int parseP(const char*,float*);

int main()// int argc,char *argv[])
{
int i;
float a[30] = {'\0'};
int count;
count = parseP("0-5-1",a);

for ( i = 0; i < count ; i++ )
{
printf("a[%d]:%f\n",i,a[i]);
}
return 0;
}

//PARSEPARAarse para by step by step
int parseP(const char *a,float *p)
{
float start,end,step;
int pCount = 0;
int pNum = 0;
pNum = sscanf(a,"%f-%f-%f",&start,&end,&step);
//printf("start:[%f]\n",start);

if ( pNum < 3 )
{
printf("Error:format of windowSize,K-value,noequalPunish and percentRatio must be start-end-step.\n");
exit(0);
}
if ( end < start )
{
printf("Error: end must be more than start in [%s]\n",a);
exit(0);
} else if ( step <= 0 )
{
printf("Error: step must be more than 0 in [%s]\n",a);
exit(0);
}

//float j;
while ( start <= end )
{
*p = start;
start = start+step;
p++;
pCount++;
}

return pCount;
//printf("pNum:%f\n",step);
}

4. Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
Code:
```//float j;
while ( start <= end )
{
*p = start;```
If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.

Quzah.

5. Originally Posted by quzah
Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
Code:
```//float j;
while ( start <= end )
{
*p = start;```
If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.

Quzah.
How to correct?

6. Originally Posted by quzah
Since you broke your own thread, and decided to take over this one with your own code, here is why yours doesn't work:
Code:
```//float j;
while ( start <= end )
{
*p = start;```
If start is 0, that means *p is given the value of zero. Since you are checking to see if zero is entered to stop your loop, the first element stops your loop. Read the top of the forum, and learn how to use code tags before you post again.

Quzah.
how to write cmp function to process two-dimensional sort?

7. I was going to write about stability, but then I noticed something. Why isn't id unique? The whole point of numerical ids is to serve as primary keys in databases. Please consider enforcing this.

Anyway, you need to pick another algorithm. Quoting you:

how to sort?
first: sort by id
second: if id equal. then sort by score
This is a problem for quick sort. It is not guaranteed to keep ids in order if it has to consider grades at all. A stable sort algorithm would keep ids in order even if it does sort by grade. Using a stable sort makes this no problem at all just sort by id and then by grade.

8. Originally Posted by whiteflags
I was going to write about stability, but then I noticed something. Why isn't id unique? The whole point of numerical ids is to serve as primary keys in databases. Please consider enforcing this.

Anyway, you need to pick another algorithm. Quoting you:

This is a problem for quick sort. It is not guaranteed to keep ids in order if it has to consider grades at all. A stable sort algorithm would keep ids in order even if it does sort by grade. Using a stable sort makes this no problem at all just sort by id and then by grade.
It would be a question of stability if he wanted items with equal "id" but different "score" members to remain in the same order they were relative to each other, prior to the sorting. However he hasn't asked that they remain in their existing order, he has asked that tie-breakers are furthur sorted by additional criteria.
He therefore does not need to pick another algorithm because this is not a question of stability here. It's simply a matter of coding up a suitable comparison function that considers multiple sort keys. Any non-stable sorting algorithm can do that just fine.

Here is one such comparison function that will do what was asked for:
Code:
```int cmp(const void *b, const void *a)
{
struct student *p1 = (struct student*)a;
struct student *p2 = (struct student*)b;

if (p1->id != p2->id)
return (p1->id < p2->id) ? -1 : 1;
if (p1->score != p2->score)
return (p1->score < p2->score) ? -1 : 1;
return 0;
}```
Note: Don't use the "register" keyword. It doesn't do anything useful.

What Hrishikesh posted does not belong in this thread at all and so is being ignored by me.
Guys, don't feed the thread hijackers eh!

9. Note: Don't use the "register" keyword. It doesn't do anything useful.
Doesnt it speeds up operations done on register declared objects by storing them into one of the registers? Atleast thats what i did read in K&R book.

10. The program may suggest "register", but it will not usually be followed. The compiler will optimize your code as it sees fit. Unless you're very good with assembly, it will do it better than you can.

Compilers used to be much more primitive than they are today - they have graduated and don't need any hints about what should go into a register and what shouldn't.

11. Originally Posted by Tool
Doesnt it speeds up operations done on register declared objects by storing them into one of the registers? Atleast thats what i did read in K&R book.
A compiler tries to put all the stuff that it knows should be in registers into registers only to perhaps find that you've told it to put some other stupid things into registers so that it doesn't have enough left for the important stuff, making it a whole lot slower.
'register' was only ever meant for those times where you've actually analysed the generated assembly and worked out the compiler didn't do things properly, and that using the keyword makes a positive difference in the resulting generated assembly after yet more analysis.
I say "was" because most compilers just ignore it now since too many people simply put it in code because they heard that it can speed things up, when it could often just make things worse if it has any effect at all.

I have only seen one usage of it that was known to have been beneficial, in the last 15 years, and that was not recently.

12. Originally Posted by iMalc
It would be a question of stability if he wanted items with equal "id" but different "score" members to remain in the same order they were relative to each other, prior to the sorting. However he hasn't asked that they remain in their existing order, he has asked that tie-breakers are furthur sorted by additional criteria.
He therefore does not need to pick another algorithm because this is not a question of stability here. It's simply a matter of coding up a suitable comparison function that considers multiple sort keys. Any non-stable sorting algorithm can do that just fine.

Here is one such comparison function that will do what was asked for:
Code:
```int cmp(const void *b, const void *a)
{
struct student *p1 = (struct student*)a;
struct student *p2 = (struct student*)b;

if (p1->id != p2->id)
return (p1->id < p2->id) ? -1 : 1;
if (p1->score != p2->score)
return (p1->score < p2->score) ? -1 : 1;
return 0;
}```
Note: Don't use the "register" keyword. It doesn't do anything useful.

What Hrishikesh posted does not belong in this thread at all and so is being ignored by me.
Guys, don't feed the thread hijackers eh!