【发布时间】:2011-10-21 09:14:18
【问题描述】:
#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 char 的 const 指针。这两个似乎都符合strcmp() 的要求:两个指向 const 字符的指针。手册页似乎给了我们指向非常量事物的 const 指针,这似乎不是 strcmp() 的声明所要求的。即使合法,给函数提供不符合其参数的东西似乎也不是一个好主意。我错过了什么吗?
最后,为什么以下内容至少不会产生错误警告:
auto const char * const ptr3 = *(const char **) ptr1; //where ptr1 is
of the form int foo(const void * ptr).
取消引用 ptr1 一次会给我们一个指向 const char 的指针,但它本身不是 const。但是,ptr3 是常量。那么为什么编译器不生成警告呢?我是否遗漏了什么,或者是否有理由不应该产生警告?
【问题讨论】:
-
忘记
auto是 C 中的关键字 - 或者不要使用它。 C++11 定义了它的用途,但在 C99 中它是噪音。
标签: c casting function-pointers strcmp qsort