指针函数 函数指针

最后更新于 2023-03-27 648 次阅读


CSDN:惟肖肖肖

http://t.csdn.cn/gAIBV

指针函数

本质是一个函数,不过它的返回值是一个指针。

其声明的形式:类型名 *函数名(函数参数列表);

int * pfun(int, int);

返回类型可以是任何基本类型和复合类型。

返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。

void型指针

void指针是一种不明确类型的指针,任何指针都可转换为void指针。

指针有两个非常重要的信息: 指针的值(指针目标对象的内存首地址) 指针指向对象的类型

注意点:void指针只保存了 指针的值 并没有记录 指针指向对象的类型。因此在用到对void指针解引时,需要先把void指针转换成原本的数据类型。

int n = 500; //定义一个int变量
int * p = &n; //定义int类型指针
void * pv = p; //定义void指针,只保存了p的值(即n的内存首地址)

//错误的写法
printf("%d\n", *pv); //这里会报错,因pv指针没有明确数据类型,因此也不知道需要取多少字节的数据

//正确写法
printf("%d\n", *( (int*)pv ) ); //先把pv指针转为int类型指针,再对其解引

函数指针

函数指针是指向函数的指针变量。

因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数

C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。

函数指针的声明方法为:

返回值类型 ( * 指针变量名) ([形参列表]);

“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:

  • int func(int x); /* 声明一个函数 */
  • int (f) (int x); / 声明一个函数指针,是一个指向返回值为int的函数的指针 */
  • f=func; /* 将func函数的首地址赋给指针f */

或者使用下面的方法将函数地址赋给函数指针:

f = &func;
#include <iostream>
void func(int x) { std::cout << "simple func " << x << std::endl; }
void funcx(int a, int b) { std::cout << a << " " << b << std::endl; }

void (*p)(int);

void func2(void (*p)(int), void(*x)(int, int)) {
    (*p)(2);
    (*x)(3, 3);
}

static float score[][4] = { {60,70,80,90},{56,89,34,45},{34,23,56,45}};

int main()
{
    p = func;
    (*p)(6);

    func2(func, funcx);

    std::cout << *(*(score + 1)) << std::endl;
}

Typedef关键字与意义

int (*PF)(int *, int); PF是一个函数指针变量,用于指向返回值为int,一个int类型参数的函数。

当使用typedef声明后,则PF就成为了一个函数指针类型,即 typedef int (*PF)(int *, int); 这样就定义了返回值的类型。

再用PF作为返回值来声明函数:PF func(int); // func(int)就是一个返回值为函数指针,一个int类型参数的函数

再用PF来声明:PF phead; //phead就是一个函数指针

typedef int a[10]; // a 类型是 int[10];(存放int型数据的数组)
a arr; // 定义一个数组:int arr[3];

typedef void (*p)(void); //p 类型是void ( * )void
p A; //是指void(*A)(void);

语法上typedef属于存储类声明说明符。
a[10]不是int的别名,(*p)(void)不是void的别名。
上面的语句把a声明为具有10个int元素的数组的类型别名,p是一种函数指针的类型别名。

函数指针对象赋值用法

typedef void (*IapFun)(void);  //定义函数指针
void func(void);               //定义函数
IapFun fun  = func;            //为函数指针对象赋值
fun();                         //这里的fun()其实就相当于跳转到了func()里
typedef void (* IapFun)(void);          //定义函数指针
IapFun jump2app;                         //定义函数指针对象
jump2app=(IapFun) * (vu32*)(appxaddr+4); //为函数指针对象赋值 appxaddr为函数指针地址,例如0x08000000
jump2app();                              //调用函数