Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A qsort problem...

10 views
Skip to first unread message

Roger E. Browning

unread,
May 24, 2000, 3:00:00 AM5/24/00
to
This is my first time working with qsort. I have an array of 10 integers
and would like to sort them in ascending order. Easy enough right? I am
thoroughly missing something though. Here is the code:

#include<stdio.h>
#include<stdlib.h>
#define MAX 10

int my_compare(const void *value, const void *value2);
int (*function_ptr)(const void *, const void *);

int main(void)
{
int index;
int int_array[MAX] = {2, 5, 9, 3, 1, 7, 4, 6, 0, 8};
function_ptr = my_compare;

qsort(int_array, MAX, sizeof(int), function_ptr);

for(index = 0; index < MAX; index++)
printf("%d", int_array[index]);
printf("\n");
return(0);
}


int my_compare(const void *value1, const void *value2)
{
return ((*(int*)value1), (*(int*)value2));
}

It compiles and runs fine, but the numbers are not sorted. Just shuffled
around a bit. I am not making the comparison correctly, right?

Thanks,
Roger
--
Roger E. Browning
jast...@mac.com


R124c4u2

unread,
May 24, 2000, 3:00:00 AM5/24/00
to
Roger E. Browning writes:

You are correct, Sir!

One would expect to see either a < or > in your return statement in
my_compare(). You seem to expect some magical properties form the comma
operator.

Brian B. Rodenborn

unread,
May 24, 2000, 3:00:00 AM5/24/00
to
In article <B551B7F1.11962%rbda...@earthlink.net>,

Roger E. Browning <rbda...@earthlink.net> wrote:
>This is my first time working with qsort. I have an array of 10 integers
>and would like to sort them in ascending order. Easy enough right? I am
>thoroughly missing something though. Here is the code:
>
>int my_compare(const void *value1, const void *value2)
>{
> return ((*(int*)value1), (*(int*)value2));
>}
>

This comparison function is way off. What you want is one that behaves
as follows:

returns an integer < 0 when *value1 < value2
0 when *value1 == value2
an integer > 0 when *value1 > value2


I think you perhaps were thinking of using ? in your return statement,
but even then the syntaxt wouldn't be correct. The comma operator
definitely won't do what you want.

Don't try to get tricky when you are still learning. Use a simple
if () else if () else construct to implement the above requirements.

Jordan Katz

unread,
May 24, 2000, 3:00:00 AM5/24/00
to
"Roger E. Browning" <rbda...@earthlink.net> writes:

[snip]


> int my_compare(const void *value1, const void *value2)
> {
> return ((*(int*)value1), (*(int*)value2));
> }
>

> It compiles and runs fine, but the numbers are not sorted. Just shuffled
> around a bit. I am not making the comparison correctly, right?

Right. You're not comparing the values at all, you're just returning
the rightmost one. Try:

int my_compare(const void *value1, const void *value2)
{

return (*(int*)value1) > (*(int*)value2);
}
--
Jordan Katz <webm...@underlevel.net>

John Gordon

unread,
May 24, 2000, 3:00:00 AM5/24/00
to
Jordan Katz <webm...@underlevel.net> writes:

>int my_compare(const void *value1, const void *value2)
>{
> return (*(int*)value1) > (*(int*)value2);
>}

the qsort comparison function is supposed to return less-than-zero,
zero, or greater-than-zero. it doesn't look like the above function
does that.

---
"... What with you being his parents and all, I think that you could
be trusted not to shaft him." -- Robert Chang, rec.games.board

John Gordon gor...@osiris.cso.uiuc.edu

Martin Ambuhl

unread,
May 25, 2000, 3:00:00 AM5/25/00
to

"Roger E. Browning" wrote:
>
> This is my first time working with qsort. I have an array of 10 integers
> and would like to sort them in ascending order. Easy enough right? I am
> thoroughly missing something though. Here is the code:


Here is a correction:
24c24
< return ((*(int *)value1), (*(int *)value2));
---
> return (*(int *)value1 - *(int *)value2);

