【问题标题】:C Function Pointer MishapC 函数指针事故
【发布时间】:2013-10-19 01:20:07
【问题描述】:

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

打印链表功能:

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 *));

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

【问题讨论】:

  • 你应该叫它seq_print(s, printFunc);
  • @GrijeshChauhan 这里有实际错误。文体问题(camelCase 与下划线)不是错误
  • @Nirk 我的意思是如果void (* print_func)(void *) 是函数指针
  • @Nirk 检查这个working code
  • 反对票是怎么回事?这不是一个鼓舞人心的启示性时刻,但问题似乎没有任何错误或遗漏。

标签: c function pointers


【解决方案1】:

你有两个错误:

首先,注意错误信息中的声明:在你的头文件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

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

#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),您需要从您在 main 中调用的函数(即 my_g2)传递您想要调用的函数指针(在我的示例中为 f()) .

你想从my_g2()拨打f()

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

如下调用表达式(读取 cmets):

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

【讨论】:

  • 但是如果它像 void (*f) (void *) 我如何将值传递给它
  • @ManPerson 没听清你,你是说来自呼叫地点?从主要?
【解决方案2】:

您的标题似乎有错字。声明应该是

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

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

编辑:省略 (*print_func) 周围的括号确实会创建一个函数指针,但对于返回指针的函数

【讨论】:

  • (void *)print_func(void *) is not a valid declaration, 这是一个有效的函数指针声明。其中void *print_func(void *) 表示返回void* 类型的指针
  • 你只是把一个错字换成了另一个。
  • 这个答案和cmets一团糟。 (void *)print_func(void*) 不是有效的函数指针声明;这是一个演员表,但这无关紧要。要将print_func 正确声明为指向采用void * 的函数的函数指针,并且不返回任何内容(即void),请将其声明为void (*print_func)(void *)。您需要 print_func 周围的括号来获得正确的运算符优先级。
  • @radical7 void print_func(void) 是一个有效的指针,除了它返回一个 void 指针
  • @Nirk 你的意思是写void * print_func(void*)
【解决方案3】:

错误消息中引用的前向声明中有错字。它需要与您发布的代码 sn-p 匹配,参数声明为void (* print_func)(void *)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2012-04-03
    • 2011-08-15
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多