C功能指针不幸事故

Man*_*son 2 c pointers function

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

打印链表的功能:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

测试功能:

seq_print(s, printFunc(1));
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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

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

Gri*_*han 6

你有两个错误:

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

 extern void seq_print(Seq seq, (void *) print_func(void *));
 //                             ^      ^ wrong = parenthesis return type
Run Code Online (Sandbox Code Playgroud)

它应该是:

 extern void seq_print(Seq seq, void (*print_func) (void *));
 //                                  ^ correct   ^ = parenthesis function name 
Run Code Online (Sandbox Code Playgroud)

第二,在呼叫的地方.

seq_print(s, printFunc(1));
//                    ^^^ you are calling function, and passes returned value 
Run Code Online (Sandbox Code Playgroud)

应该:

seq_print(s, printFunc);
//           ^^^^^^^^^^ don't call pass function address
Run Code Online (Sandbox Code Playgroud)

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

#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);
}
Run Code Online (Sandbox Code Playgroud)

检查键盘是否有工作代码.你可以看到错误类似于你得到的错误:

Line 2: error: expected declaration specifiers or '...' before '(' token
In function 'main':
Line 8: error: too many arguments to function 'my_g2'
Run Code Online (Sandbox Code Playgroud)

现在正确版本的代码:

#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);
}
Run Code Online (Sandbox Code Playgroud)

现在检查codepade输出:

In g()
In f() i =  10
Run Code Online (Sandbox Code Playgroud)

编辑:根据评论添加.

但是,如果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)
Run Code Online (Sandbox Code Playgroud)

是错误的,因为如果这样做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);
}
Run Code Online (Sandbox Code Playgroud)

输出@codepade:

In g()
In f(), i =  10
Im main, i = 20
Run Code Online (Sandbox Code Playgroud)