使用指向const的指针

时间:2010-11-01 20:35:14

标签: c pointers

在qsort的手册页中,在排序字符串的示例中:

 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);
       }

为什么在char * const *的参数中需要strcmp()char *不够吗?

4 个答案:

答案 0 :(得分:3)

strcmp被声明为

int strcmp(
   const char *string1,
   const char *string2 
);

这正确地表达了函数的接口契约 - 即strcmp不会修改其输入数据 - 并允许编译器在函数内部进行优化(假设它不是CRT的一部分,并且可能已经在汇编程序中)。

答案 1 :(得分:2)

const void* p1表示此函数未更改p1点。如果你做了

char** p1_copy = (char**) p1;

这将是一个潜在破坏承诺的设置,因为你可以做

*p1_copy = "Something else";

所以从const void*char**的演员阵容被称为“抛弃const”。合法,但是如果你使用强制转换来抛弃const并以其他方式一次更改类型,一些编译器会发出警告。

没有违反const void* p1声明承诺的演员阵容是使用的:

char* const* p1_arg = (char* const*) p1;

现在*p1_argp1指向的东西,不能像我们说的那样改变。你可以改变它中的字符:

*p1_arg[0] = 'x';

函数声明从未说过任何关于它们的内容,并且你说你知道它们原来是非const char的。所以它是允许的,即使该函数实际上没有做任何这样的事情。

然后你取消引用(作为一个rvalue)来获得char*。这可以通过自动const char*促销合法地作为strcmp参数传递给const

答案 2 :(得分:1)

从技术上讲,如果你想摆脱这些争论,演员阵容将是char **,而不是char *。由于const的参数也是cmpstringp,因此const会留在演员表中。

答案 3 :(得分:0)

传递给qsort的比较函数没有业务修改它正在比较的项目。

这就是为什么qsort的一般情况如下:

void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));