関数と関数ポインタ

結論として

定義された関数の場合、関数名、関数アドレス、および関数ポインターは、関数のエントリーアドレスを指します。

証明する

まず、次の関数を定義します。

/**********************************************************
* 函数:FuncPointer
* 描述:证明函数指针与函数名关系
* 参数:无
* 返回:无
* 备注:
**********************************************************/
void FuncPointer(void)
{
    
    
	cout << "调用FuncPointer函数" << endl;
	cout << FuncPointer << endl;//输出函数名
	cout << &FuncPointer << endl;//输出函数地址
	cout << *&FuncPointer << endl;//输出函数地址指向对象
}

主な機能:

int main()
{
    
    
    FuncPointer();//函数名调用
    (&FuncPointer)();//地址方式调用
    (*&FuncPointer)();//间址方式调用(函数地址指向对象)
 }

実行結果:
関数名と関数ポインタ
オブジェクトへの関数名、関数ポインタ、関数ポインタの値が等しく、同じエントリアドレス値を指していることがわかります。関数はこれら3つの方法で呼び出すことができます。

関数ポインタの使用

以上のことから、関数は関数ポインタの形で呼び出すことができるため、関数のアドレス値をポインタ変数に割り当てると、このポインタ変数を介して関数を呼び出すことができます。だから問題は、このポインタのタイプはどのように定義されているのかということです。このポインター変数に関数アドレスを割り当てるには、ポインター変数に関連付けられているタイプが、関数ポインターに関連付けられているタイプと同じである必要があります。したがって、最初に関数のタイプを理解する必要があります。

関数タイプ

  1. 関数定義:タイプ関数名(正式なパラメータテーブル);関数は3つの部分で構成されます:(1)タイプは関数の戻り値タイプ、(2)関数名は呼び出し元の関数のアドレスエントリ、(3)正式パラメータテーブルは、必須の外部パラメータ関数に渡されます。2つの関数の(1)と(3)が同じである場合、これら2つの関数を同じタイプの関数と呼びます。次の2つの関数f1とf2は、同じタイプの関数です。
float f1(float x)
{
    
    
	return (4 / (1 + x * x));
}

float f2(float x)
{
    
    
	return ((float)sqrt(1 + pow(x, 2)));
}
  1. typedefを使用して、関数タイプを定義します。typedefタイプ関数タイプ名(関数パラメーターリスト)
typedef float IntegralFunction(float x);
  1. 定義された関数タイプを使用して、関数を宣言したり、変数を定義したりします
IntegralFunction f1, f2;//声明f1,f2
  1. 関数ポインターの定義
    (1)関数タイプ*ポインター変数名;
    (2)タイプ(*ポインター変数名)(仮パラメーターリスト);
    たとえば、上記で定義した関数タイプを使用して、関数ポインターを宣言します。
    (1)IntegralFunction * p ;
    (2))Float(* p)(float);
    (2)を使用してポインター変数を定義する場合、* pの両側の括弧を小さくすることはできないことに注意してください。括弧が欠落している場合は次のようになります。 float * p(float)であり、pは戻り型になります。これはint *の関数です。

関数ポインタの使用:

float f1(float x)
{
    
    
	return (4 / (1 + x * x));
}

float f2(float x)
{
    
    
	return ((float)sqrt(1 + pow(x, 2)));
}
/**********************************************************
* 函数:ComputeIntegral
* 描述:求定积分
* 参数:*func - 原函数地址
		a - 积分下限
		b - 积分上限
* 返回:积分结果
* 备注:
**********************************************************/
float ComputeIntegral(IntegralFunction *func, float a, float b)
{
    
    
	const int EdValue = 1000;
	int n = (int)((float)EdValue * (b - a));

	int i;
	float Tn,h;

	h = (b - a) / n;
	Tn = (h * (func(a) + func(b))) / 2;

	for (i = 1; i < n; i++)
	{
    
    
		Tn += h * func(a + i * h);
	}

	return Tn;
}
/**************求函数积分***************/
typedef float IntegralFunction(float x);
IntegralFunction f1, f2;//声明f1,f2
float ComputeIntegral(IntegralFunction* func, float a, float b);

ComputeIntegral関数は、定積分のサイズを計算します。渡された関数ポインター* funcは、同じタイプのさまざまな関数を渡すのに便利です。さまざまな関数の定積分を計算するには、渡された関数を変更するだけです。関数ポインタ内。次のようにComputeIntegral関数を呼び出して、0-1のf1の定積分サイズを計算します。

int main()
{
    
    
    float a,b,result;
    cout << "计算定积分" << endl;
    cout << "输入积分下限" << endl;
    cin >> a ;
    cout << "输入积分上限" << endl;
    cin >> b ;
    result = ComputeIntegral(f1,a,b);
    cout << "定积分的值:" << result << endl;
 }

演算結果:
関数ポインタの使用
関数ポインタを使用すると、関数のアドレスを関数パラメータとして他の関数に渡すことができます。この関数は、渡された関数ポインターを介して渡された関数を呼び出して、特定の関数を実行できます。

おすすめ

転載: blog.csdn.net/qq_36439722/article/details/105345450