Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #75113 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-11-06 08:20 -0800 |
| Last post | 2015-11-10 02:07 +0100 |
| Articles | 20 on this page of 50 — 22 participants |
Back to article view | Back to comp.lang.c
Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-06 08:20 -0800
Re: Program to sort three integers Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-06 11:32 -0500
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 00:20 -0800
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-07 11:04 +0000
Re: Program to sort three integers "Osmium" <r124c4u102@comcast.net> - 2015-11-06 10:34 -0600
Re: Program to sort three integers "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-06 08:37 -0800
Re: Program to sort three integers supercat@casperkitty.com - 2015-11-06 10:36 -0800
Re: Program to sort three integers Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 19:17 +0000
Re: Program to sort three integers supercat@casperkitty.com - 2015-11-06 11:30 -0800
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 01:01 -0800
Re: Program to sort three integers "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-06 11:48 -0800
Re: Program to sort three integers David Brown <david.brown@hesbynett.no> - 2015-11-06 23:15 +0100
Re: Program to sort three integers "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-06 14:39 -0800
Re: Program to sort three integers Keith Thompson <kst-u@mib.org> - 2015-11-06 15:57 -0800
Re: Program to sort three integers Nick Bowler <nbowler@draconx.ca> - 2015-11-06 22:33 +0000
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 16:39 +0000
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 00:22 -0800
Re: Program to sort three integers Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 16:45 +0000
Re: Program to sort three integers "Bill Davy" <Bill@SynectixLtd.com> - 2015-11-06 18:30 +0000
Re: Program to sort three integers Keith Thompson <kst-u@mib.org> - 2015-11-06 11:36 -0800
Re: Program to sort three integers Bartc <bc@freeuk.com> - 2015-11-06 19:50 +0000
Re: Program to sort three integers Keith Thompson <kst-u@mib.org> - 2015-11-06 12:52 -0800
Re: Program to sort three integers Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-09 13:36 +0000
Re: Program to sort three integers David Brown <david.brown@hesbynett.no> - 2015-11-09 15:41 +0100
Re: Program to sort three integers raltbos@xs4all.nl (Richard Bos) - 2015-11-10 16:56 +0000
Re: Program to sort three integers Keith Thompson <kst-u@mib.org> - 2015-11-10 09:11 -0800
Re: Program to sort three integers supercat@casperkitty.com - 2015-11-10 09:15 -0800
Re: Program to sort three integers Les Cargill <lcargill99@comcast.com> - 2015-11-10 19:37 -0600
Re: Program to sort three integers asetofsymbols@gmail.com - 2015-11-06 11:52 -0800
Re: Program to sort three integers Bartc <bc@freeuk.com> - 2015-11-06 20:01 +0000
Re: Program to sort three integers asetofsymbols@gmail.com - 2015-11-06 12:21 -0800
Re: Program to sort three integers "Osmium" <r124c4u102@comcast.net> - 2015-11-06 14:23 -0600
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 20:58 +0000
Re: Program to sort three integers Mark Storkamp <mstorkamp@yahoo.com> - 2015-11-06 16:04 -0600
Re: Program to sort three integers Mark Storkamp <mstorkamp@yahoo.com> - 2015-11-06 16:08 -0600
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 22:49 +0000
Re: Program to sort three integers Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-10 16:04 -0800
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-11 21:51 +0000
Re: Program to sort three integers bartekltg <bartekltg@gmail.com> - 2015-11-11 23:50 +0100
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 22:52 +0000
Re: Program to sort three integers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-07 01:17 +0000
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 01:24 -0800
Re: Program to sort three integers Chad <cdalten@gmail.com> - 2015-11-07 02:04 -0800
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 00:57 -0800
Re: Program to sort three integers Barry Schwarz <schwarzb@dqel.com> - 2015-11-06 10:14 -0800
Re: Program to sort three integers Richard Heathfield <rjh@cpax.org.uk> - 2015-11-06 18:27 +0000
Re: Program to sort three integers Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-06 11:22 -0800
Re: Program to sort three integers Alla _ <modelling.data@gmail.com> - 2015-11-07 01:15 -0800
Re: Program to sort three integers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-07 00:57 -0800
Re: Program to sort three integers bartekltg <bartekltg@gmail.com> - 2015-11-10 02:07 +0100
Page 1 of 3 [1] 2 3 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-06 08:20 -0800 |
| Subject | Program to sort three integers |
| Message-ID | <8dcd1ed2-2734-4cff-b013-d713a33100ed@googlegroups.com> |
Hello!
Here is the description of the task:
Write a function called sort() to sort three integers into ascending order. (This function is not to be implemented with arrays.)
I have written two options, none compile because of my fundamental
misunderstandings of the way pointers work, and also return values
of functions.
First version, in which the sort () function is called in the main one,
and printf function is within the sort() function, compiles without
warnings but produces Bus error when called from the terminal
(the program is posted below):
Allas-MacBook-Pro:ch10 Alla$ gcc -Wall -Wextra -std=c99 -pedantic -o ex10-8 ex10-8.c
Allas-MacBook-Pro:ch10 Alla$ ./ex10-8
Bus error: 10
Second version has printf within the main function, also compiles, and
produces the same bus error.
1)
// Program to sort three integers using pointers
#include <stdio.h>
void sort (int* a, int* b, int* c);
int main(void)
{
int one = 3;
int two = 1;
int three = 9;
sort(&one, &two, &three);
return 0;
}
void sort (int* a, int* b, int* c)
{
int* value_1;
int* value_2;
int* value_3;
if (*a < *b)
{
if (*a < *c)
{
*value_1 = *a;
if (*b < *c)
{
*value_2 = *b;
*value_3 = *c;
}
else
{
*value_2 = *c;
*value_3 = *b;
}
}
else
{
*value_1 = *c;
*value_2 = *a;
*value_3 = *b;
}
}
else
{
if (*b < *c)
{
*value_1 = *b;
if (*a < *c)
{
*value_2 = *a;
*value_3 = *c;
}
else
{
*value_2 = *c;
*value_3 = *a;
}
}
else
{
*value_1 = *c;
*value_2 = *b;
*value_3 = *a;
}
}
printf("%i %i %i\n", *value_1, *value_2, *value_3);
}
2)
// Program to sort three integers using pointers
#include <stdio.h>
void sort (int* a, int* b, int* c);
int main(void)
{
int one = 3;
int two = 1;
int three = 9;
sort(&one, &two, &three);
printf("%d %d %d\n", one, two, three);
return 0;
}
void sort (int* a, int* b, int* c)
{
int* value_1;
int* value_2;
int* value_3;
if (*a < *b)
{
if (*a < *c)
{
*value_1 = *a;
if (*b < *c)
{
*value_2 = *b;
*value_3 = *c;
}
else
{
*value_2 = *c;
*value_3 = *b;
}
}
else
{
*value_1 = *c;
*value_2 = *a;
*value_3 = *b;
}
}
else
{
if (*b < *c)
{
*value_1 = *b;
if (*a < *c)
{
*value_2 = *a;
*value_3 = *c;
}
else
{
*value_2 = *c;
*value_3 = *a;
}
}
else
{
*value_1 = *c;
*value_2 = *b;
*value_3 = *a;
}
}
}
Truly unexpected: by now I should have already been able to solve
such easy tasks. I am doing my best to get too disappointed with
myself, and I do hope for your patience and help.
Another important issue which both versions have revealed again:
I do not understand how to make a function return several values;
for example, if the function computes 3 values, how can I make it
return all three of them to use in the main function?
Thank you! (I am not fond of exclamation marks, but have tacitly
put zillions of those after Thank you :) )
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-11-06 11:32 -0500 |
| Message-ID | <n1ikif$52l$1@dont-email.me> |
| In reply to | #75113 |
On 11/6/2015 11:20 AM, Alla _ wrote:
> Hello!
>
> Here is the description of the task:
>
> Write a function called sort() to sort three integers into ascending order. (This function is not to be implemented with arrays.)
>
> I have written two options, none compile because of my fundamental
> misunderstandings of the way pointers work, and also return values
> of functions.
>
> First version, in which the sort () function is called in the main one,
> and printf function is within the sort() function, compiles without
> warnings but produces Bus error when called from the terminal
> (the program is posted below):
>
> Allas-MacBook-Pro:ch10 Alla$ gcc -Wall -Wextra -std=c99 -pedantic -o ex10-8 ex10-8.c
> Allas-MacBook-Pro:ch10 Alla$ ./ex10-8
> Bus error: 10
>
> Second version has printf within the main function, also compiles, and
> produces the same bus error.
>
> 1)
> // Program to sort three integers using pointers
>
> #include <stdio.h>
>
> void sort (int* a, int* b, int* c);
>
> int main(void)
> {
> int one = 3;
> int two = 1;
> int three = 9;
>
> sort(&one, &two, &three);
>
> return 0;
> }
>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
>
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
>
> if (*b < *c)
> {
> *value_2 = *b;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *b;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *a;
> *value_3 = *b;
> }
>
> }
> else
> {
> if (*b < *c)
> {
> *value_1 = *b;
>
> if (*a < *c)
> {
> *value_2 = *a;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *a;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *b;
> *value_3 = *a;
> }
> }
>
> printf("%i %i %i\n", *value_1, *value_2, *value_3);
> }
>
> 2)
> // Program to sort three integers using pointers
>
> #include <stdio.h>
>
> void sort (int* a, int* b, int* c);
>
> int main(void)
> {
> int one = 3;
> int two = 1;
> int three = 9;
>
> sort(&one, &two, &three);
>
> printf("%d %d %d\n", one, two, three);
>
> return 0;
> }
>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
>
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
`value_1' is a pointer that can point at int objects, right?
Okay, then: To what int does it point?
> [...]
> Another important issue which both versions have revealed again:
> I do not understand how to make a function return several values;
> for example, if the function computes 3 values, how can I make it
> return all three of them to use in the main function?
A function can *return* no more than one value (a void function
returns none). However, that value can be a struct with as many
elements as you like.
As a substitute for (or in addition to) returning a function
value, a function may accept pointers as parameters and modify the
things the pointers point at. I imagine that's the approach the
authors of your sort() task expected you to use.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-07 00:20 -0800 |
| Message-ID | <aca68df4-4c43-482c-bb5c-c9939c57d58c@googlegroups.com> |
| In reply to | #75115 |
<snip>
if (*a < *c)
> > {
> > *value_1 = *a;
>
> `value_1' is a pointer that can point at int objects, right?
>
> Okay, then: To what int does it point?
>
I have figured that out: it's the same mistake I did in previous
program where I declared a temp variable as a pointer. No need for that, as
Ben has explained. I understand it now. I have corrected the version.
This version works the way it should, but not a correct version because
it doesn't sort values within the main function, hence the usage of pointers,
although syntactically correct now, is worthless. Still a tiny step further:
// Program to sort three integers using pointers
#include <stdio.h>
void sort (int* a, int* b, int* c);
int main(void)
{
int one = 3;
int two = 1;
int three = 9;
sort(&one, &two, &three);
return 0;
}
void sort (int* a, int* b, int* c)
{
int value_1;
int value_2;
int value_3;
if (*a < *b)
{
if (*a < *c)
{
value_1 = *a;
if (*b < *c)
{
value_2 = *b;
value_3 = *c;
}
else
{
value_2 = *c;
value_3 = *b;
}
}
else
{
value_1 = *c;
value_2 = *a;
value_3 = *b;
}
}
else
{
if (*b < *c)
{
value_1 = *b;
if (*a < *c)
{
value_2 = *a;
value_3 = *c;
}
else
{
value_2 = *c;
value_3 = *a;
}
}
else
{
value_1 = *c;
value_2 = *b;
value_3 = *a;
}
}
printf("%i %i %i\n", value_1, value_2, value_3);
}
> A function can *return* no more than one value (a void function
> returns none). However, that value can be a struct with as many
> elements as you like.
>
> As a substitute for (or in addition to) returning a function
> value, a function may accept pointers as parameters and modify the
> things the pointers point at. I imagine that's the approach the
> authors of your sort() task expected you to use.
Yes, the task requires exactly that.
Here is a 'structured' version also. I am glad it works:
// Program to sort three integers using pointers
#include <stdio.h>
struct values
{
int value_1;
int value_2;
int value_3;
};
struct values sort (int a, int b, int c);
int main(void)
{
int one = 3;
int two = 1;
int three = 9;
struct values sorted;
sorted = sort(one, two, three);
printf("%d %d %d\n", sorted.value_1, sorted.value_2, sorted.value_3);
return 0;
}
struct values sort (int a, int b, int c)
{
struct values swapped_values;
if (a < b)
{
if (a < c)
{
swapped_values.value_1 = a;
if (b < c)
{
swapped_values.value_2 = b;
swapped_values.value_3 = c;
}
else
{
swapped_values.value_2 = c;
swapped_values.value_3 = b;
}
}
else
{
swapped_values.value_1 = c;
swapped_values.value_2 = a;
swapped_values.value_3 = b;
}
}
else
{
if (b < c)
{
swapped_values.value_1 = b;
if (a < c)
{
swapped_values.value_2 = a;
swapped_values.value_3 = c;
}
else
{
swapped_values.value_2 = c;
swapped_values.value_3 = a;
}
}
else
{
swapped_values.value_1 = c;
swapped_values.value_2 = b;
swapped_values.value_3 = a;
}
}
return swapped_values;
}
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-07 11:04 +0000 |
| Message-ID | <87ziyqt6i6.fsf@bsb.me.uk> |
| In reply to | #75221 |
Alla _ <modelling.data@gmail.com> writes:
<snip>
> void sort (int* a, int* b, int* c)
> {
<snip>
> printf("%i %i %i\n", value_1, value_2, value_3);
> }
The function is supposed to alter the objects whose pointers are passed
in. Maybe this is a testing step, but printing is not enough.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | "Osmium" <r124c4u102@comcast.net> |
|---|---|
| Date | 2015-11-06 10:34 -0600 |
| Message-ID | <da434eFpihrU1@mid.individual.net> |
| In reply to | #75113 |
"Alla _" wrote: > Another important issue which both versions have revealed again: > I do not understand how to make a function return several values; > for example, if the function computes 3 values, how can I make it > return all three of them to use in the main function? You can return a structure containing three items. This may seem cumbersome or ugly to you. You will have to declare the structure in such a way that both the caller and the callee can see it.
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-11-06 08:37 -0800 |
| Message-ID | <6260467b-092e-418c-a54e-ee34e281eef6@googlegroups.com> |
| In reply to | #75113 |
On Friday, November 6, 2015 at 11:20:25 AM UTC-5, Alla _ wrote:
> Hello!
>
> Here is the description of the task:
>
> Write a function called sort() to sort three integers into ascending order. (This function is not to be implemented with arrays.)
>
> I have written two options, none compile because of my fundamental
> misunderstandings of the way pointers work, and also return values
> of functions.
>
> First version, in which the sort () function is called in the main one,
> and printf function is within the sort() function, compiles without
> warnings but produces Bus error when called from the terminal
> (the program is posted below):
>
> Allas-MacBook-Pro:ch10 Alla$ gcc -Wall -Wextra -std=c99 -pedantic -o ex10-8 ex10-8.c
> Allas-MacBook-Pro:ch10 Alla$ ./ex10-8
> Bus error: 10
>
> Second version has printf within the main function, also compiles, and
> produces the same bus error.
>
> 1)
> // Program to sort three integers using pointers
>
> #include <stdio.h>
>
> void sort (int* a, int* b, int* c);
>
> int main(void)
> {
> int one = 3;
> int two = 1;
> int three = 9;
>
> sort(&one, &two, &three);
>
> return 0;
> }
>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
>
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
>
> if (*b < *c)
> {
> *value_2 = *b;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *b;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *a;
> *value_3 = *b;
> }
>
> }
> else
> {
> if (*b < *c)
> {
> *value_1 = *b;
>
> if (*a < *c)
> {
> *value_2 = *a;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *a;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *b;
> *value_3 = *a;
> }
> }
>
> printf("%i %i %i\n", *value_1, *value_2, *value_3);
> }
>
> 2)
> // Program to sort three integers using pointers
>
> #include <stdio.h>
>
> void sort (int* a, int* b, int* c);
>
> int main(void)
> {
> int one = 3;
> int two = 1;
> int three = 9;
>
> sort(&one, &two, &three);
>
> printf("%d %d %d\n", one, two, three);
>
> return 0;
> }
>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
>
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
>
> if (*b < *c)
> {
> *value_2 = *b;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *b;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *a;
> *value_3 = *b;
> }
>
> }
> else
> {
> if (*b < *c)
> {
> *value_1 = *b;
>
> if (*a < *c)
> {
> *value_2 = *a;
> *value_3 = *c;
> }
> else
> {
> *value_2 = *c;
> *value_3 = *a;
> }
> }
> else
> {
> *value_1 = *c;
> *value_2 = *b;
> *value_3 = *a;
> }
> }
> }
>
>
> Truly unexpected: by now I should have already been able to solve
> such easy tasks. I am doing my best to get too disappointed with
> myself, and I do hope for your patience and help.
>
> Another important issue which both versions have revealed again:
> I do not understand how to make a function return several values;
> for example, if the function computes 3 values, how can I make it
> return all three of them to use in the main function?
>
> Thank you! (I am not fond of exclamation marks, but have tacitly
> put zillions of those after Thank you :) )
Here's one to consider, which uses macros to make the code simpler:
#define reverse(a, b) { t = a; a = b; b = t; }
#define presort(a, b) if (b < a) reverse(a, b)
void sort (int* a, int* b, int* c)
{
int t;
presort(*b, *c); // Sort b,c; b is lowest of b,c
presort(*a, *b); // Sort a,b; a is 1st
presort(*b, *c); // Re-sort b,c; b is 2nd, c is 3rd
}
Best regards,
Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-06 10:36 -0800 |
| Message-ID | <ac519a25-84e1-40e9-a4ac-0b96393a0b4f@googlegroups.com> |
| In reply to | #75119 |
On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
> Here's one to consider, which uses macros to make the code simpler:
>
> #define reverse(a, b) { t = a; a = b; b = t; }
> #define presort(a, b) if (b < a) reverse(a, b)
I would strongly suggest that especially if one is trying to offer examples
of how to code things, that one abide by good programming practices when
using macros. If a macro is supposed to behave like a statement, it should
be written in such a way as to do so, typically be enclosing within a
"do { ...contents here... } while(0)" block [with no trailing semicolon].
Otherwise, code like:
if (small_values_first)
presort(a,b);
else
presort(b,a);
is prone to misbehave in a confusing manner.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-06 19:17 +0000 |
| Message-ID | <n1iu85$e5i$1@dont-email.me> |
| In reply to | #75152 |
On 06/11/15 18:36, supercat@casperkitty.com wrote:
> On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
>> Here's one to consider, which uses macros to make the code simpler:
>>
>> #define reverse(a, b) { t = a; a = b; b = t; }
>> #define presort(a, b) if (b < a) reverse(a, b)
>
> I would strongly suggest that especially if one is trying to offer examples
> of how to code things, that one abide by good programming practices when
> using macros.
Alla, I would go further than that and say that using macros in this way
is a terrible idea. You would be far better off sticking to the
techniques that you are already exploring, and getting to grips with the
simplicity of pointers. (That's actually the big secret of pointers -
they're really simple! People get into all kinds of tangles with them
because they don't realise how simple they really are.)
Macros have their place, but this is not it.
<snip>
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-06 11:30 -0800 |
| Message-ID | <78271f1f-c340-45c9-85c5-887c9c1f56bc@googlegroups.com> |
| In reply to | #75159 |
On Friday, November 6, 2015 at 1:17:41 PM UTC-6, Richard Heathfield wrote:
> Macros have their place, but this is not it.
For some kinds of sorting, I'd consider such macros appropriate. For example,
if a function had to receive an array of pointers to structures whose first
field was known to be a "long" and then sort the pointers according to the
value of that field, a function to compare items i and j might on some
platforms most efficiently be written as:
(arr[i]->key > arr[j]->key)
but for portability may need to be written as:
struct thingWithLongKey *ai,*aj; // This would be outside the macro
(memcpy(&ai, arr[i], sizeof ai), \
memcpy(&aj, arr[j], sizeof aj), \
ai->key > aj->key)
Since the authors of C89 thought the first form was "deplorable" in cases
where the pointers might identify some structure type other than
"struct thingWithLongKey", even if those structures had the same initial
member, it may not always be possible to guarantee that a compiler given
the first form won't generate bogus code. Many modern compilers would
generate code for the second form which is just as efficient as what they
would usually generate for the first form, but on some older compilers
the second form may take more than twice as long as the first, so being
able to use the first form on older compilers may be helpful.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-07 01:01 -0800 |
| Message-ID | <5483dd9b-400c-491c-8ad2-52cb3087dbd7@googlegroups.com> |
| In reply to | #75159 |
On Friday, November 6, 2015 at 11:17:41 PM UTC+4, Richard Heathfield wrote:
> On 06/11/15 18:36, supercat@casperkitty.com wrote:
> > On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
> >> Here's one to consider, which uses macros to make the code simpler:
> >>
> >> #define reverse(a, b) { t = a; a = b; b = t; }
> >> #define presort(a, b) if (b < a) reverse(a, b)
> >
> > I would strongly suggest that especially if one is trying to offer examples
> > of how to code things, that one abide by good programming practices when
> > using macros.
>
> Alla, I would go further than that and say that using macros in this way
> is a terrible idea. You would be far better off sticking to the
> techniques that you are already exploring, and getting to grips with the
> simplicity of pointers. (That's actually the big secret of pointers -
> they're really simple! People get into all kinds of tangles with them
> because they don't realise how simple they really are.)
>
> Macros have their place, but this is not it.
>
Well, I have no idea what macros are.. yet ) Therefore, I am
not trying to think about them now (except for those used in
Excel; and I have some issues with them on my Mac).
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-11-06 11:48 -0800 |
| Message-ID | <70ff9ced-6acf-4e7d-bc37-d0d2078eb1a6@googlegroups.com> |
| In reply to | #75152 |
On Friday, November 6, 2015 at 1:36:48 PM UTC-5, supe...@casperkitty.com wrote:
> On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
> > Here's one to consider, which uses macros to make the code simpler:
> >
> > #define reverse(a, b) { t = a; a = b; b = t; }
> > #define presort(a, b) if (b < a) reverse(a, b)
>
> I would strongly suggest that especially if one is trying to offer examples
> of how to code things, that one abide by good programming practices when
> using macros. If a macro is supposed to behave like a statement, it should
> be written in such a way as to do so, typically be enclosing within a
> "do { ...contents here... } while(0)" block [with no trailing semicolon].
> Otherwise, code like:
>
> if (small_values_first)
> presort(a,b);
> else
> presort(b,a);
>
> is prone to misbehave in a confusing manner.
I never considered that issue. Thank you.
Best regards,
Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-11-06 23:15 +0100 |
| Message-ID | <n1j8lh$ojl$1@dont-email.me> |
| In reply to | #75169 |
On 06/11/15 20:48, Rick C. Hodgin wrote:
> On Friday, November 6, 2015 at 1:36:48 PM UTC-5, supe...@casperkitty.com wrote:
>> On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
>>> Here's one to consider, which uses macros to make the code simpler:
>>>
>>> #define reverse(a, b) { t = a; a = b; b = t; }
>>> #define presort(a, b) if (b < a) reverse(a, b)
>>
>> I would strongly suggest that especially if one is trying to offer examples
>> of how to code things, that one abide by good programming practices when
>> using macros. If a macro is supposed to behave like a statement, it should
>> be written in such a way as to do so, typically be enclosing within a
>> "do { ...contents here... } while(0)" block [with no trailing semicolon].
>> Otherwise, code like:
>>
>> if (small_values_first)
>> presort(a,b);
>> else
>> presort(b,a);
>>
>> is prone to misbehave in a confusing manner.
>
> I never considered that issue. Thank you.
>
This is also the reason why one should never write code like:
if (small_values_first)
presort(a,b);
else
presort(b,a);
Instead, write:
if (small_values_first) {
presort(a, b);
} else {
presort(b, a);
}
(Not everyone agrees with me here. Hopefully this will not start a
flame war.)
To be safest, your macros can still be written in the form :
#define reverse(a, b) \
do { t = a; a = b; b = t; } while (0)
Then they will work even if the brackets are omitted in the conditional.
However, macros such as these are very fragile - you are relying on the
existence of t, and that a and b are simple variables and not the
results of function calls or other expressions. A static inline
function is usually the best choice, rather than function-like macros -
they are safer, clearer, and typically result in at least as efficient code.
static inline reverse(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}
static inline pairsort(int* a, int* b) {
if (*b < *a) reverse(a, b);
}
void sort(int* a, int* b, int* c)
{
pairsort(b, c);
pairsort(a, b);
pairsort(b, c);
}
I fully agree with the structure of your code, but static inline
functions are a better choice than macros for the implementation.
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-11-06 14:39 -0800 |
| Message-ID | <438167ff-d731-4da9-98d2-cbba84e892a9@googlegroups.com> |
| In reply to | #75192 |
On Friday, November 6, 2015 at 5:15:29 PM UTC-5, David Brown wrote:
> On 06/11/15 20:48, Rick C. Hodgin wrote:
> > On Friday, November 6, 2015 at 1:36:48 PM UTC-5, supe...@casperkitty.com wrote:
> >> On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
> >>> Here's one to consider, which uses macros to make the code simpler:
> >>>
> >>> #define reverse(a, b) { t = a; a = b; b = t; }
> >>> #define presort(a, b) if (b < a) reverse(a, b)
> >>
> >> I would strongly suggest that especially if one is trying to offer examples
> >> of how to code things, that one abide by good programming practices when
> >> using macros. If a macro is supposed to behave like a statement, it should
> >> be written in such a way as to do so, typically be enclosing within a
> >> "do { ...contents here... } while(0)" block [with no trailing semicolon].
> >> Otherwise, code like:
> >>
> >> if (small_values_first)
> >> presort(a,b);
> >> else
> >> presort(b,a);
> >>
> >> is prone to misbehave in a confusing manner.
> >
> > I never considered that issue. Thank you.
> >
>
> This is also the reason why one should never write code like:
>
> if (small_values_first)
> presort(a,b);
> else
> presort(b,a);
>
> Instead, write:
>
> if (small_values_first) {
> presort(a, b);
> } else {
> presort(b, a);
> }
You could also use this in CAlive and it wouldn't be an issue:
lif (small_values_first) presort(a,b);
lelse presort(b,a);
It puts simple things like this on a single line, allowing horizontal
commands to be used without the { } requirement. It also brings the
subtle variances between the two presort() params lists into stark
visualization, while bypassing the issue.
> (Not everyone agrees with me here. Hopefully this will not start a
> flame war.)
>
> To be safest, your macros can still be written in the form :
>
> #define reverse(a, b) \
> do { t = a; a = b; b = t; } while (0)
>
> Then they will work even if the brackets are omitted in the conditional.
>
> However, macros such as these are very fragile - you are relying on the
> existence of t,
Any response I might offer would sound like an excuse... However, I did
design this macro for this example only. And I did consider the t issue.
I considered using { int t = a; a = b; b = t; }, but I didn't know if
scoped variables were legal in C (and not just in C++).
> and that a and b are simple variables and not the
> results of function calls or other expressions. A static inline
> function is usually the best choice, rather than function-like macros -
> they are safer, clearer, and typically result in at least as efficient code.
>
> static inline reverse(int* a, int* b) {
> int t = *a;
> *a = *b;
> *b = t;
> }
>
> static inline pairsort(int* a, int* b) {
> if (*b < *a) reverse(a, b);
> }
>
>
> void sort(int* a, int* b, int* c)
> {
> pairsort(b, c);
> pairsort(a, b);
> pairsort(b, c);
> }
>
>
> I fully agree with the structure of your code, but static inline
> functions are a better choice than macros for the implementation.
You gave me the idea for something here with the "fragile" comment:
Scoped macros
If scoped, then they only operate in the form expected. And whereas
I could define the macro inside the function, I don't like doing that.
I prefer my macros to external, and typically in a single source file
for the system.
Scoping syntax for macros:
01: #define sort::reverse(a, b) { t = a; a = b; b = t; }
02: #define sort::presort(a, b) if (b < a) reverse(a, b)
That way they only work in the context of the sort() function.
And to accommodate the needs of other functions which should be
allowed, I could add them as enumerated scopes:
03: #define {sort,sort2}::presort(a, b) if (b < a) reverse(a, b)
Or employ a new "friends" keyword:
04: #define friends{sort,sort2}::presort(a, b) if (b < a) reverse(a, b)
Or make a reference for the other function as a scoped reference:
05: #define sort2::presort(a, b) sort::presort(a, b)
That way it extends the scope as needed to any other scope. Of course,
every offering after 02 is only me trying to be funny. Though in all
honesty, 05 seems workable. :-)
Best regards,
Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-06 15:57 -0800 |
| Message-ID | <lnvb9e1y1n.fsf@kst-u.example.com> |
| In reply to | #75192 |
David Brown <david.brown@hesbynett.no> writes:
[...]
> To be safest, your macros can still be written in the form :
>
> #define reverse(a, b) \
> do { t = a; a = b; b = t; } while (0)
>
> Then they will work even if the brackets are omitted in the conditional.
If all the statements are expression statements, as they are here, you
can make the macro expand to an expression rather than to a statement,
which is potentially more flexible:
#define reverse(a, b) ( t = (a), (a) = (b), (b) = t )
On the other hand, you can make the type an additional argument, which
precludes making the whole thing an expression:
#define reverse(a, b, type) \
do { const type t = (a); (a) = (b); (b) = t; } while (0)
But as you say, an inline function is probably even better.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Nick Bowler <nbowler@draconx.ca> |
|---|---|
| Date | 2015-11-06 22:33 +0000 |
| Message-ID | <n1j9rg$r1s$1@dont-email.me> |
| In reply to | #75152 |
On Fri, 06 Nov 2015 10:36:39 -0800, supercat wrote:
> On Friday, November 6, 2015 at 10:37:42 AM UTC-6, Rick C. Hodgin wrote:
>> Here's one to consider, which uses macros to make the code simpler:
>>
>> #define reverse(a, b) { t = a; a = b; b = t; }
>> #define presort(a, b) if (b < a) reverse(a, b)
>
> I would strongly suggest that especially if one is trying to offer examples
> of how to code things, that one abide by good programming practices when
> using macros. If a macro is supposed to behave like a statement, it should
> be written in such a way as to do so, typically be enclosing within a
> "do { ...contents here... } while(0)" block [with no trailing semicolon].
> Otherwise, code like:
>
> if (small_values_first)
> presort(a,b);
> else
> presort(b,a);
>
> is prone to misbehave in a confusing manner.
It will expand to a syntax error (the else is not associated with any if).
This may be annoying but not particularly confusing since the compiler will
diagnose the problem.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-06 16:39 +0000 |
| Message-ID | <87r3k3w080.fsf@bsb.me.uk> |
| In reply to | #75113 |
Alla _ <modelling.data@gmail.com> writes:
> Here is the description of the task:
>
> Write a function called sort() to sort three integers into ascending
> order. (This function is not to be implemented with arrays.)
<snip>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
None of these pointer point anywhere. What do you think *value_1 means
when value_1 is a pointer that you have not initialised? If that's a
tricky question, what do you think this code does?
int i;
printf("%d\n", i);
Note that I am not saying the solution is to make them point somewhere.
I'm just pointing out the first step -- to see what's wrong with what
you've written so far.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-07 00:22 -0800 |
| Message-ID | <cb626c27-f492-4338-84b1-4bb01ee9ba1b@googlegroups.com> |
| In reply to | #75120 |
> Note that I am not saying the solution is to make them point somewhere. > I'm just pointing out the first step -- to see what's wrong with what > you've written so far. > > <snip> > -- > Ben. Yes. I am sorry, I am just getting back to this thread. Thanks to your explanation in the previous one, I now see my mistake, and corrected it.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-06 16:45 +0000 |
| Message-ID | <n1ilap$85f$1@dont-email.me> |
| In reply to | #75113 |
On 06/11/15 16:20, Alla _ wrote:
> Hello!
>
> Here is the description of the task:
>
> Write a function called sort() to sort three integers into ascending order. (This function is not to be implemented with arrays.)
Okay, let's start off by implementing it correctly, so that we have
something to compare against:
#include <stdio.h>
void swap(int *left, int *right)
{
int tmp = *left;
*left = *right;
*right = tmp;
}
void sort(int *a, int *b, int *c)
{
if(*a > *b)
{
swap(a, b);
}
/* The value at *a is now smaller than that at *b */
if(*b > *c)
{
swap(b, c);
}
/* The value at *c is now definitely the biggest, but *b
could now hold a value smaller than *a, so check again. */
if(*a > *b)
{
swap(a, b);
}
}
int main(void)
{
int i = 3;
int j = 1;
int k = 9; /* your own data */
printf("Before: %d %d %d\n", i, j, k);
sort(&i, &j, &k);
printf(" After: %d %d %d\n", i, j, k);
return 0;
}
Result:
Before: 3 1 9
After: 1 3 9
So now let's take a look at your code:
<snip>
> Allas-MacBook-Pro:ch10 Alla$ gcc -Wall -Wextra -std=c99 -pedantic -o ex10-8 ex10-8.c
When I compiled this, I was told:
alla.c: In function ‘sort’:
alla.c:72:11: warning: ‘value_3’ is used uninitialized in this function
[-Wuninitialized]
printf("%i %i %i\n", *value_1, *value_2, *value_3);
^
alla.c:72:11: warning: ‘value_2’ is used uninitialized in this function
[-Wuninitialized]
alla.c:72:11: warning: ‘value_1’ is used uninitialized in this function
[-Wuninitialized]
And that's your problem right there.
If you kick it hard enough, the compiler will give you all kinds of
useful information.
> Allas-MacBook-Pro:ch10 Alla$ ./ex10-8
> Bus error: 10
>
> Second version has printf within the main function, also compiles, and
> produces the same bus error.
>
> 1)
> // Program to sort three integers using pointers
>
> #include <stdio.h>
>
> void sort (int* a, int* b, int* c);
>
> int main(void)
> {
> int one = 3;
> int two = 1;
> int three = 9;
>
> sort(&one, &two, &three);
>
> return 0;
> }
>
> void sort (int* a, int* b, int* c)
> {
> int* value_1;
> int* value_2;
> int* value_3;
These are pointers-to-int. You can use them for pointing to ints, but at
present you haven't pointed them anywhere. Their values are
"indeterminate", which means we don't know what those values are. That
is, we have no guarantee that they are pointing anywhere useful or safe.
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
So, here, we take the value of the int pointed to by a, and copy it
into... where? value_1 isn't pointing to any int that we own. This is
almost certainly the reason for your "bus error". Whatever indeterminate
value is scribbled into that object is not aligned correctly for
addressing an int. (It may not be this one, of course - it might be
*value_2 or *value_3, but certainly at least one of these is the culprit.)
Never Write Through A Pointer Unless You Know Where It Is Pointing!
> 2)
> // Program to sort three integers using pointers
<snip>
> int* value_1;
> int* value_2;
> int* value_3;
>
> if (*a < *b)
> {
> if (*a < *c)
> {
> *value_1 = *a;
Same problem.
> Truly unexpected: by now I should have already been able to solve
> such easy tasks.
You made it too complicated, that's all. Why did you make value_1,
value_2, and value_3 pointers? What was wrong with making them ints?
> I am doing my best to get too disappointed with
> myself, and I do hope for your patience and help.
You're doing fine, but you need to go slower and listen more.
> Another important issue which both versions have revealed again:
> I do not understand how to make a function return several values;
Neither do I. If you find out, let me know.
Actually, there is a way, using an aggregate data structure, or better
still a pointer to it, but I wouldn't bother worrying about that for
now. At present, you have more important things to worry about.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | "Bill Davy" <Bill@SynectixLtd.com> |
|---|---|
| Date | 2015-11-06 18:30 +0000 |
| Message-ID | <da49tmFrah7U1@mid.individual.net> |
| In reply to | #75122 |
"Richard Heathfield" <rjh@cpax.org.uk> wrote in message
news:n1ilap$85f$1@dont-email.me...
> On 06/11/15 16:20, Alla _ wrote:
>> Hello!
>>
>> Here is the description of the task:
>>
>> Write a function called sort() to sort three integers into ascending
>> order. (This function is not to be implemented with arrays.)
>
> Okay, let's start off by implementing it correctly, so that we have
> something to compare against:
>
> #include <stdio.h>
>
> void swap(int *left, int *right)
> {
> int tmp = *left;
> *left = *right;
> *right = tmp;
> }
>
> void sort(int *a, int *b, int *c)
> {
> if(*a > *b)
> {
> swap(a, b);
> }
> /* The value at *a is now smaller than that at *b */
> if(*b > *c)
> {
> swap(b, c);
> }
> /* The value at *c is now definitely the biggest, but *b
> could now hold a value smaller than *a, so check again. */
> if(*a > *b)
> {
> swap(a, b);
> }
> }
>
> int main(void)
> {
> int i = 3;
> int j = 1;
> int k = 9; /* your own data */
>
> printf("Before: %d %d %d\n", i, j, k);
>
> sort(&i, &j, &k);
>
> printf(" After: %d %d %d\n", i, j, k);
>
> return 0;
> }
>
> Result:
>
> Before: 3 1 9
> After: 1 3 9
>
> So now let's take a look at your code:
>
> <snip>
>
>> Allas-MacBook-Pro:ch10 Alla$ gcc -Wall -Wextra -std=c99 -pedantic -o
>> ex10-8 ex10-8.c
>
> When I compiled this, I was told:
>
> alla.c: In function ‘sort’:
> alla.c:72:11: warning: ‘value_3’ is used uninitialized in this function
> [-Wuninitialized]
> printf("%i %i %i\n", *value_1, *value_2, *value_3);
> ^
> alla.c:72:11: warning: ‘value_2’ is used uninitialized in this function
> [-Wuninitialized]
> alla.c:72:11: warning: ‘value_1’ is used uninitialized in this function
> [-Wuninitialized]
>
> And that's your problem right there.
>
> If you kick it hard enough, the compiler will give you all kinds of useful
> information.
>
>> Allas-MacBook-Pro:ch10 Alla$ ./ex10-8
>> Bus error: 10
>>
>> Second version has printf within the main function, also compiles, and
>> produces the same bus error.
>>
>> 1)
>> // Program to sort three integers using pointers
>>
>> #include <stdio.h>
>>
>> void sort (int* a, int* b, int* c);
>>
>> int main(void)
>> {
>> int one = 3;
>> int two = 1;
>> int three = 9;
>>
>> sort(&one, &two, &three);
>>
>> return 0;
>> }
>>
>> void sort (int* a, int* b, int* c)
>> {
>> int* value_1;
>> int* value_2;
>> int* value_3;
>
> These are pointers-to-int. You can use them for pointing to ints, but at
> present you haven't pointed them anywhere. Their values are
> "indeterminate", which means we don't know what those values are. That is,
> we have no guarantee that they are pointing anywhere useful or safe.
>
>> if (*a < *b)
>> {
>> if (*a < *c)
>> {
>> *value_1 = *a;
>
> So, here, we take the value of the int pointed to by a, and copy it
> into... where? value_1 isn't pointing to any int that we own. This is
> almost certainly the reason for your "bus error". Whatever indeterminate
> value is scribbled into that object is not aligned correctly for
> addressing an int. (It may not be this one, of course - it might be
> *value_2 or *value_3, but certainly at least one of these is the culprit.)
>
> Never Write Through A Pointer Unless You Know Where It Is Pointing!
>
>> 2)
>> // Program to sort three integers using pointers
>
> <snip>
>
>> int* value_1;
>> int* value_2;
>> int* value_3;
>>
>> if (*a < *b)
>> {
>> if (*a < *c)
>> {
>> *value_1 = *a;
>
> Same problem.
>
>> Truly unexpected: by now I should have already been able to solve
>> such easy tasks.
>
> You made it too complicated, that's all. Why did you make value_1,
> value_2, and value_3 pointers? What was wrong with making them ints?
>
>> I am doing my best to get too disappointed with
>> myself, and I do hope for your patience and help.
>
> You're doing fine, but you need to go slower and listen more.
>
>> Another important issue which both versions have revealed again:
>> I do not understand how to make a function return several values;
>
> Neither do I. If you find out, let me know.
>
> Actually, there is a way, using an aggregate data structure, or better
> still a pointer to it, but I wouldn't bother worrying about that for now.
> At present, you have more important things to worry about.
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
void Sort2(int *pa, int *pb)
{
if ( *pa > *pb )
{
const int tmp = *pa;
*pa = *pb;
*pb = temp;
}
// *pb now greater than or equal to *pb
}
void Sort3(int *p1, int *pb, int *pc)
{
Sort2(pa,pb); Sort2(pb,pc); // Biggest now in *pc
Sort2(pa,pb). // Smallest in *pa
}
If later you need a SortN(...) then it might be worth optimisng things.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-06 11:36 -0800 |
| Message-ID | <lnoaf63oo6.fsf@kst-u.example.com> |
| In reply to | #75122 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 06/11/15 16:20, Alla _ wrote:
>> Here is the description of the task:
>>
>> Write a function called sort() to sort three integers into ascending
>> order. (This function is not to be implemented with arrays.)
>
> Okay, let's start off by implementing it correctly, so that we have
> something to compare against:
>
> #include <stdio.h>
>
> void swap(int *left, int *right)
> {
> int tmp = *left;
> *left = *right;
> *right = tmp;
> }
>
> void sort(int *a, int *b, int *c)
> {
> if(*a > *b)
> {
> swap(a, b);
> }
> /* The value at *a is now smaller than that at *b */
> if(*b > *c)
> {
> swap(b, c);
> }
> /* The value at *c is now definitely the biggest, but *b
> could now hold a value smaller than *a, so check again. */
> if(*a > *b)
> {
> swap(a, b);
> }
> }
>
> int main(void)
> {
> int i = 3;
> int j = 1;
> int k = 9; /* your own data */
>
> printf("Before: %d %d %d\n", i, j, k);
>
> sort(&i, &j, &k);
>
> printf(" After: %d %d %d\n", i, j, k);
>
> return 0;
> }
I found this to be an interesting problem, so I went ahead and
threw together a solution. I was hesitant to post a full solution,
but since you've already done so here goes.
#include <stdio.h>
void sort2(int *x, int *y) {
if (*x > *y) {
const int old_x = *x;
*x = *y;
*y = old_x;
}
}
void sort3(int *x, int *y, int *z) {
sort2(x, y);
sort2(y, z);
sort2(x, y);
}
void try(int a, int b, int c) {
printf("%d %d %d -> ", a, b, c);
sort3(&a, &b, &c);
printf("%d %d %d\n", a, b, c);
}
int main(void) {
try(3, 1, 1);
try(3, 3, 1);
try(1, 2, 3);
try(1, 3, 2);
try(2, 1, 3);
try(2, 3, 1);
try(3, 1, 2);
try(3, 2, 1);
}
For sorting N items, where you don't know N until run time, you have
to write general code. (There are more general-purpose sorting
algorithms out there than you can shake a stick at.) If you know
that N==3, you can do something more specific by recognizing that
sorting the first two items, then the last two items, then the
first two items, solves the problem. (If I needed to sort 4 items,
I *might* try to come up with a custom solution, but it would
probably be easier to call an existing general sorting routine.)
In a swap routine, it's traditional to call the temporary variable
something like "temp". I like to call it something like "old_x"
because it makes it very clear what value it holds, and I don't have
to stop and think *quite* as hard to avoid doing the assignments
in the wrong order (yes, I've made that mistake). Also, defining
it as "const" guarantees that I won't incorrectly re-assign to it.
(It's not really "old_x", it's really "old_star_x" -- but in this
case terseness and clarity win out over pedantic correctness.)
Since I wasn't quite 100% confident that my algorithm would cover all
cases, I wrote code to test it for all cases. A more thorough test
framework would verify that the result is actually sorted and that
the output contains the same numbers as the input, but for something
this small visual examination of the output is good enough. I test
all 6 permutations of 3 distinct values. If I wanted to be truly
exhaustive, I'd test all the cases where two or more of the values
are equal, but I only bothered doing a couple (3,1,1 and 3,3,1).
I also assume that if sorting 2,1,3 works correctly, sorting 20,10,30
will also work correctly; I can justify that assumption because I
know that the function depends only on "<" comparisons.
You'll note that there are no comments. I'd like to think that
my code is clear enough, including the choice of names, that it
doesn't need them.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web