>
> #include<stdio.h>
> #include<stdlib.h>
> #define MAX 10
>
> int my_compare(const void *value, const void *value2);
> int (*function_ptr)(const void *, const void *);
>
> int main(void)
> {
> int index;
> int int_array[MAX] = {2, 5, 9, 3, 1, 7, 4, 6, 0, 8};
> function_ptr = my_compare;
>
> qsort(int_array, MAX, sizeof(int), function_ptr);
>
> for(index = 0; index < MAX; index++)
> printf("%d", int_array[index]);
> printf("\n");
> return(0);
> }
>

> int my_compare(const void *value1, const void *value2)
> {

> return ((*(int*)value1), (*(int*)value2));
> }
>
> It compiles and runs fine, but the numbers are not sorted. Just shuffled
> around a bit. I am not making the comparison correctly, right?
>

> Thanks,
> Roger
> --
> Roger E. Browning
> jast...@mac.com

--
Martin Ambuhl mam...@earthlink.net

What one knows is, in youth, of little moment; they know enough who
know how to learn. - Henry Adams

A thick skin is a gift from God. - Konrad Adenauer

Amit Kaushik

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
> #include<stdio.h>
> #include<stdlib.h>
> #define MAX 10
>
> int my_compare(const void *value, const void *value2);
> int (*function_ptr)(const void *, const void *);
>
> int main(void)
> {
> int index;
> int int_array[MAX] = {2, 5, 9, 3, 1, 7, 4, 6, 0, 8};
> function_ptr = my_compare;
>

Why do you need to assign to function_ptr use my_compair directly
as an argument.

>
> qsort(int_array, MAX, sizeof(int), function_ptr);

qsort(int_array,MAX,sizeof(int),my_compair);

>
> for(index = 0; index < MAX; index++)
> printf("%d", int_array[index]);
> printf("\n");
> return(0);
> }
>
> int my_compare(const void *value1, const void *value2)
> {
> return ((*(int*)value1), (*(int*)value2));

return( * (int*)value1 - *(int*)value2)

Al Bowers

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
In article <392C9DC9...@earthlink.net>,

Martin Ambuhl <mam...@earthlink.net> wrote:
>
>
> > int my_compare(const void *value1, const void *value2)
> > {
> > return ((*(int*)value1), (*(int*)value2));
> > }

> Here is a correction:
> 24c24
> replace return ((*(int *)value1), (*(int *)value2));
> ---
> with return (*(int *)value1 - *(int *)value2);
>

Replacing with the above will work in most cases and certainly with the
values currently in the array example, but it is hazardous in that you
can have int overflow or underflow. For example if value1 = INT_MIN,
value2 = 1, the result of the operation value1 - value2 would underflow
type int. Some implementations will not gracefully handle this
underflow.

It would be best to us the if-else or ?: operator.

int my_compare(const void *v1, const void *v2) {

return *((int *)v1)<*((int *)v2)?-1:*((int *)v1)>*((int *)v2);
}


--
Al Bowers
http://www.geocities.com/abowers822
mailto:abo...@combase.com
C-faq: http://www.eskimo.com/~scs/C-faq/top.html
GIBCO Labs.
Tampa FL. USA.


Sent via Deja.com http://www.deja.com/
Before you buy.

Richard Heathfield

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
Al Bowers wrote:
>
> In article <392C9DC9...@earthlink.net>,
> Martin Ambuhl <mam...@earthlink.net> wrote:
> >
> >
> > > int my_compare(const void *value1, const void *value2)
> > > {
> > > return ((*(int*)value1), (*(int*)value2));
> > > }
>
> > Here is a correction:
> > 24c24
> > replace return ((*(int *)value1), (*(int *)value2));
> > ---
> > with return (*(int *)value1 - *(int *)value2);
> >
>
> Replacing with the above will work in most cases and certainly with the
> values currently in the array example, but it is hazardous in that you
> can have int overflow or underflow. For example if value1 = INT_MIN,
> value2 = 1, the result of the operation value1 - value2 would underflow
> type int. Some implementations will not gracefully handle this
> underflow.
>
> It would be best to us the if-else or ?: operator.
>
> int my_compare(const void *v1, const void *v2) {
>
> return *((int *)v1)<*((int *)v2)?-1:*((int *)v1)>*((int *)v2);
> }
>


More elegant would be:

int my_compare(const void *v1, const void *v2)
{

const int *i1 = v1;
const int *i2 = v2;

return *i2 > *i1 ? -1 : *i1 > *i2;
}

at the expense, admittedly, of a couple of extra variables.

I can't help thinking it's clearer without the casts.


--

Richard Heathfield

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.

C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
37 K&R Answers: http://users.powernet.co.uk/eton/kandr2/index.html (60
to go)

