C语言中的指针函数和函数指针

指针函数和函数指针这对词语总是让人迷惑,其实只是语法长得像,造成极易混淆。先来说明它们的区别

项目 指针函数 函数指针
本质 函数 指针
写法 int *func(int a) int (*p)(int a)
含义 函数执行完,返回一个指针 保存函数的入口地址,可以调用函数
括号位置 *和返回类型在一起,func是函数名 (*p)整体
内存 函数在代码段,返回值指针指向数据区 p变量本身在栈,存函数地址

然后逐一展开介绍两者定义和实际使用情况

一、指针函数--返回指针的函数

1、定义

本质是一个函数,这个函数的返回值是指针,一般定义形式是:

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

注意:不能将具有局部作用域的变量的地址作为函数的返回值(因为局部变量的内存空间在函数返回后即被释放,而该变量也不再有效),可以返回全局、static静态变量、malloc堆内存的地址

2、主要应用

a标准库就是指针函数

b返回堆上malloc开辟的内存地址(调用方free释放)

c返回数组/结构体指针,返回对象地址

示例代码

c 复制代码
#include<stdio.h>
#include<windows.h>
#include<math.h>
int* get_max(int *a,int*b )
{
    if(*a>*b)
    {
        return a;
    }
    else{
        return b;
    }
}
int main(){
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    int a=10,b=20;
    int *p=get_max(&a,&b);
    printf("%d\n",*p);  
    return 0;
} 

运行结果:

二、函数指针--指向函数的指针变量

在C程序中,可以将函数地址保存在函数指针变量中,然后用该指针间接调用函数。

1、定义--

本质是一个指针变量,这个指针保存函数的地址,指向一个函数,一般定义形式是:

返回类型 (*指针名)(参数列表)

2、主要应用

a把函数作为参数传给另一个函数,内部自动调用

c 复制代码
#include<stdio.h>
#include<windows.h>
#include<math.h>

int add(int a,int b){
    return a+b;
}
int sub(int a,int b){
    return a-b;
}
int main(){
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    //定义函数指针p,输入是2个int,输出是1个int
    int (*p)(int,int);
    p=add;//函数名代表函数入口地址
    printf("两个数的和是%d\n",p(5,4));//等价add(5,4),结果为9
    p=sub;//函数名和&函数名,都可以表示函数的地址
    printf("两个数的差是%d\n",p(5,4));//等价sub(5,4),结果为1
    return 0;
} 

b在嵌入式、单片机大量使用函数指针作为函数表、跳转表

c 复制代码
#include<stdio.h>
#include<windows.h>
#include<math.h>
void add(int a,int b){
    printf("两个数之和是%d\n",a+b);
}
void sub(int a,int b){
    printf("两个数之差是%d\n",a-b);
}
int main(){
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    //函数指针数组
    void (*func[])(int,int)={add,sub};
    func[0](5,4);
    func[1](5,4);
    return 0;
} 

两个运行结果都是如下:

c、多态事项、接口封装

硬件驱动:不同硬件,统一接口,替换不同底层函数(eg:lcd显示,切换lcd1、lcd2,只需要修改函数指针,上层代码不用改动)

d、信号处理、中断回调(单片机):中断触发后执行注册好的回调函数。

当有参数时,函数指针写起来很长,工程代码常常使用typedef重命名,示例如下:

c 复制代码
#include<stdio.h>
#include<windows.h>
#include<math.h>

int add(int a,int b){
    printf("两个数之和是%d\n",a+b);
    return a+b;
}

int sub(int a,int b){
    printf("两个数之差是%d\n",a-b);
    return a-b;
}
int main(){
    SetConsoleOutputCP(65001);
    SetConsoleCP(65001);
    //定义Func_P为函数指针-类型:指向输入2个int参数,返回1个int
    typedef int (*Func_P)(int a,int b);
    Func_P p=add;
    p(1,2);
    p=sub;
    p(1,2);
    return 0;
} 

运行结果:

相关推荐
Sarvartha16 小时前
final 关键字
java·开发语言
2601_9520477916 小时前
单一策略深度教程:用轻易云把集成任务的报错实时推送到钉钉机器人
java·机器人·钉钉
程序员Sunday16 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
数据狐(Datafox)16 小时前
淘宝图片搜索 API 落地实战:基于以图搜货搭建跨境电商选品系统
java·大数据·微服务
zhangzeyuaaa17 小时前
Ruby 多线程、GVL(GIL)与 Mutex 完全指南
开发语言·前端·ruby
谢亮_vipxieliang18 小时前
用 PHP 构建轻量级 REST API:从路由到鉴权的完整实践
开发语言·后端·php
Escalating_xu18 小时前
【C 语言】数据在内存中的存储:补码、大小端、整型陷阱与 IEEE 754 全解析
java·c语言·网络
思无邪6618 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能