2

さて、私は関数ポインタを学ぼうとしています。私はそのように基本的な関数ポインタを設定しています。

リンクされたリストを印刷する関数:

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

何をすべきか本当にわかりません。どんな洞察も役に立ちます。

4

3 に答える 3

6

2 つの間違いがあります。

まず、エラー メッセージの宣言に注意してください。ヘッダー ファイル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);
}

コードパッドで作業コードを確認してください。次のようなエラーが表示されます。

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これを行うと、2 番目のパラメーター value = return value from function で呼び出されるため、間違っています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
于 2013-10-11T04:31:57.530 に答える
3

エラー メッセージで引用されている前方宣言にタイプミスがあります。のパラメーター宣言を使用して、投稿したコード スニペットと一致する必要がありますvoid (* print_func)(void *)

于 2013-10-11T04:18:07.303 に答える
2

ヘッダーにタイプミスがあるようです。宣言は

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

(void *)print_func(void *)は有効な関数ポインタ宣言ではありません。void ポインターを受け入れ、値を返さない関数 print_func を宣言するには、次を使用します。void (*print_func)(void *)

編集: (*print_func) の周りのかっこを省略すると、関数ポインターが作成されますが、ポインターを返す関数の場合

于 2013-10-11T04:03:06.443 に答える