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
usernumcmp
和 strcmp
有不同的指针类型。你没有显示 usernumcmp
但我会假设 int usernumcmp(int *, int*)
或接近的东西,而 strcmp
是 int strcmp(const char*, const char*)
.
没关系,因为你立即将结果转换为 int (*)(void *, void *)
但如果你想摆脱警告,你应该转换函数 before计算表达式。
typedef int (*compfunc)(void*, void*);
...
userqsort((void**)lineptr, left, right, (numeric ? (cmpfunc) usernumcmp : (cmpfunc)strcmp));
以下是该程序的摘录:我已尝试重新生成尽可能少的代码以专注于警告消息。
#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
usernumcmp
和 strcmp
有不同的指针类型。你没有显示 usernumcmp
但我会假设 int usernumcmp(int *, int*)
或接近的东西,而 strcmp
是 int strcmp(const char*, const char*)
.
没关系,因为你立即将结果转换为 int (*)(void *, void *)
但如果你想摆脱警告,你应该转换函数 before计算表达式。
typedef int (*compfunc)(void*, void*);
...
userqsort((void**)lineptr, left, right, (numeric ? (cmpfunc) usernumcmp : (cmpfunc)strcmp));