参考:

  1. 函数指针和指针函数用法和区别
  2. C++函数指针、指针函数、返回值为函数指针的函数浅谈
  3. C++类成员函数指针使用介绍

正文:

  1. 指针函数
    指针函数,本质是一个函数,它是返回值为指针的一个函数。
声明格式:类型名称 * 函数名(参数表)
#include <iostream>

using namespace std;

int * getNum(){
    int num = 36;
    return &num;
}

int main(){
    
    int * num = getNum();
    cout << "num : " << *num << endl;

	return 0;
}
warning: address of local variable ‘num’ returned [-Wreturn-local-addr]
     int num = 36;
         ^~~
//且没有返回值
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

出现警告:返回的是局部变量 num 的地址,是因为num是一个函数内部的一个局部变量指针 , 因为本地变量的声明周期应该只位于函数内部,一旦函数执行完毕则被释放。为了避免错误,所以用堆指针。

#include <iostream>

using namespace std;

int * getNum(){
    int num = 36;
    return new int (num);
}

int main(){

    int * num = getNum();
    cout << "num : " << *num << endl;

    delete num;
    num = nullptr;
    
    return 0;
}

在调用指针函数时,需要一个同类型的指针来接收其函数的返回值指针。不过也可以将其返回值定义为 void * 类型,在调用的时候强制转换返回值为自己想要的类型,如下:

#include <iostream>

using namespace std;

typedef struct _Data{
    int a;
    int b;
}Data;


void * f(int a,int b){
    Data * data = new Data;
    data->a = a;
    data->b = b;
    return data;
}


int main(){

    Data * myData = static_cast<Data * >(f(4,5));
    cout << myData->a << " " <<myData->b << endl;

    delete myData;
    myData = nullptr;
    return 0;
}

其输出结果是一样的,不过不建议这么使用,因为强制转换可能会带来风险。

  1. 函数指针
    函数指针,本质是一个指针,它是指向一个函数的指针,也就是存放这个函数的地址。函数指针就是指向函数的指针。
声明格式:类型名称  (*函数名) (参数)

2.1 使用函数指针接受函数,然后再用函数指针来调用函数

格式: 类型名称  (*函数名) (参数) = 函数名(函数地址)
#include <iostream>

using namespace std;


int add(int a ,int b){
    return a + b;
}

void printHi(){
    cout << "hi ~~,print..." << endl;
}

int main() {

    cout << add(7,8) <<endl;

    int (*f1)(int,int) = add;
    cout << f1(18,24) <<endl;
    cout << add << endl;
    cout << &add << endl;
    cout << f1 << endl;
    cout << *f1 << endl;

    cout << "--------------------------" << endl;
    void(*f2)() = printHi;
    f2();
    cout << printHi << endl;
    cout << &printHi << endl;
    cout << f2 << endl;
    cout << *f2 << endl;

    return 0;
}

//后台输出:
15
42
1
1
1
1
--------------------------
hi ~~,print...
1
1
1
1

Address of function ‘add’ will always evaluate to ‘true’(fix avilable)
解释了为什么函数的地址为1。

2.2 函数指针的应用场景
直接使用函数名调用函数不可以吗?为什么多此一举使用函数指针调用呢?
函数名调用函数,是在函数声明实现后才可以调用。
如果函数没有实现,就不能函数名调用函数,这时使用函数指针调用。函数指针调用一般出现在SDK开发中。

#include <iostream>


using namespace std;


int add(int a , int b){
    return a + b;
}

int subtract(int a , int b){
    return a - b;
}

int multiplic(int a , int b){
    return a * b;
}

int division(int a , int b){
    return a / b;
}

int calc(int a , int b , int (*func)(int, int)){
    return func(a , b);
}


int main() {

    int a = 8;
    int b = 4;

    cout << "a = " << a << ", b = " << b << endl;

    cout << "a + b = " << calc(a,b,add) << endl;
    cout << "a - b = " << calc(a,b,subtract) << endl;
    cout << "a * b = " << calc(a,b,multiplic) << endl;
    cout << "a / b = " << calc(a,b,division) << endl;

    return 0;
}

//后台输出:
a = 8, b = 4
a + b = 12
a - b = 4
a * b = 32
a / b = 2

2.3 typedef 简化函数指针

typedef int (*func)(int, int)
int calc(int a , int b , func f){
    return f(a , b);
}

typedef 简化函数指针的时候,不需要后面跟上名字,因为函数指针 int (*func)(int, int) 中的func 就是简化出来的的类型。
int calc(int a , int b , func f) 中的 func 是类型,f 类似于形参。

更多推荐