(9)ポインタ関数と関数ポインタ

ポインター宣言:

ポインタは実際には変数です。ポインタの宣言メソッドは、次のように一般的な変数宣言に似ています。

int *p;             // 声明一个 int类型的指针,该指针指向一个int类型的对象
char *p;            // 声明一个 char类型的指针,该指针指向一个 char类型的对象
int *arr[10];       // 声明一个指针数组, 该数组有10个元素,其中每个元素都是一个指向int 类型对象的指针
int*arr)[10];    // 声明一个数组指针,该指针指向一个 int 类型的以为数组
int **p;            // 声明一个二级指针p,该指针指向一个 int 类型的指针

ポインタ変数を宣言しても、メモリは自動的に割り当てられません。ポインタに間接的にアクセスする前に、ポインタを初期化する必要があります。既存のメモリを指すようにするか、動的にメモリを割り当てます。そうしないと、ポインタがどこを指しているのかわかりません。この問題には特別な注意が必要です。

関数ポインタとは何ですか?

関数ポインターの定義:関数ポインターは、関数を指すポインター変数です。したがって、「関数ポインタ」自体は最初にポインタ変数である必要がありますが、ポインタ変数は関数を指します。これは、ポインタ変数を使用して整数変数、文字タイプ、および配列を指すのと同じです。ここでは、関数を指しています。

一般的な表現は次のとおりです型指定子(*関数名)(パラメーター)

int (*fun)(int x);        // 函数指针的定义
int (*fun)(int x,int y);  // 函数指针的定义


関数ポインタの割り当て関数ポインタは、他のポインタとして定義された後、使用する前に初期化する必要があります。
関数ポインタには、関数の呼び出し関数パラメータの作成という2つの目的があります。

int (*fun)(int x,int y);  // 函数指针的定义
fun=&Function;            // 函数指针的赋值方式1
fun=Function;             // 函数指针的赋值方式2
x=(*fun)();               // 函数指针的调用方式1
x=fun();                  // 函数指针的调用方式2,错误的方式

関数識別子はそのアドレスを表し、関数は割り当てるときに括弧を必要としないため、関数を割り当てるときにアドレス演算子&を使用する必要はありません。

関数呼び出しの場合は、括弧で囲まれたパラメーターリストも含める必要があります。

関数ポインタの
使用ポインタを使用する場合、メモリ内の値を取得するためにキー*を使用する必要があります。これは、関数ポインタにも当てはまります。このアドレスに格納されている関数を(* pf)で取り出して呼び出します。


char* fun(char * p1,char* p2)
{
    
    
int i=0;
i=strcmp(p1,p2);
if(i==0)
{
    
    
return p1;
}
else
{
    
    
return p2;
}
}

int main()
{
    
    
char *(*pf)(char *,char *);
pf=&fun;
(*pf)("a","b");
return 0;
}

ポインタ関数とは何ですか?

**ポインタ関数の定義:**ポインタ関数の足場は関数であり、この関数の戻り値はポインタです。これは、返されるデータを除いて、通常の関数int function(int、int)と同様です。タイプが異なります。

_type_ *function(int, int);   // 返回的是指针地址
int function(int, int);       // 返回的是int类型的数据
int *fun(int x);              // 指针函数的定义
int * fun(int x, int y);      // 指针函数的定义
int* fun(int x,int y);        // 指针函数的定义

上記の3つの書き方は正しいですが、*は戻り値の近くで理解しやすくなっています。

関数ポインタを呼び出す
ときの関数呼び出しへのポインタ。そのポインタ関数と同じタイプの戻り値を受け取る必要があります。

typedef struct _Data{
    
    
int a;
int b;
} Data;

// 指针函数
Data* f(int a,int b)
{
    
    
Data *data=new Data;
data->a=a;
data->b=b;
return data;
}

int main()
{
    
    
Data *myData=f(4,5);
cout<<"f(4,5) = " << myData->a << myData->b;
return 0;
}

ただし、戻り値をvoid *型として定義し、呼び出し時に必要な型に戻り値をキャストすることもできます。

出力結果は同じですが、強制変換はリスクをもたらす可能性があるため、使用することはお勧めしません。戻り値の型は、任意の基本型と複合型にすることができます。ポインタを返す関数は非常に用途が広いです。

実際、すべての関数は、特定のタイプのポインターを返さない場合でも、それ自体にエントリー・アドレスを持っています。これは、ポインターと同等です。

たとえば、整数値を返す関数は、実際にはポインタ変数の値を返すことと同等ですが、この時点での変数は関数自体であり、関数全体は「変数」と同等です。


関数ポインタとポインタ関数の違い

1.さまざまな定義

  • ポインタ関数は本質的に関数であり、その戻り値はポインタです。

  • 関数ポインタは本質的に、関数を指すポインタです。

2.別の文章

  • ポインタ関数:int * fun(int x、int y);

  • 関数ポインタ:int(* fun)(int x、int y);

ポインタ関数の*はデータ型に属し、関数ポインタのアスタリスクは関数名に属することを簡単かつ大まかに理解できます。

簡単にするために、次のように2つを区別できます。括弧付きの関数名は関数ポインターです。それ以外の場合はポインター関数です。

3.使い方が違います
上記の関数ポインタとポインタ関数を使いますが、関数ポインタの使い方が多くなり、関数ポインタやコールバック関数など比較的難易度が高くなります。C++非静的の場合メンバー関数ポインタ、その使用法いくつかの違いもあります。興味のある学生は、フォローアップのツイートをフォローしたり、関連する本を自分で読んだりできます。

おすすめ

転載: blog.csdn.net/qq_40329851/article/details/114951175