mike burrell

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
Richard Heathfield <bin...@eton.powernet.co.uk> wrote:
> int my_compare(const void *v1, const void *v2)
> {
> const int *i1 = v1;
> const int *i2 = v2;

const int * const i1 = v1;
const int * const i2 = v2;

> return *i2 > *i1 ? -1 : *i1 > *i2;
> }

making them const might get your compiler to get rid of them easier.

--
/"\ m i k e b u r r e l l
\ / ASCII RIBBON CAMPAIGN mik...@home.com
X AGAINST HTML MAIL
/ \

ke...@hplb.hpl.hp.com

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
In article <B551B7F1.11962%rbda...@earthlink.net>,

"Roger E. Browning" <rbda...@earthlink.net> writes:
> This is my first time working with qsort. I have an array of 10 integers
> and would like to sort them in ascending order. Easy enough right? I am
> thoroughly missing something though. Here is the code:
>
> int my_compare(const void *value1, const void *value2)
> {
> return ((*(int*)value1), (*(int*)value2));
> }

Wouldn't it help to use `<` instead of `,`?

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html

Dann Corbit

unread,
May 25, 2000, 3:00:00 AM5/25/00
to
<ke...@hplb.hpl.hp.com> wrote in message
news:8girhb$h2b$1...@murdoch.hpl.hp.com...

> In article <B551B7F1.11962%rbda...@earthlink.net>,
> "Roger E. Browning" <rbda...@earthlink.net> writes:
> > This is my first time working with qsort. I have an array of 10
integers
> > and would like to sort them in ascending order. Easy enough right? I
am
> > thoroughly missing something though. Here is the code:
> >
> > int my_compare(const void *value1, const void *value2)
> > {
> > return ((*(int*)value1), (*(int*)value2));
> > }
>
> Wouldn't it help to use `<` instead of `,`?

Probably not.

The comparison function pointed is called with two arguments that point to
the key object and to an array element, in that order. The function shall
return an integer less than, equal to, or greater than zero if the key
object is considered, respectively, to be less than, to match, or to be
greater than the array element.

Now, I don't see how changing the comma to a greater than test might return
a negative number.

And (for any additional suggestions) -- no dirty subtraction tricks please.

Don't forget the Kirby cutie:
return (x > y) ? 1 : (x < y) ? -1 : 0;

1.5 comparisons on average and cute as a bug.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. Newsgroup http://www.dejanews.com/~c_a_p
C.A.P. FAQ: ftp://38.168.214.175/pub/Chess%20Analysis%20Project%20FAQ.htm

Richard Heathfield

unread,
May 26, 2000, 3:00:00 AM5/26/00
to
ke...@hplb.hpl.hp.com wrote:
>
> In article <B551B7F1.11962%rbda...@earthlink.net>,
> "Roger E. Browning" <rbda...@earthlink.net> writes:
> > This is my first time working with qsort. I have an array of 10 integers
> > and would like to sort them in ascending order. Easy enough right? I am
> > thoroughly missing something though. Here is the code:
> >
> > int my_compare(const void *value1, const void *value2)
> > {
> > return ((*(int*)value1), (*(int*)value2));
> > }
>
> Wouldn't it help to use `<` instead of `,`?


Not if the array is already sorted. :-)

Roger E. Browning

unread,
May 26, 2000, 3:00:00 AM5/26/00
to
in article B551B7F1.11962%rbda...@earthlink.net, Roger E. Browning at
rbda...@earthlink.net wrote on 5/24/00 4:47 PM:

> This is my first time working with qsort. I have an array of 10 integers
> and would like to sort them in ascending order. Easy enough right? I am
> thoroughly missing something though. Here is the code:
>

> #include<stdio.h>
> #include<stdlib.h>
> #define MAX 10
>
> int my_compare(const void *value, const void *value2);
> int (*function_ptr)(const void *, const void *);
>
> int main(void)
> {
> int index;
> int int_array[MAX] = {2, 5, 9, 3, 1, 7, 4, 6, 0, 8};
> function_ptr = my_compare;
>

> qsort(int_array, MAX, sizeof(int), function_ptr);


>
> for(index = 0; index < MAX; index++)
> printf("%d", int_array[index]);
> printf("\n");
> return(0);
> }
>
>

