定义使用函数指针


1  定义一个函数指针
且不论语法,有两种不同形式的指针函数: 一个是指向普通的C函数的指针和C++的静态成员函数,另外一个是指向C++的非静态成员函数的指针。这两者的基本区别是所有指向非静态成员函数的指针都 需要这个隐含定义:指向本类的一个This指针。注意:这两种函数指针彼此不兼容。
既然一个函数指针实际上和一个变量没有什么区别,定义它的时候也就没有什么特殊。下面的例子中我们定义3个函数指针,名字是pt2Functionpt2Member 和 pt2ConstMember. 它们指向的函数,输入一个 float和两个char 类型的变量并返回一个 int 类型的变量. 对于C++程序例子,我们的指针指向的的函数,是一个叫做 TMyClass 的 类的非静态成员函数。


// 1 define a function pointer and initialize to NULL
int (*pt2Function)(floatcharchar) = NULL; // C

int (TMyClass::*pt2Member)(floatcharchar) = NULL; // C++
int (TMyClass::*pt2ConstMember)(floatcharcharconst = NULL; // C++
2 函数调用规范
通常你不需要考虑一个函数的调用规范:编译器缺省的使用__cdecl,如果你不特别指出用哪个的话。调用规范告诉编译器如何传 递参数以及如何产生函数名。一些其他的调用规范可以举例为:__stdcall__pascal__fastcall. 注意:使用不同调用规范的函数指针彼此不兼容。

// 2 define the calling convention
void __cdecl DoIt(float a, char b, char c); // Borland and Microsoft
void DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC
3 为函数指针分派一个地址
将函数的地址分派给函数指针很容易,在函数名字之前冠以取址符&就可以了。

// 3 assign an address to the function pointer
// Note: Although you may ommit the address operator on most compilers
// you should always use the correct way in order to write portable code.


// C
int DoIt (float a, char b, char c){ printf("DoIt\n"); return a+b+c; }
int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }

pt2Function = DoIt; // short form
pt2Function = &DoMore; // correct assignment using address operator


// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };

/* more of TMyClass */
};

pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
4 比较函数指针
你可以和通常方式一样使用比较符号(==, !=)。下面的例子中我们检查变量 pt2Function 和 pt2Member ,它们分别指向的函数 DoIt 和 TMyClass::DoMore. 如果指向正确就会输出代表争取的字符串。

// 4 comparing function pointers

// C
if(pt2Function >0){ // check if initialized
if(pt2Function == &DoIt)
printf("Pointer points to DoIt\n"); }
else
printf("Pointer not initialized!!\n");


// C++
if(pt2ConstMember == &TMyClass::DoMore)
cout << "Pointer points to TMyClass::DoMore" << endl;
5  使用函数指针调用函数
在C语言中我们可以通过 * 符号来调用函数指针,也可以不使用函数名而代以函数指针的名字。C++使用两个符号 * 和 ->* 来调用类的非静态函数指针。如果呼叫在其他成员函数中发生,那么就得加上this指针。

// 5 calling a function using a function pointer
int result1 = pt2Function (12'a''b'); // C short way
int result2 = (*pt2Function) (12'a''b'); // C

TMyClass instance1;
int result3 = (instance1.*pt2Member)(12'a''b'); // C++
int result4 = (*this.*pt2Member)(12'a''b'); // C++ if this-pointer can be used

TMyClass* instance2 = new TMyClass;
int result4 = (instance2->*pt2Member)(12'a''b'); // C++, instance2 is a pointer
delete instance2;
6  如何像传递一个参数一样传递函数指针
你可以在调用一个函数的时候把函数指针当作参数来传递。在回调函数中尤其要使用到这个技术。下边这个例子演示了如何把指针传递给一个函数,这个 函数使用一个 float 和两个 char 类型的参数并有一个int类型的返回值。

//------------------------------------------------------------------------------------
// 6 How to Pass a Function Pointer


// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(floatcharchar))
{
int result = (*pt2Func)(12'a''b'); // call using function pointer
cout << result << endl;
}

// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}
7  如何返回一个函数指针
看上去有点怪,但是一个函数指针可以作为一个函数的返回值。下面的例子中提供了两种把函数指针作为返回值的解决方案。这个函数输入两个float类 型的参数,返回一个float类型的值。

//------------------------------------------------------------------------------------
// 7 How to Return a Function Pointer
// 'Plus' and 'Minus' are defined above. They return a float and take two float



