1

最近Linuxカーネルを読んでいます。多くの場合、構造体「typedef xxx f(xxx)」を使用していることがわかりましたが、その仕組みがわかりません。(関数ポインタのようなもの?)

これが私のテストコードです。

#include<stdio.h>
typedef int Myfunc(int);
typedef int (*point_to_myfunc)(int);
static Myfunc example;
static int example(int a){
    printf("example a=%d\n", a);
    return 1;
}
static void example2(Myfunc* f){
    printf("example2\n");
    f(2);
}
static void example3(int (*)(int));
static void example3(int (*point_to_Myfunc)(int)){
    printf("example3\n");
    point_to_Myfunc(3);
}
int main(){
    point_to_myfunc f=&example;
    example2(f);
    example3(f);
    return 0;
}

誰か私に簡単な説明をしてもらえますか? もぅ~

4

4 に答える 4

3
#include <stdio.h>
typedef int Myfunc(int);

Myfunc型の名前です。intこれは、引数を取り、 を返す関数intです。

typedef int (*point_to_myfunc)(int);

point_to_myfuncint引数を取り、 を返す関数へのポインタintです。必要に応じて、次のこともできtypedef Myfunc *ptr_to_myfunc;ます (同じタイプの別の名前)。

static Myfunc example;

exampleこれは、「タイプの呼び出された関数が存在する」ことを示していMyfuncます。

static int example(int a)
{
    printf("example a=%d\n", a);
    return 1;
}

これは の可能な実装ですexampleMyfuncその型の関数の定義でtypedef 名を like に使用することはできません。

static void example2(Myfunc *f)
{
    printf("example2\n");
    f(2);
}

これは、へのポインターを受け取る関数ですMyfunc。この行f(2);は、引数 2 で指定された関数を呼び出し、戻り値を無視します。

static void example3(int (*)(int));

これは、引数を取り結果を返すexample3関数へのポインタを取る関数として宣言します。またはまたはと書かれている可能性があります。intintstatic void example3(point_to_myfunc);static void example3(ptr_to_myfunc);static void example3(Myfunc *);

static void example3(int (*point_to_Myfunc)(int))
{
    printf("example3\n");
    point_to_Myfunc(3);
}

これは の実装ですexample3

int main(void)
{
    point_to_myfunc f = &example;
    example2(f);
    example3(f);
    return 0;
}

このプログラムにはf、関数へのポインターである変数があります。興味深いことに、次のことができます。

    point_to_myfunc f2 = example;
    point_to_myfunc f3 = *example;

などなど、すべて同じ意味です。

以下を使用してそれらを呼び出すこともできます。

    (*f2)(101);
    (**f3)(103);

初期化の標準表記では、 も も使用しませ&*。古い学校の C プログラマーなら、(*f2)(101)表記法を使用して関数ポインターを呼び出すことができます。C89 標準より前では、それが関数ポインターを呼び出す唯一の方法でした。f2(101);モダンなスタイルは代わりになりがちです。

于 2013-03-22T06:16:12.123 に答える
1

Vaughn Catoは正しいです、さらに、

typedef int (*point_to_myfunc)(int);

関数ポインタを定義します。これは、point_to_myfuncが型であることを意味し、次のように使用できます。

point_to_myfunc f=&example;

これで、fはexample()と同じようになり、f()でメソッドexampleを呼び出すことができます。

于 2013-03-22T06:01:54.740 に答える
1
typedef int Myfunc(int);

これは、Myfunc が int パラメーターを取り、int を返す関数の型であることを意味します。

この行:

static Myfunc example;

と言っているのと同じです

static int example(int);

example 関数を前方宣言します。

これの用途の 1 つは、特定の関数セットが特定の目的で使用されていることを明確にすることです。

typedef char CharacterConverter(char);

extern CharacterConverter make_upper_case;
extern CharacterConverter make_lower_case;

extern void process_string(char *s,CharacterConverter *f);
    // easier to see that make_upper_case and make_lower_case are valid arguments.
于 2013-03-22T05:49:33.183 に答える
0

typedefは、型を定義するときに役立ちます。

例: char *a, b;ポインタ「a」と文字bを定義しました。 char *a, *b2つのcharポインタを定義しました。typedefを使用すると、次のことが明確になります。

typedef char* PCHAR;
PCHAR a,b;

これで、aとbの両方がcharポインタになります。

typedef int Myfunc(int);
typedef int (*point_to_myfunc)(int);

2行は、関数形式と関数を指すことができるポインターのタイプのペアを定義しているため、それらを使用すると明確でわかりやすくなります。

于 2013-03-22T05:53:56.003 に答える