#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
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);
}
int main(int argc, char *argv[])
{
int j;
assert(argc > 1);
qsort(&argv[1], argc - 1, sizeof(argv[1]), cmpstringp);
for (j = 1; j < argc; j++)
puts(argv[j]);
exit(EXIT_SUCCESS);
}
Я смущен этой частью:
return strcmp(* (char * const *) p1, * (char * const *) p2);
Почему они это сделали? Почему НЕ сделали этого: (const char**)
или (const char * const*)
? Разве мы не получим указатель на const char, если один раз разыменуем (const char**)
? Разыменовав второй, мы не получим указатель const, указывающий на const char. Оба они кажутся тем, что запрашивает strcmp()
: два указателя, которые указывают на константные символы. То, что справочная страница, кажется, дает нам константные указатели, указывающие на неконстантные вещи, что, похоже, не то, о чем просит объявление strcmp()
. Даже если это законно, не кажется хорошей идеей давать функции что-то, что не соответствует ее параметрам. Я что-то пропустил?
Наконец, почему следующее не генерирует хотя бы предупреждение об ошибке:
auto const char * const ptr3 = *(const char **) ptr1; //where ptr1 is
of the form int foo(const void * ptr).
Разыменование ptr1
один раз дает нам указатель на константный char, но сам по себе не является константой. Однако ptr3
является константой. Так почему же компилятор не генерирует предупреждение? Я что-то упустил, или есть причина, по которой не должно выдаваться предупреждение?
auto
— это ключевое слово в C, или не используйте его. C++11 определил его использование, но в C99 это шум. - person Jonathan Leffler   schedule 22.10.2011