此字符串比较函数中(const char*)cast C的剖析和解释

此字符串比较函数中(const char*)cast C的剖析和解释,c,casting,C,Casting,通过反复试验,我成功地让下面的字符串比较函数按照我的预期使用qsort(),但我真的不明白为什么(const char*)cast表达式中需要星号。请有人仔细分析并解释一下:- int strCompare(const void *a, const void *b) { return strcmp((const char*)a, (const char*)b); } 附件:- void findStrings(int * optionStats, char strings[][MAX

通过反复试验,我成功地让下面的字符串比较函数按照我的预期使用qsort(),但我真的不明白为什么(const char*)cast表达式中需要星号。请有人仔细分析并解释一下:-

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()的参数?

strcmp的签名是(还有另一个,但这是您正在使用的):

因此,由于函数(
a
b
)的参数是
const void
,因此必须执行这些强制转换


只要调用
qsort
时用作参数的变量将作为
char*
传递给
strCompare
作为
char*
,您需要一个星号,因为您想将指向
const void
的指针转换为指向
const char
的指针,星号表示它们是空的指针类型

实际上,你并不需要转换,因为空的指针类型可以用C语言隐式地转换为<代码>指针到t<代码>类型,这不是C++的。

因为

int strcmp(
   const char *string1,
   const char *string2 
);
是这样定义的。如果不将其强制转换为“const char*”,则变量“a”应为指向void的指针类型。如果你打字,最好能理解

const void*a作为const void*a

星号与数据类型相关联


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

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

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

这就是我所想的,但编译器发出警告:从不兼容的指针类型[enabled by default]传递'qsort'的参数4您是对的,这就是原因。我将编辑我的答案,删除我的最后一个问题。@nhahtdh这是我做的第一件事,但我得到了警告:从不兼容的指针类型[默认启用]传递'qsort'的参数4。我遗漏了什么吗?作为附录,您可以在您的问题中添加项目中的代码,您可以在其中调用strCompare,它的参数是什么。谢谢Nicolas。我添加了附录。我相信
MAX\u STRING\u SIZE+1==21
否则,你是在向你的编译器撒谎,当你向他们撒谎时,编译器很容易收回自己的话。您可能最好一致地使用相同的值表示法。请注意,如果要对指向char的指针数组进行排序,则需要不同的字符串比较例程:
int-cmpStrings(const-void*a,const-void*b){char*a1=*(char**)a;char*b1=*(char**)b;返回strcmp(a1,b1);}
。是最大字符串大小+1==21,调试后将替换为21。该函数似乎排序正确,但出于好奇,我将尝试您的变体;这是一个不同的工作!相关,但不同。现在我明白了为什么我不需要将它包装在单独的函数中的strcmp()中。我会记下这个答案。谢谢严格地说,函数指针转换不是定义良好的行为。实际上,只要调用约定和参数大小相同,它们几乎总是可以工作的。@Lundin,当然!不过,强制转换背后的全部要点是,告诉编译器您知道自己在做什么。@behnam不是真的。许多程序员之所以选择强制转换,是因为他们不知道自己在做什么,他们希望编译器警告消失。@behnam顺便说一句,您的代码只会对指针数组(“软拷贝”)排序,而不会对字符串数组(“硬拷贝”)排序这似乎是OP的情况。有一些很好的解释,但这似乎很好地回答了最初的问题。
qsort(arr,
      sizeof(arr)/sizeof(char*),
      sizeof(char*),
      (int(*)(const void *, const void *))strcmp);