【问题标题】:Is it possible to cast printf as a parameter to another function?是否可以将 printf 作为参数转换为另一个函数?
【发布时间】:2013-01-07 20:29:08
【问题描述】:

我正在开发一个链表库,这是我写的一个函数:

/**
 * go through a linked list and perform function func for every node of the
 * linked list
 *
 * func is a function pointer to the function you would to apply on the node.
 * it should return 0 if it is successful and non-zero value otherwise.
 */
void traverse_list(linkedlist * ll, int (* func)(void * args)){
    node * temp;

    temp = ll->head;
    while( temp != NULL ){
        if((* func)(temp->val))
            fprintf(stderr,"Error processing value!\n");
        temp = temp->next;
    }
}

我的问题很简单,我尝试了travers_list(testlinkedlist,printf) 之类的方法,但它无法正常工作(printf 没有打印任何内容),我做错了什么?我能做到吗,如果可以的话,怎么做?

【问题讨论】:

标签: c pointers linked-list function-pointers


【解决方案1】:

这里有一个代码 sn-p 可以帮助你:

#include <stdio.h>

typedef int (*func)(const char* format, ...);

int main()
{
    func a = printf;
    a("Hello World\n");
    return 0;
}

现在,如果您想在 C 语言中创建自己的函数,它接受可变数量的参数,this page from the GNU manual 是一个很好的资源,可以用来解释可变参数函数的工作原理。

【讨论】:

  • 在 typedef 中 ... 是什么意思?
  • @dorafmon:这意味着函数接受可变数量的参数——就像printf一样。
  • 它表示一个可变参数函数......即,可以有无限数量的后续参数,尽管在这种情况下这些参数需要匹配 printf 的实际格式,因为那是你的想要创建一个指向的指针。
  • 我刚刚意识到一个问题,你怎么能在函数内部访问由...表示的变量?
【解决方案2】:

创建您自己的函数类型,将您的列表元素作为参数。 如果唯一匹配的函数是printf,则创建以函数为参数的遍历过程是没有意义的。 (printf 有非常独特的签名)

【讨论】:

  • static int printfAnInt(void * val){ printf("%d\n",*((int *)val));返回0; } 这就是我之前所做的。
  • @dorafmon 没错。所以你可以使用更多的函数,而不仅仅是 printf,或者预定义参数。考虑:printfAnIntToFile(void * val){ sprintf(globalDumplogHandle, "%d\n",*((int *)val)); return 0; }
  • globalDumplogHandle 在这里是什么意思?
  • @dorafmon 全局定义的文件句柄,FILE*。在调用 traverse_list 之前打开并在之后关闭。
  • 谢谢老兄!这对我来说是新事物。
【解决方案3】:

您应该将 printf 转换为函数的参数类型:

traverse_list(my_list, (int (*) (void*))&printf);

记得在使用之前将其强制转换,否则最终会出现未定义的行为。

(我假设您不想在这里更改函数的参数。)

编辑:

如果你真正要问的是你的函数应该采用什么参数,那么它应该是一个指向对应于 printf 概要的函数的指针,你可以在 man 3 printf 中找到它:

int printf(const char *format, ...);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2021-03-23
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多