函数指针介绍及其用法

1、前言

  这里有两个绕来绕去的东西,函数指针和指针函数;对于四个字,我们首先只看后面两个字,这样方便我们记忆;

  函数指针,本质是指针;是指向函数入口地址的指针。

  指针函数,本质是函数;返回类型为指针的函数。

2、介绍

  对于一个函数而言,函数名是指向函数第一条指令的常量指针。在程序编译之后,编译器会为每个函数分配首地址,即该函数第一条指令的地址。一般情况下,我们可以用一个指针来保存这个地址,而这个指针就是函数指针。所以函数指针实际就是指向函数的别名,我们就可以用这个指针来调用这个函数。

3、用途

  函数指针有两个用途:(1)调用函数,(2)做函数的参数

4、声明方法

  普通声明方法:

 1 type (*f)(type &,type &);

  利用typedef来简化声明和定义的操作:

 1 typedef void (*vp) (int&,int&);

  具体的简化效果在后面给出例子明了地说明简化带来的方便。

5、示例

  定义三个函数,分别对两个int型的变量做操作,up函数用于两个变量的加一操作,down函数用于两个变量的减一操作,print函数用于打印对应的操作和操作后的结果,实现代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 /* --- function declare --- */
 5 void up(int &a,int &b);
 6 void down(int &a,int &b);
 7 void print(void (*p) (int &,int &),int &a,int &b); //function pointer work as parameter
 8 
 9 /* --- main function --- */
10 int main()
11 {
12     int a = 2,b = 3;
13     char in = '1';
14     while(in!='0')
15     {
16         cout<<endl<<"--- up(+) , down(-) , quit(0) ---"<<endl;
17         cin>>in;
18 
19         void (*p) (int &,int &); //define function pointer
20         switch(in)
21         {
22             case '0':
23                 break;
24             case '+':
25                 p = up; //function pointer work as function caller
26                 print(p,a,b);
27                 break;
28             case '-':
29                 p = down;
30                 print(p,a,b);
31                 break;
32             default:
33                 cout<<"put error"<<endl;
34         }
35     }
36 }
37 
38 /* --- function define --- */
39 void up(int &a,int &b)
40 {
41     a++;
42     b++;
43 }
44 void down(int &a,int &b)
45 {
46     a--;
47     b--;
48 }
49 void print(void (*p) (int &a,int &b),int &a,int &b) //function pointer work as parameter
50 {
51     p(a,b);
52     if(p==up)
53         cout<<"up: "<<"a="<<a<<" b="<<b<<endl;
54     else if(p==down)
55         cout<<"down: "<<"a="<<a<<" b="<<b<<endl;
56 }

  利用typedef简化之后的代码如下,可以看出的确较少了一部分繁琐又冗长的代码;

 1 #include<iostream>
 2 using namespace std;
 3 
 4 /* --- function declare --- */
 5 typedef void (*vp) (int&,int&);
 6 void up(int &a,int &b);
 7 void down(int &a,int &b);
 8 void print(vp,int &a,int &b); //function pointer work as parameter
 9 
10 /* --- main function --- */
11 int main()
12 {
13     int a = 2,b = 3;
14     char in = '1';
15     while(in!='0')
16     {
17         cout<<endl<<"--- up(+) , down(-) , quit(0) ---"<<endl;
18         cin>>in;
19 
20         vp p; //define function pointer
21         switch(in)
22         {
23             case '0':
24                 break;
25             case '+':
26                 p = up; //function pointer work as function caller
27                 print(p,a,b);
28                 break;
29             case '-':
30                 p = down;
31                 print(p,a,b);
32                 break;
33             default:
34                 cout<<"put error"<<endl;
35         }
36     }
37 }
38 
39 /* --- function define --- */
40 void up(int &a,int &b)
41 {
42     a++;
43     b++;
44 }
45 void down(int &a,int &b)
46 {
47     a--;
48     b--;
49 }
50 void print(vp p,int &a,int &b) //function pointer work as parameter
51 {
52     p(a,b);
53     if(p==up)
54         cout<<"up: "<<"a="<<a<<" b="<<b<<endl;
55     else if(p==down)
56         cout<<"down: "<<"a="<<a<<" b="<<b<<endl;
57 }

运行结果:

6、注意事项

(1)声明函数指针时,其返回值类型、参数个数、参数类型等应该与需要它指向的函数保持一致,否者编译器会报错;

(2)利用函数指针指向某一个函数的时候,只需要将函数名赋值给函数指针即可,不需要附带函数名后的参数;

1 p = up; //correct
2 p = up(a,b); //error

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mukekeheart的iOS之旅

Java基础——数据类型之间的转换

Java数据类型分为三大类,即布尔型、字符型和数值型。其中数值型又分为整型和浮点型。Java的基本数据类型(8种)为布尔型boolean(1字节);字符型cha...

2366
来自专栏海天一树

小朋友学Python(15):函数

函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。 函数能提高应用的模块性,和代码的重复利用率。 Python提供了许多内建函数,比如print(...

3117
来自专栏PHP技术

PHP函数

请点击上面蓝色PHP关注 你知道这些简单的函数中的方法吗? count() 函数计算数组中的单元数目或对象中的属性个数。 对于数组,返回其元素的个数,对于其他值...

2695
来自专栏hbbliyong

python 函数参数的传递(参数带星号的说明)

python中函数参数的传递是通过赋值来传递的。函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个...

3188
来自专栏Ryan Miao

String的按值传递,java传参都是传值

java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? String和int参数传递是按值传递还是引用传递? 一道面试题目,String的传递: p...

3036
来自专栏青枫的专栏

当类中的方法全部都是 static 关键字修饰时 ,它的构造方法最好作为 private 私有化,理由是方法全是 static, 不知道的人会去new对象去调用,需要调用构造方法。 但 static的

当类中的方法全部都是 static 关键字修饰时 ,它的构造方法最好作为 private 私有化,理由是方法全是 static, 不知道的人会去new对象去调用...

282
来自专栏前端知识分享

第196天:js---调用函数的五种方式

672
来自专栏前端儿

ES6笔记(4)-- Symbol类型

类似字符串String的声明方式 var str = 'str'; Symbol的声明方式类似,它调用构造函数Symbol()

942
来自专栏Nian糕的私人厨房

C_10 指针拓展

指针是内存地址 指针在定义的时候, * 表示指针标识符 指针在使用的时候, * 表示取内容

553
来自专栏JetpropelledSnake

Python面试题之Python中的类和实例

类,在学习面向对象我们可以把类当成一种规范,这个思想就我个人的体会,感觉很重要,除了封装的功能外,类作为一种规范,我们自己可以定制的规范,从这个角度来看,在以后...

602

扫码关注云+社区