【C/C++】函数指针与指针函数

简介: 函数指针是指向函数的指针变量。 因此函数指针本质上是一个指针变量,只不过该指针变量指向函数。指针变量也可以指向整型变量、字符型、数组,也可以指向函数。
作者:[柒号华仔]
个人信条:星光不问赶路人,岁月不负有心人。
个人方向:主要方向为5G,同时兼顾其他网络协议,编解码协议,C/C++,linux,云原生等,感兴趣的小伙伴可以关注我,一起交流。


1. 函数指针

1.1 概念定义

函数指针是指向函数的指针变量。 因此函数指针本质上是一个指针变量,只不过该指针变量指向函数。指针变量也可以指向整型变量、字符型、数组,也可以指向函数。
C语言中,每一个函数都有一个入口地址,函数指针就指向函数的入口地址,可以通过函数指针来调用函数。

例如 :int (*fun)(int x,int y);
另外定义一个常用函数为 void func( ),那么fun=func; fun这时就是 func( )这个函数的入口地址了。


1.2 声明方法

函数指针的声明方法为:
返回值类型 ( * 指针变量名) ([形参列表])

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

int func(int x);      //声明一个函数
int (*fun)(int x,int y);  //声明一个函数指针 
fun = func;              // 将func函数的首地址赋给指针fun 

或者将函数地址赋给函数指针:

fun = &func;

赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针fun就指向函数func(x)的首地址。


1.3 调用方法

下面的实例说明了函数指针调用函数的方法:

#include <stdio.h>
  
//返回两个数中较大的一个
int max(int a, int b){
    return a>b ? a : b;
}

int main(){
    int x, y, maxval1,maxval2;
    int (*pmax)(int, int); //定义函数指针
    pmax = max;

    printf("Input two numbers:");
    scanf("%d %d", &x, &y);

    maxval1 = (*pmax)(x,y);
    printf("Max value 1: %d\n", maxval1);

    maxval2 = pmax(x,y);
    printf("Max value 2: %d\n", maxval2);

    return 0;
} 

运行结果:

Input two numbers:5 8
Max value 1: 8
Max value 2: 8

maxval1 = (pmax)(x,y)对函数进行了调用。pmax 是一个函数指针,在前面加 就表示对它指向的函数进行调用。注意( )的优先级高于*,第一个括号不能省略。
maxval2 = pmax(x,y),pmax就是函数max的入口地址,pmax(x,y)等同于max(x,y)。
注意这里pmax是一个指针变量,它可以指向任何函数,也就是说这里指向了函数max(),但它也可以再指向其他函数。如果我们直接调用函数名称,比如max,那么它是不可变的。


1.4 函数指针作为函数参数

#include <stdio.h>
  
//返回两个数中较大的一个
int max(int a, int b){
    return a>b ? a : b;
}

int fun(int (*pfun)(int, int), int a, int b){
    pfun(a,b);
}

int main(){
    int x, y, maxval;
    
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);

    maxval = fun(max,x,y);
    printf("Max value: %d\n", maxval);

    return 0;
}

运行结果:

Input two numbers:5 8
Max value: 8

maxval = fun(max,x,y)将函数max的入口地址传给了fun的形参pfun,调用pfun实际就调用了函数max。


1.5 函数指针数组

函数指针数组是一个元素均为函数指针的数组。

#include <stdio.h>
  
//返回两个数中较大的一个
int max(int a, int b){
    return a>b ? a : b;
}

//返回两个数中较小的一个
int min(int a, int b){
    return a<b ? a : b;
}

int main(){
    int x, y, maxval, minval;

    int(*arr[2])(int x, int y) = { max, min};
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);

    maxval = arr[0](x,y);
    printf("Max value: %d\n", maxval);
    minval = arr[1](x,y);
    printf("Min value: %d\n", minval);

    return 0;
}

运行结果:

Input two numbers:5 8
Max value: 8
Min value: 5

int(*arr[2])(int x, int y) = { max, min}定义的是一个指针函数数组,数组两个元素分别为函数max和函数min的地址,调用数组arr元素实际就调用了对应函数,这一点始终没变。


2. 指针函数

2.1 概念定义

指针函数是非常常见的,它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有“函数返回值”,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。

例如: int fun(x,y); 其结构为 类型标识符 函数名(参数)
fun是一个函数,只是返回值是一个int型的指针,如果不加*,它依然是一个函数,只是返回值是一个int整型数。


2.2 调用方法

#include <stdio.h>
  
//返回两个数中较大的一个
int *max(int *a, int *b){
    int *ptr;

    ptr = *a>*b ? a : b;
    return ptr;
}

int main(){
    int x, y, *maxval;

    printf("Input two numbers:");
    scanf("%d %d", &x, &y);

    maxval = max(&x,&y);
    printf("Max value: %d\n", *maxval);

    return 0;
}

运行结果:

Input two numbers:5 8
Max value: 8

int max(int a, int *b)为指针函数,它与普通整型函数或字符型函数并没很大区别,只是函数返回为指针ptr。

3. 总结

指针函数本质是一个函数,其返回值为指针。
函数指针本质是一个指针,其指向一个函数。
指针函数:int* fun(int x,int y);
函数指针:int (*fun)(int x,int y);
与函数名在括号内,表明指针作用于函数本身,与函数名不在括号内,表明指针作用于函数返回值。

相关文章
|
9天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
32 4
|
25天前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
25天前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
25天前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
28天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
45 6
|
1月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
23 0
C++ 多线程之线程管理函数
|
1月前
利用指针函数
【10月更文挑战第2天】利用指针函数。
17 1
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
38 1