【问题标题】:Dissection and explanation of (const char*) cast C in this string comparison function此字符串比较函数中 (const char*) cast C 的剖析与解释
【发布时间】:2012-08-24 05:22:46
【问题描述】:

通过反复试验,我设法使以下字符串比较函数按预期与 qsort() 一起使用,但我真的不明白为什么在 (const char*) 强制转换表达式中需要星号。有人可以剖析和解释一下吗:-

int strCompare(const void *a, const void *b) {
    return strcmp((const char*)a, (const char*)b);
} 

附录:-

void findStrings(int * optionStats, char strings[][MAX_STRING_SIZE + 1], int numStrings)
{
    qsort(strings, numStrings, 21*sizeof(char), strCompare);
}

有没有办法通过 strCompare() 消除对 strcmp() 的调用,而只使用 strcmp() 作为 qsort() 的参数?

【问题讨论】:

  • 我相信MAX_STRING_SIZE + 1 == 21 否则,你在欺骗你的编译器,当你对他们撒谎时,编译器很容易收回他们自己的东西。您最好始终对值使用相同的符号。
  • 请注意,如果要对指向 char 的指针数组进行排序,则需要一个不同的字符串比较例程:int cmpStrings(const void *a, const void *b) { char *a1 = *(char **)a; char *b1 = *(char **)b; return strcmp(a1, b1); }
  • 是 MAX_STRING_SIZE + 1 == 21,调试后将替换 21。该函数似乎排序正确,但出于好奇,我会尝试您的变体。
  • 不要在你的数据上尝试我的代码;这是为了一份不同的工作!相关,但不同。

标签: c casting


【解决方案1】:

您需要一个星号,因为您想将 pointerconst void 转换为 pointerconst char,并且星号表示它们是指针类型。

实际上你并不需要转换,因为pointer to void 类型可以隐式转换为 C 语言中的pointer to T 类型,而 C++ 则不然。

【讨论】:

  • 有一些很好的解释,但这似乎很好地回答了最初的问题。
【解决方案2】:

正如其他人在这里提到的,您不需要定义新函数,只需转换 pointer 类型。以下是在将函数传递给qsort 时如何转换函数,防止出现任何警告/错误:

qsort(arr,
      sizeof(arr)/sizeof(char*),
      sizeof(char*),
      (int(*)(const void *, const void *))strcmp);

【讨论】:

  • 好的,现在我明白为什么我不需要将它包装在 strcmp() 中的单独函数中了。我会标记这个答案。谢谢你
  • 严格来说,函数指针转换不是明确定义的行为。实际上,只要调用约定和参数大小相同,它们几乎总是可以工作。
  • @Lundin,当然!然而,转换背后的重点是告诉编译器你知道你在做什么。
  • @behnam 不是。许多程序员强制转换是因为他们不知道自己在做什么,他们希望编译器警告消失。
  • @behnam 顺便说一句,您的代码只会对指针数组(“软拷贝”)进行排序,而不是字符串数组(“硬拷贝”),这似乎是 OP 的情况。
【解决方案3】:

strcmp 的签名是(还有一个,但是你用的是这个):

int strcmp(const char *s1, const char *s2);

所以,由于您的函数的参数(ab)是 const void,因此您必须执行这些转换。

只要您在调用qsort 时用作参数的变量将作为char * 传递给strCompare,这将是正确的。

【讨论】:

  • 这就是我的想法,但编译器抱怨警告:从不兼容的指针类型传递“qsort”的参数 4 [默认启用]
  • 你是对的,这就是原因。我将编辑我的答案,删除我的最后一个问题。
  • @nhahtdh 这是我做的第一件事,但我收到警告:从不兼容的指针类型传递“qsort”的参数 4 [默认启用]。有什么我想念的吗?
  • 作为附录,您可以在问题中添加您调用strCompare 的项目中的代码,以及它的参数是什么。
  • 谢谢尼古拉斯。我添加了附录。
【解决方案4】:

因为

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

是这样定义的。如果您不将其转换为“ const char* ”,则变量“ a ”应该是指向 void 的指针类型。如果你输入它会更好地理解

const void *a as const void* a

星号与数据类型相关联。

所以要将整个变量“a”转换为指向“const char”数据类型的指针,您也必须使用星号。

【讨论】:

    猜你喜欢
    • 2013-03-23
    • 2012-05-03
    • 2021-12-31
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多