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;
} 

运行结果:

相关推荐
北冥you鱼15 小时前
Go 语言 GORM 使用 Preload:从关联查询到嵌套预加载的完整实践
开发语言·jvm·golang
silvamux_15 小时前
微头条爆款体平台适配实测:把交付要求变成可计算的指标
java·线性代数·算法·决策树·矩阵
论文复现现场15 小时前
DeepSeek V4.1 Flash 和 V4 Pro 有什么区别?API 价格、性能与迁移建议
java·服务器·人工智能·python·大模型api·deepseek·deepseek v4.1
dingzd9515 小时前
TikTok账号登录态失效的Cookie字段排查路径
开发语言·php·跨境电商·营销策略
abc light15 小时前
ARM 裸机开发(1)——ARM 体系结构
c语言·arm开发
曹牧15 小时前
C#:The operation has timed out
开发语言·c#
郭小李15 小时前
转发与重定向
java·服务器·数据库
你看我名字15 小时前
数眼智能 Search + Reader 实战:联网问答怎样避免“搜到了,却引用错了”
android·java·开发语言
小嘉丶学长15 小时前
Day13 · 列表与元组
linux·运维·服务器·开发语言·python
努力努力再努力wz15 小时前
【Lua入门系列】从 C++ 迭代器到 Lua 迭代器:一文深入理解 Lua 有状态以及无状态迭代器与泛型for、闭包、ipairs、pairs 和 next
开发语言·c++·lua