C 强制转换时条件表达式中的不兼容类型

C 强制转换时条件表达式中的不兼容类型,c,pointers,casting,conditional-operator,kernighan-and-ritchie,C,Pointers,Casting,Conditional Operator,Kernighan And Ritchie,我目前正在努力完成K&R练习,有一些事情困扰着我 我有qsort函数声明: void qsort(void *v[], int left, int right, int (*comp)(void *, void *)); 根据这本书,我应该能够使用条件表达式来选择比较函数。我有两个: int numcmp(char *s1, char *s2) 而cstring的 int strcmp(const char *s1, const char *s2); 这个电话看起来像

我目前正在努力完成K&R练习,有一些事情困扰着我

我有
qsort
函数声明:

void qsort(void *v[], int left, int right,
           int (*comp)(void *, void *));
根据这本书,我应该能够使用条件表达式来选择比较函数。我有两个:

int numcmp(char *s1, char *s2)
而cstring的

int strcmp(const char *s1, const char *s2);
这个电话看起来像:

qsort((void **)lineptr, 0, nlines - 1,
            (int(*)(void *, void *))(numeric ? numcmp : strcmp));
我的MS VS给了我一个错误:

Error: operand types are incompatible
然而,当我这样做的时候:

qsort((void **)lineptr, 0, nlines - 1,
            (numeric ? (int(*)(void *, void *))numcmp : (int(*)(void *, void *))strcmp));
一切都好


这本书是错误的,还是仅仅是VS对应该如何做的想法?

您的错误是使用了一个不好的原型作为自定义比较函数
numcp

它应该使用指向常量的指针:

int numcmp(char const *s1, const char *s2); // Showing both equivalent orders for const

条件运算符不能接受参数2和参数3,其中两个参数都不能隐式转换为其他类型,但您可以事先将它们转换为相同的类型。

在C标准(6.5.15条件运算符)中对条件运算符的描述中,有这样的内容:

3第二个和第三个操作数应满足以下条件之一:- 两个操作数都是指向的限定或非限定版本的指针 兼容类型

兼容功能应具有兼容参数

因为你的函数有指针作为参数

2对于要兼容的两种指针类型,两者应相同 合格,且两者都应是指向兼容类型的指针

但是,这两个函数的参数不是完全一致的


因此,编译器是正确的。

有什么令人惊讶的地方?当两个参数都不能隐式转换为其他类型时,条件运算符不能接受2个参数,但您可以事先自然地将它们转换为同一类型。可能重复的I未使用stdlib的qsort。声明来自作者编写的函数。定义也在那里。令人惊讶的是,作者在书中使用了第一种方法。我想知道这本书中的代码是不是太老了以至于VS无法接受,或者我在这里做错了什么。请注意,如果您正在转换传递给
qsort
的函数指针,那么您使用的是错误的。很好-所以OP的问题不是
qsort()
问题,而是
?:
问题。谢谢,就这样。突然,事情变得非常清楚。作者的意思一定是本书前面确实定义的
strcmp
,并采用了两个
char*
参数。在这种情况下不会有错误。当K&R发布“C编程语言”时,
const
限定符不存在。如果它被更新为现代C语言,那么这两个函数都可以通过在它们的参数中添加const修饰符来进行const校正。