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。)