> int my_compare(const void *value1, const void *value2)
> {
> return ((*(int*)value1), (*(int*)value2));
> }
>

> It compiles and runs fine, but the numbers are not sorted. Just shuffled
> around a bit. I am not making the comparison correctly, right?
>
> Thanks,
> Roger

Thanks for the quick responses and answers. Through everyone's good
suggestions and knowledge, I have a greater understanding of qsort. I used
a subtraction math operator to get the results I was looking for.

Once again, thanks

Roger


Al Bowers

unread,
May 26, 2000, 3:00:00 AM5/26/00
to
In article <392D8C5B...@eton.powernet.co.uk>,
Richard Heathfield <bin...@eton.powernet.co.uk> wrote:


> More elegant would be:


>
> int my_compare(const void *v1, const void *v2)
> {
> const int *i1 = v1;
> const int *i2 = v2;
>

> return *i2 > *i1 ? -1 : *i1 > *i2;
> }
>

> at the expense, admittedly, of a couple of extra variables.
>
> I can't help thinking it's clearer without the casts.
>

You might as well go ahead and make the extra variables type const int
and take care of the dereferencing with their declaration.

int my_compare(const void *v1, const void *v2) {

const int i1 = *((const int *)v1);
const int i2 = *((const int *)v2);

return (i1 < i2) ? -1 : (i1 > i2);

Larry Jones

unread,
May 26, 2000, 3:00:00 AM5/26/00
to
Dann Corbit (dco...@solutionsiq.com) wrote:
>
> Don't forget the Kirby cutie:
> return (x > y) ? 1 : (x < y) ? -1 : 0;
>
> 1.5 comparisons on average and cute as a bug.

I still like:

return (x > y) - (x < y);

It's two comparisons (although most current architectures allow a clever
compiler to get away with just one in either case), but it's shorter and
has a nice symmetry.

-Larry Jones

Years from now when I'm successful and happy, ...and he's in
prison... I hope I'm not too mature to gloat. -- Calvin

Chris Mears

unread,
May 27, 2000, 3:00:00 AM5/27/00
to
On 26 May 2000 15:58:31 GMT, that hoopy frood Larry Jones wrote:

>Dann Corbit (dco...@solutionsiq.com) wrote:
>>
>> Don't forget the Kirby cutie:
>> return (x > y) ? 1 : (x < y) ? -1 : 0;
>>
>> 1.5 comparisons on average and cute as a bug.
>
>I still like:
>
> return (x > y) - (x < y);
>
>It's two comparisons (although most current architectures allow a clever
>compiler to get away with just one in either case), but it's shorter and
>has a nice symmetry.

I find Lawrence's version easier to read. I read it as "if x > y,
return 1, if x < y, return -1, otherwise return 0." It's just my
preference, of course.

--
Chris Mears
ICQ: 36697123
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Lawrence Kirby

unread,
May 27, 2000, 3:00:00 AM5/27/00
to
In article <8gm6v7$p...@nfs0.sdrc.com> larry...@sdrc.com "Larry Jones" writes:

>Dann Corbit (dco...@solutionsiq.com) wrote:
>>
>> Don't forget the Kirby cutie:
>> return (x > y) ? 1 : (x < y) ? -1 : 0;
>>
>> 1.5 comparisons on average and cute as a bug.

My original "cutie" was

return (x < y) ? -1 : (x > y);

which has a nice symmetry. The main problem is whether with real usage
a 1 result is more likely than -1.

>I still like:
>
> return (x > y) - (x < y);
>
>It's two comparisons (although most current architectures allow a clever
>compiler to get away with just one in either case), but it's shorter and
>has a nice symmetry.

Yes, with conditional move or similar instructions it could be very good.
If the compiler generated conditional tests and branches it may not be
so good. The compiler might be able to recognise it anyway and generate
special code with whatever is available, maybe shift with carry and
that sort of thing. The important thing in that case would be to write
code that the compiler recognises as this speciic operation.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------


0 new messages