K&R 第 5.11 节 qsort 程序生成指针不匹配警告。你能解释为什么会产生这个警告吗?

K&R section 5.11 qsort program generates a warning of pointer-mismatch. Can you explain why this warning is generated?

以下是该程序的摘录:我已尝试重新生成尽可能少的代码以专注于警告消息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* function declarations */
void userwritelines(char *[],int );
int usernumcmp(char *, char *);

/* constants */
#define MAXLINES 10
#define MAXWIDTHPERLINE 10

void userqsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
char *lineptr[MAXLINES] = { "testing", "whether", "it would", "work"};

int main()
{
    int nlines, numeric;
    nlines = 4;
    numeric = 0;
        userqsort((void **) lineptr, 0, nlines -1, (int (*)(void *, void *)) (numeric ? usernumcmp : strcmp));
        userwritelines(lineptr, nlines);
        return 0;
}

/* qsort: sort v[left]...v[right] into increasing order */
void userqsort(void *v[], int left, int right,
                int (*comp)(void *, void *))
{
    int i, last;
    void swap(void *v[], int, int);

    if(left >= right)   /* do nothing if array contains */
        return;         /* fewer than 2 elements */

    swap(v, left, (left+right)/2);
    last = left;
    for (i = left+1; i <= right; i++)
        if((*comp)(v[i],v[left]) < 0)
            swap(v, ++last, i);

    swap(v, left, last);
    userqsort(v, left, last-1, comp);
    userqsort(v, last+1, right, comp);
}

void swap(void *v[],int i, int j)
{
    void *temp;
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}

/* writeline function to write the strings as pointed by lineptr i.e. pointer of arrays to char */
void userwritelines(char *lineptr[],int countofline)
{
    while(countofline > 0){
        printf("%s\n",*lineptr);
        lineptr++;
        countofline--;
    }
}

/* usernumcmp: compare s1 and s2 numerically */
int usernumcmp(char *s1, char *s2)
{
    double v1, v2;

    v1 = atof(s1);
    v2 = atof(s2);
    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}

编译时,它会生成以下警告:

51009396@NHQ-GF-51009396 /cygdrive/d/Let us C/Practice
$ gcc -g -Wall sopointertofunc.c -o sopointertofunc.exe
sopointertofunc.c: In function ‘main’:
sopointertofunc.c:21:100: warning: pointer type mismatch in conditional expression
   15 |         userqsort((void **) lineptr, 0, nlines -1, (int (*)(void *, void *)) (numeric ? usernumcmp : strcmp));
                                                                                                           ^

您能解释一下为什么会首先生成此警告吗?虽然我知道我将 const 关键字添加到函数原型和 usernumcmp 函数定义的那一刻,警告消失了,但为什么首先出现警告?

这只是意味着在计算以下表达式时:

numeric ? usernumcmp : strcmp

usernumcmpstrcmp 有不同的指针类型。你没有显示 usernumcmp 但我会假设 int usernumcmp(int *, int*) 或接近的东西,而 strcmpint strcmp(const char*, const char*).

没关系,因为你立即将结果转换为 int (*)(void *, void *) 但如果你想摆脱警告,你应该转换函数 before计算表达式。

typedef int (*compfunc)(void*, void*);
...
userqsort((void**)lineptr, left, right, (numeric ? (cmpfunc) usernumcmp : (cmpfunc)strcmp));