Вот вы.
int compare( const void *p1, const void *p2 )
{
const struct student *left = p1;
const struct student *right = p2;
int result = ( right->votes < left->votes ) - ( left->votes < right->votes );
return result == 0 ? strcmp( left->name, right->name ) : result;
}
Вот демонстрационная программа.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_SIZE 20
struct student
{
unsigned int votes;
char name[NAME_SIZE];
};
int compare( const void *p1, const void *p2 )
{
const struct student *left = p1;
const struct student *right = p2;
int result = ( right->votes < left->votes ) - ( left->votes < right->votes );
return result == 0 ? strcmp( left->name, right->name ) : result;
}
int main(void)
{
struct student students[] =
{
{ 10, "JAMES" },
{ 8, "JACK" },
{ 10, "ALEXA" }
};
const size_t N = sizeof( students ) / sizeof( *students );
qsort( students, N, sizeof( struct student ), compare );
for ( size_t i = 0; i < N; i++ )
{
printf( "%2u, %s\n", students[i].votes, students[i].name );
}
putchar( '\n' );
return 0;
}
Выход программы:
8, JACK
10, ALEXA
10, JAMES
Что касается функции сравнения
int compare(const void* p1, const void* p2){
return ( ((const struct student*) p2)->votes - ((const struct student*) p1)->votes );
int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
if(value==0)
{
return stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
}
}
тогда в его начале есть оператор return. Таким образом, код после оператора return не будет выполнен.
Этот оператор
int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
имеет неопределенное поведение, поскольку существует различие между двумя указателями, которые не указывают на элементы одного и того же массива.
Этот вызов
stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
doea не имеет смысла и не будет компилироваться, потому что функция strcmp
ожидает два аргумента типа char *
.