Вопрос

это только я или этот код в Жемчужины программирования неправильно (быстрая сортировка требует 2 постоянных пустоты, нет?) Если да, то правильно ли мое решение?Прошу прощения, просто учусь...

int wordncmp(char *p, char* q)
{   int n = k;
    for ( ; *p == *q; p++, q++)
        if (*p == 0 && --n == 0)
            return 0;
    return *p - *q;
}

int sortcmp(char **p, char **q)
{   return wordncmp(*p, *q);
}
...

qsort(word, nword, sizeof(word[0]), sortcmp);

Является ли это решением?

int sortcmp(const void *p, const void *q)
{   return wordncmp(* (char * const *) p, * (char * const *) q);
}
Это было полезно?

Решение

Первый пример кода, вероятно, будет работать практически с любым компилятором и процессором;однако это технически неопределенное поведение, если вы дословно следуете стандарту C.

Как вы сказали, последний аргумент в пользу qsort() является указателем на функцию, принимающую два аргумента типа const void*. sortcmp принимает разные аргументы.Ваш компилятор следует выдам вам предупреждение о несовместимых сигнатурах типов или что-то в этом роде.В любом случае выполняется приведение из функции одного типа в функцию другого типа.

Стандарт C определяет, что вы можете приводить указатели на функции к другим указателям на функции с разными типами, но вы не можете разыменовывать и вызывать приведенный указатель на функцию.Однако, если вы повторно приведете указатель на функцию обратно к ее исходному типу, то вызов этого имеет определенное поведение - он вызывает исходную функцию.

Поскольку вы проводите кастинг из int (*)(char**, char**) к a int (*)(const void*, const void*), а затем , в конце концов qsort() вызывает ли вашу функцию компаратора без приведения ее обратно к int (*)(char**, char**), это неопределенное поведение.

Однако, поскольку практически на всех архитектурах char ** и еще const void* если они представлены таким же образом, вызов функции практически всегда будет работать.

Если вы хотите получить определенное поведение, вы должны убедиться, что ваша функция сравнения имеет правильную сигнатуру типа, а затем вы можете привести аргументы к нужному типу.Ваше решение абсолютно правильное и не нарушает тамошний стандарт C.Хорошо проделано на const-корректность - многие люди не совсем понимают, что char * const * означает.

Вы также должны сделать wordncmp() возьмите параметры const char*, поскольку вы не изменяете параметры.

Боковое примечание:Вы также технически не можете привести указатель функции к указателю данных (напримерa void*) или наоборот.Стандарт допускает, чтобы указатели на функции и указатели на данные имели разные размеры.Даже если это работает на вашем компьютере, это не гарантирует, что оно будет работать всегда.

Другие советы

Вы правы, подпись для sortcmp не соответствует чему qsort ожидает.Ваша поправка верна. wordcmp также следует сделать const-правильно, поскольку технически вы теряете часть const-несс по пути.

int wordncmp(const char *p, const char* q)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top