【问题标题】:Casting a const void * to a const char * in C在 C 中将 const void * 转换为 const char *
【发布时间】:2015-02-08 16:30:10
【问题描述】:

所以我有一个像这样的 C 函数:

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

rot13cmp 是另一个函数,它接受两个 const char * 类型的参数。

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

但是,如果我改为通过执行

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

然后该功能开始工作。我查看了这个,但每个消息来源都说第一种铸造方法应该有效,所以我想知道为什么只有第二种方法对我有用?

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

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 返回一个整数,表示字母在字母表中旋转了 13 个字母的 ASCII 码。

我通过这样做调用了 qsort

qsort(words, word_count, sizeof(char*), cmp);

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

【问题讨论】:

  • 我觉得SSCCE真的在这里提供帮助。
  • 发生这种情况一定有不同的原因。
  • 那你是怎么打电话给qsort()的?
  • 如果您不向我们展示您的 ab 最初的类型,我们将一无所知。根据您的描述,我猜它们是指向指针的指针,但没有信息,这纯粹是猜测。
  • 对不起,我在上面添加了相关代码。

标签: c casting qsort


【解决方案1】:

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

如果您的数组包含const char*,这意味着使用指向这些指针的指针调用比较函数,您必须相应地强制转换和取消引用。

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

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

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

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

【讨论】:

  • 您认为您可以详细说明一下吗?我认为 (char*) 和 *(char **) 都是强制转换/取消引用的有效方法,但我想知道为什么后者有效。
  • *(char **) 正在取消引用您传入的指针,而 (char *) 只是一个演员表。
  • @ChangLiu:我添加了更多细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 2012-01-16
相关资源
最近更新 更多