// Direct solution: Function takes a char and returns a pointer to a
// function which is taking two floats and returns a float. <opCode>
// specifies which function to return

float (*GetPtr1(const char opCode))(floatfloat)
{
if(opCode == '+')
return &Plus;
else
return
 &Minus; // default if invalid operator was passed
}


// Solution using a typedef: Define a pointer to a function which is taking
// two floats and returns a float

typedef float(*pt2Func)(floatfloat);

// Function takes a char and returns a function pointer which is defined
// with the typedef above. <opCode> specifies which function to return

pt2Func GetPtr2(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return
 &Minus; // default if invalid operator was passed
}


// Execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;

// define a function pointer and initialize it to NULL
float (*pt2Function)(floatfloat) = NULL;

pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'
cout << (*pt2Function)(24) << endl; // call function using the pointer


pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'
cout << (*pt2Function)(24) << endl; // call function using the pointer
}
8  如何使用函数指针数组
使用函数指针数组非常有意思,这个技术提供了一种从索引中选择函数的方法。实现的语法看上去很复杂,经常导致理解错误。下面的例子中我们可以看 到两种定义和使用函数指针数组的方法。前一种使用 typedef ,后一种直接定义数组。使用哪一种全凭你的兴趣。
//------------------------------------------------------------------------------------
// 8 How to Use Arrays of Function Pointers


// C ---------------------------------------------------------------------------------

// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(floatcharchar);

// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
printf("\nExecuting 'Array_Of_Function_Pointers'\n");

// define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are arrays
// with 10 pointers to functions which return an int and take a float and two char


// first way using the typedef
pt2Function funcArr1[10] = {NULL};

// 2nd way directly defining the array
int (*funcArr2[10])(floatcharchar) = {NULL};


// assign the function's address - 'DoIt' and 'DoMore' are suitable functions
// like defined above in 1-4

funcArr1[0] = funcArr2[1] = &DoIt;
funcArr1[1] = funcArr2[0] = &DoMore;

/* more assignments */

// calling a function using an index to address the function pointer
printf("%d\n", funcArr1[1](12'a''b')); // short form
printf("%d\n", (*funcArr1[0])(12'a''b')); // "correct" way of calling
printf("%d\n", (*funcArr2[1])(56'a''b'));
printf("%d\n", (*funcArr2[0])(34'a''b'));
}


// C++ -------------------------------------------------------------------------------

// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(floatcharchar);

// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;

// define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are
// arrays with 10 pointers to member functions which return an int and take
// a float and two char


// first way using the typedef
pt2Member funcArr1[10] = {NULL};

// 2nd way of directly defining the array
int (TMyClass::*funcArr2[10])(floatcharchar) = {NULL};


// assign the function's address - 'DoIt' and 'DoMore' are suitable member
// functions of class TMyClass like defined above in 2.1-4

funcArr1[0] = funcArr2nd use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.

[1] = &TMyClass::DoIt;
funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;
/* more assignments */

// calling a function using an index to address the member function pointer
// note: an instance of TMyClass is needed to call the member functions

TMyClass instance;
cout << (instance.*funcArr1[1])(12'a''b') << endl;
cout << (instance.*funcArr1[0])(12'a''b') << endl;
cout << (instance.*funcArr2[1])(34'a''b') << endl;
cout << (instance.*funcArr2[0])(89'a''b') << endl;
}



