指针、数组名与对数组名取地址、函数指针、auto关键字、回调函数与代理模式(一)

本文探讨了函数指针的核心概念,包括函数地址、声明方式以及如何通过函数指针调用。强调了函数指针在动态传递不同函数时的作用。同时,文章对比了数组名与对数组名取地址的差异,解析了他们在内存表示和类型上的区别,并举例说明了在实际操作中应注意的细节。最后,提到了函数指针在回调函数和代理模式中的应用。
摘要由CSDN通过智能技术生成

函数指针重要概念

  • 与数据项类似,函数也有地址,函数的地址是存储其机器语言代码内存的开始地址。该特性对程序而言,可以将另一个函数的地址作为参数的函数,它允许在不同的时间传递不同的函数地址,这意味着可以在不同的时间使用不同的函数;
  • 声明函数指针时,必须同时指定函数的返回类型和参数列表;
  • 若对于函数指针double (*funcPtr)(int)而言可以通过两种方法调用,一是:double y = (*funcPtr)(5),二是double y = funcPtr(5);
  • []的优先级比*优先级高,通常使用如double (*funcPtr[3])(const double *, int)= {f1, f2, f3}表示三个函数指针的数组。创建一个指向整个数组的指针可用如下形式表示double (*(*ptr)[3]))(const double *, int),ptr是一个指针,指向一个包含三个元素的数组,这些元素有该声明的其他部分描述;
  • 对于数组int pa[3] = {0, 1, 2};而言,pa&pa的区别。在大多数情况下,pa都是数组第一个元素的地址,即&pa[0],从数字上说,pa&pa相同,但他们的类型不同,&pa的类型为int(*)[3],一种差别是pa+1为指向下一个元素的地址,而&pa+1为数组pa后面加上一个12字节内存块的地址(假定地址为4字节),另一个差别就是要得到第一个元素,只需要对pa解除一次引用,但需要对&pa解除两次引用,即**&pa == *pa == pa[0];
#include <iostream>
using namespace std;

double betsy(int);
double pam(int);

void estimate(int lines, double (*pf)(int)); 

int main()
{
    int code;
    cout << "How many lines of code do you need?" << endl;
    cin >> code;
    cout << "Here's Bytes's estimate:\n";
    estimate(code, betsy);
    cout << "Here's Pam's estimate:\n";
    estimate(code, pam);
}

double betsy(int lines)
{
    return 0.05 * lines;
}

double pam(int lines)
{
    return 0.01 * lines;
}

void estimate(int lines, double (*pf)(int))
{
    cout << lines << " lines will take ";
    cout << (*pf)(lines) << " hour(s)" << endl;
}

输出:
在这里插入图片描述

#include <iostream>
using namespace std;

const double* func1(const double arr[], int n);
const double* func2(const double [], int n);
const double* func3(const double *, int n);

int main()
{
    double arr[3] = {1.i11, 2.22, 3.33};

    const double* (*ptr1)(const double *, int) = func1;
    //const double* (*ptr2)(const double *, int) = func2;
    auto ptr2 = func2; //after c++11 
    cout << "Usage pointers to functions:\n";
    cout << "Address Value\t:\tValue\n";
    cout << (*ptr1)(arr, 3) << "\t:\t" << *(*ptr1)(arr, 3) << endl;
    cout << ptr2(arr, 3) << "\t:\t" << *ptr2(arr, 3) << endl;

    const double* (*ptrA[3])(const double *, int) = {func1, func2, func3};
    cout << "\nUsing an array of pointers to functions:\n";
    cout << "Address Value\t:\tValue" << endl;
    for(int i = 0; i < 3; i++)
    {
        cout << ptrA[i](arr, 3) << "\t:\t" << *ptrA[i](arr, 3) << endl;
    }

    //auto ptrB= ptrA;
    const double* (**ptrB)(const double *, int) = ptrA;
    cout << "\nUsing a pointer to a pointer to a function:\n" << endl;
    cout << "Address Value\t:\tValue\n";
    for(int i = 0; i < 3; i++)
    {
        cout << ptrB[i](arr, 3) << "\t:\t" << *ptrB[i](arr, 3) << endl;
    }


    cout << "\nUsing pointer to an array of pointers:\n";
    cout << "Address Value\n";
    //const double* (*(*ptrC)[3])(const double *, int) = &ptrA;
    auto ptrC = &ptrA;
    cout << (*ptrC)[0](arr, 3) << "\t:\t" << *(*ptrC)[0](arr, 3) << endl;


    const double* (*(*ptrD)[3])(const double *, int) = &ptrA;
    const double *ptrDp = (*ptrD)[1](arr, 3);
    cout << ptrDp << "\t:\t" << *ptrDp << endl;
    cout << (*(*ptrD)[2])(arr, 3) << "\t:\t" << *(*(*ptrD)[2])(arr, 3) << endl;
    return 0;
}


const double* func1(const double *arr, int n)
{
      return arr;
}

const double* func2(const double *arr, int n)
{
      return arr + 1;
}

const double* func3(const double *arr, int n)
{
      return arr + 2;
}

在这里插入图片描述

注意对const double* (*(*ptrC)[3])(const double *, int) = &ptrA;const double* (**ptrB)(const double *, int) = ptrA;的理解:

  • ()的优先级比*高,如const double* f1(const double *, int);表示返回值类型为const double*的函数;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值