2013-11-21 4 views
1

У меня следующий вопрос: Моя функция сравнения в QSort выглядит следующим образом:QSort в C: сравнить Струны

static int compare(const void *arg1, const void *arg2) { 
    return strcmp((const char *) arg1, (const char *) arg2); 
} 

Это не сработало, так что я посмотрел пример кода на странице человека, и я изменил это немного, так что теперь это выглядит следующим образом:

static int compare(const void *arg1, const void *arg2) { 
    return strcmp(*(char * const *) arg1, *(char * const *) arg2); 
} 

Я не понимаю, почему метод страницы человек работает, так как параметр STRCMP являются Const символ * s1 и Const символ * s2.

Я довольно новичок в C, поэтому мне трудно понять это. Может кто-нибудь, пожалуйста, объясните мне это, почему работает только метод страниц.

+2

Просьба найти дубликаты - ответы на многие подобные вопросы уже заданы. Параметры включают (в порядке очередности): [SO 14993282] (http://stackoverflow.com/questions/14993282/), [SO 5035289] (http://stackoverflow.com/questions/5035289/), [SO 18400333] (http://stackoverflow.com/questions/18400333/), [SO 19558447] (http://stackoverflow.com/questions/19558447/). Я уверен, что есть и другие. Попробуйте выполнить поиск с помощью '[c] qsort string' в окне поиска SO. –

ответ

3

Краткий ответ на ваш вопрос заключается в том, что указатели, переданные в функцию сравнения, не являются char *, а char **.

Если вы думаете об этом, если вы сортируете массив целых чисел, вы должны пройти два значения int * (замаскировано под void *). Если вы сортируете массив парных разрядов, вы должны получить два значения double *; если вы сортируете массив строк, вы передаете два указателя на строки, что означает два значения char **.

+2

Точное решение – Abhineet

+0

Действительно кратким и точным. – haccks

3

man qsort говорит:

Содержимое массива сортируются в порядке возрастания функции сравнения , на которую указывает compar, который вызывается с двумя аргументами, которые указывают на сравниваемых объектов.

Понятно, что «с двумя аргументами, указывающими на сравниваемые объекты». Таким образом, при сравнении два char * строк, аргумент в типа «указателей на указатели на char», который также охваченных в страницах руководства:

static int 
    cmpstringp(const void *p1, const void *p2) 
    { 
     /* The actual arguments to this function are "pointers to 
      pointers to char", but strcmp(3) arguments are "pointers 
      to char", hence the following cast plus dereference */ 

     return strcmp(* (char * const *) p1, * (char * const *) p2); 
    } 

И man strcmp скажет вам, что его прототип:

int strcmp(const char *s1, const char *s2); 

где аргументы являются «указателями на char».

Поэтому конверсия решает это.

Возможно, вам понадобится внимательно прочитать справочную страницу.