C功能指针不幸事故

时间:2013-10-11 04:00:43

标签: c function pointers

好的,所以我正在尝试学习函数指针。我有一个像这样的基本函数指针设置。

打印链表的功能:

void seq_print(Seq seq, void (* print_func)(void *)){
Node * p = seq->top;
    if(p == NULL){
        printf("%s %c", "There is no data to print.", '\n');
        return;
    }
    while(p != NULL){
        print_func(p->data);
        p = p->next;
    }
}

测试功能:

seq_print(s, printFunc(1));

我收到此错误:

seq.h:113:32: error: expected declaration specifiers or ‘...’ before ‘(’ token
 extern void seq_print(Seq seq, (void *) print_func(void *));

我真的不确定该怎么做,任何见解都会有所帮助。

3 个答案:

答案 0 :(得分:6)

您有两个错误:

首先,在错误消息中注意声明:在头文件seq.h中,声明函数是错误的!

 extern void seq_print(Seq seq, (void *) print_func(void *));
 //                             ^      ^ wrong = parenthesis return type

它应该是:

 extern void seq_print(Seq seq, void (*print_func) (void *));
 //                                  ^ correct   ^ = parenthesis function name 

第二,在呼叫场所。

seq_print(s, printFunc(1));
//                    ^^^ you are calling function, and passes returned value 

应该是:

seq_print(s, printFunc);
//           ^^^^^^^^^^ don't call pass function address

我的以下代码示例将帮助您更好地理解(阅读评论):

#include<stdio.h>
void my_g2(int i, (void*) f(int));  // Mistake: Notice () around void*
void f(int i){
    printf("In f() i =  %d\n", i);        
}
int main(){
    my_g2(10, f(1));  // wrong calling
    return 0;
}
void my_g2(int i, void (*f)(int)){
    printf("In g()\n");
    f(i);
}

检查codepad是否有工作代码。你可以看到错误与你得到的相似:

Line 2: error: expected declaration specifiers or '...' before '(' token
In function 'main':
Line 8: error: too many arguments to function 'my_g2'

现在正确版本的代码:

#include<stdio.h>
void my_g2(int i, void (*f)(int)); // Corrected declaration 
void f(int i){
    printf("In f() i =  %d\n", i);
}
int main(){
    my_g2(10, f);  // corrected calling too 
    return 0;
}
void my_g2(int i, void (*f) (int)){
    printf("In g()\n");
    f(i);
}

现在检查codepade输出:

In g()
In f() i =  10

修改:根据评论添加。

  

但是,如果它像void (*f) (void *)那样如何将值传递给它呢?

从main()中的调用函数(在我的示例中为my_g2),您需要传递您想要调用的函数指针(在我的示例f()中)来自您在main中调用的函数(即my_g2)。

您想从f()

致电my_g2()

我们总是在函数调用时将参数传递给函数。因此,如果您想将参数传递给f()函数,则必须在my_g2()中调用此函数时传递参数。

如下所示的调用表达式(读取注释):

seq_print(s, printFunc(1));
             ^ // first printFunc(1) will be called then seq_prints
             pass returned value from printFunc(1)

是错误的,因为如果你这样做,seq_print将被调用第二参数值=来自函数printFunc(1)的返回值。

要传递void指针,我的以下代码可能会对您有所帮助:

#include<stdio.h>
void my_g2(void* i, void (*f)(void*));
void f(void *i){
    printf("In f(), i =  %d\n", *(int*)i);
    *(int*)i = 20; 
}
int main(){
    int i = 10; 
    my_g2(&i, f);
    printf("Im main, i = %d", i);
    return 0;
}
void my_g2(void* i, void (*f)(void*)){
    printf("In g()\n");
    f(i);
}

输出@ codepade

In g()
In f(), i =  10
Im main, i = 20

答案 1 :(得分:3)

错误消息中引用的前向声明中存在拼写错误。它需要匹配您发布的代码段,参数声明为void (* print_func)(void *)

答案 2 :(得分:2)

看起来你的标题有拼写错误。声明应该是

extern void seq_print(Seq seq, void (*print_func)(void *));

(void *)print_func(void *)不是有效的函数指针声明。要声明一个接受void指针并且不返回值的函数print_func,请使用void (*print_func)(void *)

编辑:省略(* print_func)周围的parens会创建一个函数指针但是对于返回指针的函数