最近在学习c++,想一边学习一边做笔记。使用博客来做笔记好像也挺大材小用的,没办法,也在培养写博客的习惯,就随便写一些吧。那么,就来说一下我在学习c++函数指针时的想法。
说起函数指针,隐约记得大一上c语言这门课有学,然而那时自己愚钝,就是理解不了(或许那时理解了,却忘了)。现在重新学起,感觉没那么吃力了,毕竟有学习了其它语言的积累。
那么,什么是函数指针?在我理解,就是指向函数的指针。有了这种指针,那么可以把函数进行传递。如果没有指针,一个函数就只能被调用。把函数进行传递,可以有什么作用?下面看一个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <iostream> double add(double, double); double sub(double, double); double operation(double (*pf)(double, double), double, double); int main(int argc, char const *argv[]) { /* code */ using namespace std; double a = 1.4; double b = 1.5; cout << "ensure the operator is:"; char op = getchar(); double (*opf)(double, double);//声明一个函数指针变量,指向的函数结构是有两个double型参数,并且返回double类型的值 switch (op) { case '+': opf = add; break; case '-': opf = sub; break; } cout << "the result is :" << operation(opf, a, b) << endl; return 0; } double add(double a, double b) { return a + b; } double sub(double a, double b) { return a - b; } double operation(double (*pf)(double, double), double a, double b) { return pf(a, b); }
|
这段程序的目的是接收一个”+”或”-“号字符,然后决定对两个变量进行加法或减法运算,最后输出计算结果。
首先定义两个函数add
和sub
,分别用来进行加法和减法运算。然后通过输入的字符来判断,用一个函数指针类型变量opf
指向对应的函数(也可以说是函数的地址赋给这个变量)。最后调用opf
来进行运算。
现在可能看不出函数指针有什么优点。但假如运算的种类多了,有了乘除,或者其它符合double ...(double, double)
结构的函数。如果不用函数指针,就必须在每个case
语句中调用方法,无疑有了重复代码。所以有了函数指针,编程会变得灵活(肯定也还有其它高级的用法)。
相似的Javascript
当我知道函数指针的基本使用时,脑海中马上浮现出Javascript中也有类似的使用场景。因为Javascript中函数是一种对象,可以赋值给任意变量。也就是说,Javascript中变量可以指向函数。先看看如何用Javascript实现上面c++的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <html> <head> <title>begin</title> </head> <body> <p>ensure the operator is:</p> <input id="operator" width="100px" /> <button id="btn" onclick="onClick()">calc</button> <p id="result-output"></p> </body> <script type="text/javascript"> function add(a, b) { return a + b; } function sub(a, b) { return a - b; } function operation(func, a, b) { return func(a, b); } function onClick() { var a = 1.4, b = 1.5; var input = document.getElementById('operator'); var opf; switch (input.value) { case '+': opf = add; break; case '-': opf = sub; break; default: } document.getElementById('result-output').innerHTML = 'the result is :' + operation(opf, a, b); } </script> </html
|
相似度是不是很高。唯一的区别就是在javascript中,变量是弱类型的,不用声明它是指向函数对象的变量。
所以通过类比,我更容易理解函数指针了。就是一个变量来引用函数,但是这个变量是具体函数的类型的。什么叫具体函数的类型?一个函数的结构是怎样的?看看函数原型的定义:返回值类型+函数名+参数类型。函数名是具体的,其它两部分是类型。也就是说,只有“返回值类型+参数类型”才能把函数归纳起来成为类型。像上面的例子:
double add(double, double);
double sub(double, double);
函数add
和sub
的类型就是返回值为double
类型,参数为两个double
类型。后面就定义了这样一个类型的函数指针:double (*opf)(double, double)
。看到这个声明,可以这样理解:opf变量的类型是函数指针,它只能指向返回值为double
类型的,有两个double
类型参数的函数。