C语言函数指针解析

一、函数指针的本质

函数指针是存储函数内存地址的变量,它允许程序在运行时动态调用不同的函数。与数据指针不同,函数指针指向的是可执行代码段。

/* 典型声明方式 */
int (*func_ptr)(int, int); // 可指向任何接受两个int参数且返回int的函数

二、核心语法详解

1. 声明与初始化

函数指针的声明必须与目标函数签名严格匹配:

#include <stdio.h>

// 基础函数定义
int Add(int a, int b) { return a + b; }
int Sub(int a, int b) { return a - b; } int main() {
// 初始化方式(两种等效)
int (*fp1)(int, int) = Add; // 直接赋值
int (*fp2)(int, int) = &Sub; // 取地址赋值 printf("5+3=%d\n", fp1(5, 3)); // 输出8
printf("5-3=%d\n", (*fp2)(5, 3)); // 输出2 return 0;
}

2. 类型定义简化

使用typedef提升代码可读性:

typedef int (*ArithmeticFunc)(int, int);

ArithmeticFunc fp = Add;  // 简化后的声明

三、实际应用场景

1. 回调函数实现

函数指针最常见的用途是实现回调机制:

// 回调函数类型定义
typedef void (*Logger)(const char*); // 业务函数
void ProcessData(int data, Logger log) {
char buf[50];
sprintf(buf, "Processing: %d", data);
log(buf); // 通过函数指针回调
} // 具体回调实现
void ConsoleLogger(const char* msg) {
printf("[LOG] %s\n", msg);
} int main() {
ProcessData(42, ConsoleLogger); // 输出:[LOG] Processing: 42
return 0;
}

2. 函数指针数组

创建可扩展的操作表:

ArithmeticFunc operations[] = {
Add,
Sub,
[](int a, int b) { return a * b; }, // 注意:此lambda语法为C++特性,纯C需替换为具名函数
[](int a, int b) { return a / b; }
}; // 纯C替代方案
int Multiply(int a, int b) { return a * b; }
int Divide(int a, int b) { return a / b; }
ArithmeticFunc c_operations[] = {Add, Sub, Multiply, Divide};

四、工程实践建议

1. 错误预防

/* 必须检查空指针 */
if (func_ptr != NULL) {
func_ptr(1, 2);
} /* 避免签名不匹配 */
// int WrongFunc(float a, float b);
// func_ptr = WrongFunc; // 编译错误!

2. 典型应用案例

/* 标准库qsort用法 */
#include <stdlib.h>
int CompareInt(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
} int main() {
int arr[] = {5, 2, 9, 1};
qsort(arr, 4, sizeof(int), CompareInt);
// 排序结果:1, 2, 5, 9
return 0;
}

五、总结对比

特性 函数指针 普通函数调用
运行时灵活性 可在运行时改变指向 编译期固定
性能开销 无额外开销 无额外开销
典型用途 回调/插件/策略模式 直接功能实现

提示:在C++中可考虑更安全的std::function,但在C项目中函数指针仍是核心机制。

C语言函数指针解析的更多相关文章

  1. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  2. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  3. “对外部(局部)变量的访问”是C语言函数指针的最大弱点

    1.“对外部(局部)变量的访问”是C语言函数指针的最大弱点 . #include <stdio.h> #include <stdlib.h> /* 结构体定义 */ struc ...

  4. C语言函数指针 和 OC-Block

    C语言函数指针 和 OC-Block 一. C语言函数指针 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/2967037 ...

  5. C语言函数指针实验

    上次看Atmel的示例工程,发现人家使用了函数指针的结构体(函数指针结构体).感叹人家的C语言功夫审核,自己费劲还是只能读懂的份.不过,函数指针确实好用.今天就试试这个超牛的东西.Now let's ...

  6. C语言函数指针的用法

    函数指针是一种在C.C++.D语言.其他类 C 语言和Fortran 2003中的指针.函数指针可以像一般函数一样,用于调用函数.传递参数.在如 C 这样的语言中,通过提供一个简单的选取.执行函数的方 ...

  7. c语言函数指针的理解与使用

    1.函数指针的定义 顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: A) char * (*fun1)(char * p1,char * p2); B) char * *fun ...

  8. C语言函数指针(转载)

    二.通常的函数调用 一个通常的函数调用的例子:/* 自行包含头文件 */void MyFun(int x); /* 此处的声明也可写成:void MyFun(int) */int main(int a ...

  9. C语言函数指针变量和指针函数以及指针数组

    C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址.我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数.然后通过指针变量就可以找到并调用这 ...

  10. C语言函数指针与 c#委托和事件对比

    C语言: 函数指针可以节省部分代码量,写类似具有多态的函数,比如要比较最大值,如果不用函数指针就只能写比较某一类型比如int类型的max函数,这个max无法比较string的大小.函数指针的意义就不多 ...

随机推荐

  1. AI图像翻译

    在当今互联互通的世界中,快速准确地翻译图像中的文本的能力非常宝贵.无论您是商务人士.教育工作者.设计师还是内容创作者,Visual Paradigm Online 的 AI 图像翻译器都能提供强大的解 ...

  2. 仿京东短信验证码UI效果(鸿蒙)

    整体思路: 外层Stack布局,里面TextInput组件用来调起键盘,Row布局中循环出四个Text组件,Row布局覆盖在TextInput组件上,用来展示输入的数字. 定义两个参数,code用来接 ...

  3. PKCS#系列规范分别规定了什么

    PKCS#1:定义了RSA公钥和私钥的表示方法,以及如何进行RSA加密和签名. PKCS#2:原本是用以规范RSA加密摘要的转换方式,现已被纳入PKCS#1之中. PKCS#3:规范以Diffie-H ...

  4. 通过局域网访问连接 vite 或 Django 之类的项目

    博客地址:https://www.cnblogs.com/zylyehuo/ step1 将 vite 或 Django 类的项目启动 ip 设置为 0.0.0.0:端口 step2 查询本机电脑在当 ...

  5. HoloLens 2 开发推荐书籍

    博客地址:https://www.cnblogs.com/zylyehuo/ 书名 HoloLens 2开发入门精要--基于Unity和MRTK http://www.tup.tsinghua.edu ...

  6. 开发app步骤总结

    以下是用IDEA后端Java开发(如Spring Boot)与Android Studio前端开发app的逻辑实现步骤详解: 一.技术选择 通信协议:推荐使用RESTful API(HTTP/HTTP ...

  7. Open R1 项目进展第一期

    DeepSeek R1 发布已经两周了,而我们启动 open-r1 项目--试图补齐它缺失的训练流程和合成数据--也才过了一周.这篇文章简单聊聊: Open-R1 在模仿 DeepSeek-R1 流程 ...

  8. 【Java】String字符串格式化

    一.前言 String.format() 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", &qu ...

  9. 【SpringCloud】SpringCloud Alibaba入门简介

    SpringCloud Alibaba入门简介 why会出现SpringCloud alibaba Spring Cloud Netflix项目进入到维护模式 SpringCloud Netflix ...

  10. 【Maven】仓库

    在 Maven 的术语中,仓库是一个位置(place). Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库. 在 Maven 中,任何一个依赖.插件或者项目构建的输出,都可以称之为构件 ...