• C++指针解读(7)-- 指针和函数


    前面我们讲过用指针变量作为函数参数。这里讲指向函数的指针变量和返回指针的函数。

    1、指向函数的指针变量

    跟变量一样,函数也会存储在内存空间中,函数的内存空间有一个起始地址,每次调用函数时就从该入口地址开始执行函数代码。

    既然函数有地址,我们就可以定义一个指向该函数的指针变量。比如,我们可以定义这样的指针变量:

    int (*pfun)();

    从右往左读,先是(),表示这是一个函数;然后是(*pfun),表示一个指针指向这个函数;最后是void,表示这个函数返回int。

    如果我们把指针的挂号去掉:

    int *pfun();

    则表示一个返回int*类型的函数。

    所以,定义指向函数的指针变量的形式为:

    (1)类型名 (*指针变量名)(函数参数列表)

    (2)typedef 类型名 (*指针变量名)(函数参数列表)

    这里必须注意,一个函数的指针变量只能指向定义时指定的类型的函数。比如int (*p)()表示函数指针变量p可以指向返回值是int的无参数函数。

    2、函数指针的使用

    我们来看一个使用函数指针的例子:

    1. int max(int a, int b) {
    2. if (a > b) {
    3. return a;
    4. }
    5. else {
    6. return b;
    7. }
    8. }
    9. int main()
    10. {
    11. int a = 3;
    12. int b = 7;
    13. int (*p)(int, int);
    14. p = max;
    15. int ret = p(3, 7);
    16. //也可以这么调用
    17. //int ret = (*p)(3, 7);
    18. printf(" max = %d\n", ret);
    19. return 0;
    20. }

    使用函数指针的注意事项:

    (1)函数指针只能指向定义时指定的函数类型。比如int (*p)(int, int)就只能指向返回值是int,形参列表是2个int的函数。比如int max(int a, int b); int min(int a, int b)等这样的函数都可以。

    (2)函数指针变量要调用哪个函数,就让指针指向哪个函数。

    比如p = max,这里形参的列表是不用写的,只要写函数名就可以了。因为函数名代表函数的入口地址,让函数指针指向这个入口地址就可以了。

    (3)用函数指针变量代替函数运行,比如p(a, b)。

    (4)函数指针变量不能进行算术运算,p+n, p++等都是错误的。

    3、用函数的指针作函数参数

    指向函数的指针可以作为函数参数,把函数的指针作为形参,这样就能够在被调用函数中使用实参函数。

    有下面几种传递函数指针的方式:

    (1)显式地将形参定义为指向函数的指针

    void func(int nValue,int (*pf)(int,int));

    (2)第二个形参为函数类型,会自动转换为指向此类函数的指针

    void func(int nValue,int pf(int,int));

    (3)

    typedef int (*PF)(int, int);

    void func(int nValue, PF pf)

    例子:

    1. int add(int i, int j) {
    2. return i + j;
    3. }
    4. int sub(int i, int j) {
    5. return i - j;
    6. }
    7. typedef int (*pfun)(int i, int j);
    8. int compute(pfun fun, int i, int j) {
    9. return fun(i, j);
    10. }
    11. int main()
    12. {
    13. int a = 3;
    14. int b = 7;
    15. int (*pf1)(int i, int j);
    16. pf1 = sub;
    17. std::cout << compute(pf1, b, a) << std::endl;
    18. return 0;
    19. }

    4、函数指针数组

    函数指针也可以存放在数组中。

    假如有这么一个应用场景,系统需要根据输入的参数来选择需要执行的具体函数。

    输入‘+’,则执行add()函数;输入‘-’,则执行sub()函数。

    1. typedef int (*operation)(int i, int j);
    2. operation ops[128] = { 0 };
    3. ops['+'] = add;
    4. ops['-'] = sub;
    5. operation op1 = ops['+'];
    6. printf(" 3 + 4 = %d\n", op1(3, 4));
    7. operation op2 = ops['-'];
    8. printf(" 7 - 3 = %d\n", op2(7, 3));

    这里我们用'+', '-'作为数组的索引,因为char其实就是int类型,我们把数组长度定义为128,是因为ASCII共有128个字符,这样每个ASCII字符都能作为数组的索引存放。

    5、返回指针值的函数

    定义返回指针值的函数的形式为:

    类型名 *函数名(参数列表)

    返回指针时要注意这几种情况:

    (1)如果返回的是函数内部局部变量的指针,那么这个指针出函数作用域时,其指向的对象已经失效。这种情况下就成了迷途指针或悬空指针。

    1. int* invalidPointer() {
    2. int tmp = 3;
    3. return &tmp; //出函数后tmp对象已被释放,返回的指针成了: 迷途指针/悬空指针
    4. }

    (2)如果是在函数内部动态分配了内存的指针,记得在函数外部释放内存,避免产生内存泄漏。

    1. int* localPointer() {
    2. int* pi = (int*)malloc(sizeof(int));
    3. return pi;
    4. }
  • 相关阅读:
    中国移动发布《新型智慧城市白皮书》(2023版)
    谷歌宣布:今年将Android 12L系统交付于三星、联想和微软
    【25】c++设计模式——>责任链模式
    283. 移动零
    Vue路由懒加载
    数据机构——顺序表的基本操作
    vue3从基础到入门(一)
    where条件中有权限校验的自定义函数优化方法
    Python——字符串
    cesium 鹰眼图2
  • 原文地址:https://blog.csdn.net/mars21/article/details/133849408