C++中的函数指针
为了指向数据,使用了指针。像普通的数据指针一样,我们有function pointers ,指向functions 。一个函数的地址被存储在一个函数指针中。
简介
它们存储了由一个函数的所有指令组成的内存块的起始地址或入口点,更加详细。我们使用函数指针来完成几个任务。一个例子是防止代码冗余,这也是大多数程序员追求的目标。
例如,如果你正在编写一个sort() ,你可能想让函数的调用者选择以升序或降序对数据进行排序。有些程序员可能需要以升序或降序进行排序,而其他程序员可能更喜欢介于两者之间。函数指针允许程序员选择如何对数据进行排序。
回调、事件驱动的程序等等都是函数指针的应用。本文将解释函数指针是如何工作的,并给你几个例子,以及代码样本。
前提条件
要读完这篇文章,读者应该。
- 安装了Codeblocks IDE。
- 对C++语言有基本的了解。
- 具备C++函数的基本知识。
函数指针的基本语法
void (*fun_ptr)(int);
fun_ptr = &fun;
我们可以把函数指针看作是普通的C++函数。其中void是函数的返回类型。*fun_ptr 是一个指向函数的指针,它需要一个int 参数。这就好比我们在声明一个名为*fun_ptr 的函数,该函数接收int ,并返回void 。
编写函数指针声明的关键是把它看作是一个函数声明,但用*fun_name 而不是func_name 。指针符号* 在函数指针声明之前。因为函数指针可以接受许多参数,它可以指向任何接受两个integer 参数并返回void 的函数。
一个函数的地址
为了获得一个函数的地址,我们必须首先说明该函数的名称。我们不需要调用该函数。
考虑一下下面的例子。
#include <iostream>
using namespace std;
int main()
{
std::cout << "The address of function main(): " <<&main<< std::endl;
return 0;
}
在上面的程序中,我们要显示的是main()函数的地址。我们只列出了函数的名称,没有括号,也没有参数来打印main()函数的地址。因此,一个函数的地址只是它的名字,没有任何括号或参数。
你应该知道的关于函数指针的事实
- 与其他指针不同,函数指针指向的是代码而不是数据。可执行代码的起点通常存储在一个函数指针中。
- 我们不会像对待普通指针那样用函数指针来分配或取消内存。
- 正如我们在上面的程序中看到的那样,一个函数的名称也可以用来查找该函数的地址。
- 普通指针可以和普通指针一样,与函数指针阵列一起使用。
- 在代替switch的情况下,可以利用函数指针。
- 一个函数指针,像一个数据指针一样,可以作为参数提供,并从一个函数中返回。
间接调用一个函数
通过使用函数指针,我们可以使用一个函数的名称来调用它。通过函数指针调用函数的语法与直接调用函数的语法相同。
让我们来看看一些代码例子。
例1
#include <iostream>
using namespace std;
int add(int x , int y)
{
return x+y;
}
int main()
{
int (*funcptr)(int,int); // Declaration of function pointer
funcpointr=add; // In this case we are pointing to the add function
int sum=funcpointr(7,10);
std::cout << "Sum=" <<sum<< std::endl;
return 0;
}
继续运行这里的代码 输出。
Sum value is : 17
我们声明了函数指针,int (*funcptr)(int,int) ,然后在前面的程序中把add() 函数的地址存储在funcptr 。这意味着add() 方法的地址被存储在funcptr 。现在我们可以使用funcptr 来调用add() 方法。add() 函数被短语funcptr(7,10) 调用,其结果被放在sum 变量中。
例2
#include <iostream>
using namespace std;
void printname(char *name)
{
std::cout << "Name:" <<name<< std::endl;
}
int main()
{
char x[30]; // array declaration
void (*ptr)(char*); // function pointer declaration
ptr=printname; // storing the address of printname in ptr.
std::cout << "Enter name: " << std::endl;
cin>>x;
cout<<x<<endl;
ptr(x); // calling printname() function
return 0;
}
输出。
Enter name:
Daniel
Daniel
Name: Daniel
我们在前面的程序中定义了函数printname() ,它需要一个char 指针作为参数。我们声明我们的函数指针为void (*ptr)(char*) 。
我们用表达式ptr=printname ,将printname() 函数的地址设置为ptr。现在我们可以使用ptr 语句来调用printname() 方法。在输入名称为Daniel 后,我们得到上面的输出。
将函数指针作为参数传递
我们可以在我们的程序中传递函数指针作为参数,如下所示。
#include <iostream>
using namespace std;
void function1()
{
cout<<"function1 is called";
}
void function2(void (*funcptr)())
{
funcptr();
}
int main()
{
function2(function1);
return 0;
}
输出。
function 1 is called
在上面的程序中,我们把一个函数指针作为参数传给了function2() 函数。function1() 的地址是由main() 方法提供给func2()函数的。function2() 函数以这种方式间接地调用了function1() 函数。
总结
在这篇文章中,我们已经了解了函数指针。我们已经看到了函数指针的重要性,它们被用于何处,以及它们如何使我们的程序更容易开发和维护。