将const void *转换为C中的const char *

时间:2015-02-08 16:30:10

标签: c casting qsort

所以我有一个类似的C函数:

int cmp (const void *a, const void* b)
 return rot13cmp( (const char*)a, (const char*)b );
}

和rot13cmp是另一个带有两个const char *类型参数的函数。

我将此函数传递给C qsort函数的compare参数,但它似乎不起作用。

但是,如果我通过执行

来转换const void *变量
return rot13cmp ( *(const char **)a, *(const char **)b ); 

然后该功能开始工作。我在SO看了这个,但每个消息来源都说第一种投射方法应该有效,所以我想知道为什么只有第二种方法适合我?

编辑:这是我的相关代码,

int cmp (const void *a, const void *b) {
 return rot13cmp( (const char *)a, (const char *)b );
}

int rot13cmp (const char *a, const char *b) {
 while (*a == *b && *a != '\n') {
  a++;
  b++;
 }

 if (*a == *b) { return 0; }
 else if (*a == '\n') { return 1; }
 else if (*b == '\n') { return 1; }
 else { return rot13(*a) - rot13(*b);
}

和rot13返回一个int,表示字母表中旋转了13个字母的字母的ASCII代码。

我通过

调用了qsort
qsort(words, word_count, sizeof(char*), cmp);

其中words是char **数组,word_count是int。 cmp也只是

1 个答案:

答案 0 :(得分:3)

qsort()使用指向应该比较的数组元素的指针调用比较函数。

如果你的数组包含const char*,那意味着调用比较函数并指向那些指针,你必须相应地进行转换和取消引用。

使用(const char*)a,您将解释参数,就好像它是指向const char的指针一样。但事实并非如此。实际上,它是指向输入数组中const char*的指针。

这就是为什么(const char**)a是正确的强制转换,它将参数解释为指向const char*的指针。要进行字符串比较,您需要指向const char*,您可以通过使用*取消引用该值来访问该字段。

您可以将其视为首先更正类型(通过强制转换),然后访问指向的值(通过解除引用)。

两次尝试之间的区别在于第二种情况会进行额外的解除引用。这很重要,因为qsort()不会直接传递const char*,而是传递指向它的指针。因此,我们必须查看指向的值,以找到我们正在寻找的东西。通过直接转换为const char*,我们只声称变量将包含这样的指针,这将不会很好地结束,因为情况并非如此。