C 指针 - 作为参数传递的函数指针
C Pointers - Function pointer passed as a paramter
问题space:
我在理解以下最终参数的语法时遇到了一些麻烦,它是作为参数传递的函数指针:
qsort(
(void **) lineptr, 0, nlines - 1,
/* Can't understand the following syntax */
(int (*)(void*, void*))(numberic ? numcmp : strcmp)
);
还有一种我理解的替代方法:
int (*fn)(void*, void*);
if(numeric) {
fn = numcmp;
} else {
fn = strcmp;
}
同时它们都产生编译器错误:warning: assignment from incompatible pointer type
.
代码:
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "line.h"
#include "qsort.h"
#include "numcmp.h"
char *lineptr[MAXLINES];
int main(int argc, char *argv[])
{
int nlines; /* number of input lines read */
int numeric = 0;
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
/*
qsort with custome soring function passed as a parameter
throught pointers
*/
int (*fn)(void*, void*);
if(numeric) {
fn = numcmp;
} else {
fn = strcmp;
}
qsort((void **) lineptr, 0, nlines - 1, fn);
/*
Alternative:
qsort(
(void **) lineptr, 0, nlines - 1,
(int (*)(void*, void*))(numberic ? numcmp : strcmp)
);
*/
printf("Sorted and tailed:\n");
writelines(lineptr, nlines);
return 0;
} else {
printf("error: input to big to sort\n");
return 1;
}
}
它本质上是从三元表达式的结果到一个函数指针的转换,该函数指针应该是qsort
中的相应参数。因此,沿着 (a)b
的路线,使用 b
三元表达式和 a
你的函数指针声明。
int (*)(void*, void*)
声明一个指向函数的指针,该函数接受两个 void *
参数和 returns 一个 int
.
关于 (*)
的注释:
- 如果您删除括号,您将拥有一个 returns 指向 int 的指针的函数。
- 在括号中,您有一个指向 returns int 函数的指针。
找出不同。
有一个很棒的实用程序 cdecl
可以解释此类声明。这是您的案例:
cdecl> explain (int (*)(void*, void*))
cast unknown_name into pointer to function (pointer to void, pointer to void) returning int
(遗憾的是,使用三元表达式时似乎失败了:`坏字符':'。您必须弥补这一部分。)
在 cdecl.org 在线试用,或在本地安装。
(提到破译C声明的相关讨论was on Hacker News recently, where alternatives to the clockwise/spiral rule。)
问题space:
我在理解以下最终参数的语法时遇到了一些麻烦,它是作为参数传递的函数指针:
qsort(
(void **) lineptr, 0, nlines - 1,
/* Can't understand the following syntax */
(int (*)(void*, void*))(numberic ? numcmp : strcmp)
);
还有一种我理解的替代方法:
int (*fn)(void*, void*);
if(numeric) {
fn = numcmp;
} else {
fn = strcmp;
}
同时它们都产生编译器错误:warning: assignment from incompatible pointer type
.
代码:
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "line.h"
#include "qsort.h"
#include "numcmp.h"
char *lineptr[MAXLINES];
int main(int argc, char *argv[])
{
int nlines; /* number of input lines read */
int numeric = 0;
if (argc > 1 && strcmp(argv[1], "-n") == 0)
numeric = 1;
if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
/*
qsort with custome soring function passed as a parameter
throught pointers
*/
int (*fn)(void*, void*);
if(numeric) {
fn = numcmp;
} else {
fn = strcmp;
}
qsort((void **) lineptr, 0, nlines - 1, fn);
/*
Alternative:
qsort(
(void **) lineptr, 0, nlines - 1,
(int (*)(void*, void*))(numberic ? numcmp : strcmp)
);
*/
printf("Sorted and tailed:\n");
writelines(lineptr, nlines);
return 0;
} else {
printf("error: input to big to sort\n");
return 1;
}
}
它本质上是从三元表达式的结果到一个函数指针的转换,该函数指针应该是qsort
中的相应参数。因此,沿着 (a)b
的路线,使用 b
三元表达式和 a
你的函数指针声明。
int (*)(void*, void*)
声明一个指向函数的指针,该函数接受两个 void *
参数和 returns 一个 int
.
关于 (*)
的注释:
- 如果您删除括号,您将拥有一个 returns 指向 int 的指针的函数。
- 在括号中,您有一个指向 returns int 函数的指针。
找出不同。
有一个很棒的实用程序 cdecl
可以解释此类声明。这是您的案例:
cdecl> explain (int (*)(void*, void*))
cast unknown_name into pointer to function (pointer to void, pointer to void) returning int
(遗憾的是,使用三元表达式时似乎失败了:`坏字符':'。您必须弥补这一部分。)
在 cdecl.org 在线试用,或在本地安装。
(提到破译C声明的相关讨论was on Hacker News recently, where alternatives to the clockwise/spiral rule。)