I would expect
main to look like
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
printf("%d\n", find_second(a, b, c));
Obviously your original function wouldn't work with this, but it's much more straight forward. Read in the input, process it, output the results.
void swap(int *a, int *b)
int temp = *a;
*a = *b;
*b = temp;
void sort(int *a, int *b, int *c)
if (*a > *b)
/* a <= b now */
if (*b > *c)
if (*a > *b)
/* a <= b <= c */
int find_second(int a, int b, int c)
sort(&a, &b, &c);
swap is clear. It just exchanges the two values.
sort function now sorts the three values such that afterwards, \$a \le b\$ and \$b \le c\$. It may seem like you are checking
b twice, but realize that they could change in between. So the second time you could be comparing the original
b to the original
Once sorted, we can just return
b, which is the middle value.
In my opinion, this is the most readable version. You might be able to get better performance by multiplying or taking the exclusive or, but this is the most understandable.
I'm also not convinced that it is slower. Note that
a ^ b ^ c ^ smallest ^ largest does four register assignments (of intermediate results) and
max each do two comparisons and two register assignments. At worst, this version does three comparisons and nine register assignments. At best, this version does no assignments and two comparisons. The
max solutions always do at least four comparisons and eight assignments. In many systems, each
if comparison involves a register assignment and then a branch command. So four branches against three.
You'd have to test to be sure how each version performed. Note that you'd likely have to do a large number of operations to get a good test, as both versions are going to be very fast on an individual basis. Actual speed may depend on how the compiler is able to optimize them.
An alternative is to use an array instead.
int compare_int(const void *a, const void *b)
return ( *(int *)b - *(int *)a );
int find_second(int *data, int size)
qsort(data, size, sizeof *data, compare_int);
scanf("%d %d %d", &data, &data, &data);
printf("%d\n", find_second(data, 3));
This allows us to use the standard
qsort and avoid defining our own
It also scales well. It's easy to return a different ordinal value or to handle more values.