If I were you I would write some functions and macros to simplify the code and make it easier to read. Here are some that come to mind :
double GetArea( triangle * pt )
{
double p, area;
p = ( pt->a + pt->b + pt->c ) / 2.0;
area = sqrt( p * ( p - pt->a ) * ( p - pt->b ) * ( p - pt->c ) );
return area;
}
void Print( triangle * tris, double * areas, int count )
{
int i;
for( i = 0; i < count; i++)
{
printf( "%2d : %5.1f : %2.0f, %2.0f, %2.0f\n",
i + 1, areas[ i ], tris[ i ].a, tris[ i ].b, tris[ i ].c );
}
}
Here's a macro for memory allocation :
#define ALLOCATE(typ,cnt) (typ*)calloc(cnt,sizeof(typ))
and here's another one to do the swap :
#define SWAP(typ,a,b) { typ temp; temp = a; a = b; b = temp; }
then your code can look like this :
void sort_by_area( triangle* tr, int n )
{
double * areas = ALLOCATE( double, n );
int i, j;
for( i = 0; i < n; i++)
{
areas[ i ] = GetArea( & tr[ i ] );
}
printf( "before sorting :\n" );
Print( tr, areas, n );
for( i = 0; i < n - 1; i++ )
{
for( j = i + 1; j < n; j++ ) {
if( areas[ i ] > areas[ j ] ) {
SWAP( triangle, tr[ i ], tr[ j ] );
SWAP( double, areas[ i ], areas[ j ] );
}
}
}
printf( "after sorting :\n" );
Print( tr, areas, n );
free( areas ); }
Note the different terms in the sorting loops. After the first pass (i=0) the triangle in slot 0 will have the smallest area so you don't need to check it again. Also, there is no need to compare the same one with itself so the inner loop starts one slot after the outer loop. Similarly, the outer loop ends one slot before the last one while the inner loop goes to the last slot.
I added a
Print
function so I could see all the values.