<think>首先,用户的问题是:“如何定义使用函数指针”,我需要用中文回答。 我的回答必须包括: 1. 对问题的解答。 2. 在回答末尾,输出“§§相关问题§§”,然后列出3-5个相关问题。 3. 第一行必须是“§§相关问题§§”,不能换行分散。 4. 整个回答要符合规则,否则无效。 示例格式显示: - 先回答问题。 - 然后输出“§§相关问题§§”。 - 接着是相关问题列表,用数字编号。 所以,结构是: - 回答部分。 - “§§相关问题§§” - 1. 问题1 - 2. 问题2 - 3. 问题3 现在,针对问题“如何定义使用函数指针”,我需要提供清晰的中文解释。 关键点: - **函数指针**:在C或C++中,函数指针是指向函数指针变量。 - **定义**:声明一个函数指针变量,指定其类型。 - **使用**:通过指针调用函数。 在C语言中: - 定义函数指针:`return_type (*pointer_name)(parameter_types);` - 使用:`pointer_name = function_name;` 然后 `(*pointer_name)(arguments);` 或直接 `pointer_name(arguments);` 在C++中类似,但可能涉及类成员函数指针。 我将用中文解释。 回答大纲: 1. 介绍函数指针的概念。 2. 解释如何定义函数指针。 3. 解释如何使用函数指针。 4. 给出一个简单的代码示例。 代码示例应该用代码块,如示例中的Python代码。 最后,生成3-5个相关问题。 相关问题应该基于用户的问题和我的回答。例如: - 函数指针的应用场景。 - 如何传递函数指针作为参数。 - 函数指针与回调函数的关系。 - 在C++函数指针的变体。 确保问题是相关的。 列出3-5个问题: 1. 函数指针有哪些常见的应用场景? 2. 如何将函数指针作为参数传递给其他函数? 3. 在C++中,函数指针函数对象(functor)有什么区别? 4. 函数指针在动态链接库(DLL)中的作用是什么? 5. 如何定义使用类成员函数指针? 现在,构建回答。 回答部分: - 先解释定义。 - 然后使用。 - 代码示例。 代码示例:使用C语言,因为函数指针常见于C/C++。 示例代码: ```c #include <stdio.h> // 定义一个函数 int add(int a, int b) { return a + b; } int main() { // 定义一个函数指针,指向一个返回int,参数为两个int的函数 int (*func_ptr)(int, int) = &add; // 或直接 = add; // 使用函数指针调用函数 int result = func_ptr(3, 4); printf("Result: %d\n", result); // 输出 Result: 7 return 0; } ``` 在回答中,解释这个代码。 最后,相关问题。 完整回答: [回答部分] §§相关问题§§ 1. 函数指针在回调函数中是如何应用的? 2. 如何定义使用指向类成员函数指针? 3. 函数指针数组是什么?如何创建和使用它? 4. 在C++中,lambda表达式如何替代函数指针? 5. 函数指针函数引用有什么区别? 确保有3-5个。 现在,写回答。</think>### 如何定义使用函数指针 函数指针是一种特殊类型的指针变量,它指向一个函数的内存地址,而不是数据。通过函数指针,可以动态地调用不同的函数,这在回调机制、事件处理等场景中非常有用。以下是定义使用函数指针的详细步骤,以C语言为例(C++类似)。 #### 1. **定义函数指针** - 函数指针的声明语法为:`return_type (*pointer_name)(parameter_types);` - `return_type`:函数返回值的类型(如 `int`、`void`)。 - `pointer_name`:函数指针变量的名称。 - `parameter_types`:函数参数的类型列表(如 `int, int`)。 - 示例声明: - 指向一个返回 `int` 且接受两个 `int` 参数的函数:`int (*func_ptr)(int, int);` #### 2. **使用函数指针** - **赋值**:将函数地址赋给指针函数名本身代表其地址,因此可以直接赋值:`func_ptr = function_name;` 或使用取地址符:`func_ptr = &function_name;`。 - **调用**:通过指针调用函数。语法为:`(*func_ptr)(arguments);` 或简写为 `func_ptr(arguments);`。 - **场景示例**: - 作为回调函数传递。 - 在函数数组中使用,实现多态行为。 #### 3. **代码示例** 以下是一个完整的C语言示例,演示如何定义使用函数指针: ```c #include <stdio.h> // 定义两个简单函数 int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int main() { // 定义函数指针:指向返回int,参数为两个int的函数 int (*operation)(int, int); // 声明 // 使用函数指针:赋值并调用 operation = add; // 将add函数地址赋给指针 printf("Addition: %d\n", operation(10, 5)); // 输出: Addition: 15 operation = subtract; // 重新赋值为subtract函数 printf("Subtraction: %d\n", operation(10, 5)); // 输出: Subtraction: 5 return 0; } ``` - **解释**: - 此代码定义一个函数指针 `operation`,它可以指向任何具有相同签名的函数(即返回 `int` 并接受两个 `int` 参数)。 - 通过改变指针的赋值,可以动态调用不同的函数(`add` 或 `subtract`)。 #### 注意事项 - **兼容性**:函数指针必须与目标函数的签名(返回类型和参数类型)完全匹配,否则会导致错误。 - **C++扩展**:在C++中,函数指针可以用于类成员函数(需使用 `&ClassName::function` 语法),但需注意 `this` 指针的处理。 - **安全**:避免野指针问题,确保指针被正确初始化后再使用函数指针是高效灵活的编程工具,但需谨慎使用以避免复杂性和错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值