【C语言进阶篇】数组指针都学过了那么函数指针你了解嘛?

简介: 【C语言进阶篇】数组指针都学过了那么函数指针你了解嘛?

📋 前言

  🌈hello! 各位宝子们大家好啊,数组指针的概念我们学完了那么今天就给大家打来函数指针的讲解!

  ⛳️函数既然也有自己的地址那么,是不是也可以用指针来存储呢?答案是是的!今天就来看一下函数指针是什么,以及如何应用!

  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐

  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

🔥 注:vs2022 等C语言学习工具都在《学习工具专栏》。 还有各种实用调试技巧有兴趣可以去看看!

💬 函数指针

函数指针是什么其实很简单?我们依旧可以类比一下

  • 数组指针 —— 指向数组的指针
  • 函数指针 —— 指向函数的指针

💭 函数名 和 &函数

函数既然有地址那么该怎么拿到函数的地址,数组名是数组的地址,&数组可以拿到整个数组的地址!那么函数名是函数的地址嘛?

  • 其实函数名是函数的地址
  • &函数名也是函数的地址

📚 代码演示:

#include <stdio.h>
void test()
{
    printf("hehe");
}
int main()
{
    printf("%p\n", &test);
    printf("%p\n", test);
    return 0;
}

📑 代码结果:

💭 函数指针的定义

数组指针我们知道他的指针类型是 int (*)[ ] 这样接收的,那么函数指针该怎么样书写呢?假设我们的函数指针类型的

  • 那么就应该这样书写
  • int (*pf)(int, int ) = test;
  • *表明了他是个指针,是用 pf 接收的函数地址
  • int ()(int , int )说明了他是一个函数
  • 第一个int是他的返回值,括号里面的是参数类型
  • 这和数组指针是不是非常类似int (*pf)[ ]= &arr;
  • * 表明了他是个指针,是用 pf 接收的数组地址
  • int [ ]说明了他是一个数组

✅总结:

  • int (* )(int, int)是函数指针类型
  • int (*)[ ] 是数组指针类型

📚 代码演示:

#include <stdio.h>
int add(int x, int y)
{
    return x + y;
}
int main()
{
    int (*pf)(int, int) = add;
    printf("%d\n", add(2, 3));
    printf("%d\n", (*pf)(2, 3));
    return 0;
}

📑 代码结果:

💻 函数指针pf 和 函数名的关系

大家看啊!既然我们是用 pf 接收的函数地址,而函数名本身代表的是函数地址。所以我们可不可以说 pf 等于函数名!

  • int (*pf)(int, int) = add;
  • 所以 pf == add
  • 那么我们在用指针解引用调用函数时,是不是可以直接写
  • pf(2,3) == add(2,3)我们来试一试

📚 代码演示:

#include <stdio.h>
int add(int x, int y)
{
    return x + y;
}
int main()
{
    int (*pf)(int, int) = add;
    printf("%d\n", add(2, 3));
    printf("%d\n", pf(2, 3));
    return 0;
}

📑 代码结果:

💻 函数指针的应用

阅读两段有趣的代码:

  • 这俩句代码是干嘛呢?
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);

📜 代码一讲解

其实代码一(*(void (*)())0)();是调用0地址处的函数,

  1. 将 0 转换为函数指针类型 void (*)()
  2. 然后进行函数调用 (*)()

🔥 注:此代码来自于《C的陷阱与缺陷》

其实这里最难理解的话就是 0 这个数字,这段代码我们只能先从 0 这个数字下手。

  • 大家看 0x00ff40 我们可以理解为**16**进制的整数!
  • 当然 我们也可以理解 0x00ff40 是个地址毕竟地址也是编号嘛!是以 16 进制编写的。

这时数字 0 就好理解了,我们可以把 0 当成一个地址里面,默认他是个整形。所以那么把地址 0 强制转换为一个函数指针

  • 然后再进行解引用调用这个函数
  • (*(void (\*)())0)();

📜 代码二讲解

其实代码二void (*signal(int , void(*)(int)))(int);可以这样理解,

  1. signal 是 一个函数声明signal(int , void(*)(int))
  2. signal 函数有 俩个参数,第一个参数的类型是int ,第二个参数的类型是 void(*)(int) 函数指针类型
  3. 该函数指针指向的函数 有一个 int 类型的参数,返回类型是 void
  4. signal 函数的返回类型也是一个 函数指针类型void (*signal(int , void(*)(int)))(int);
  5. 该函数指针 指向的函数 有一个int 类型的参数,返回类型是 void

这样看起来这段代码是不是不好理解,那么我们对指针类型重名一下就看的简洁好懂了!

#include <stdio.h>
int main()
{
    typedef void(*pf_t)(int);
    pf_t signal(int, pf_t);
    void (*signal(int, void(*)(int)))(int);
    return 0;
}

📝全篇总结

✅ 归纳:

好了以上就是关于函数指针是什么,如何定义和应用就全部讲解完毕啦!

  函数指针是干嘛的?

  函数指针的定义

  函数指针的应用

  函数指针实例

☁️ 把本章的内容全部掌握,铁汁们就可以熟练应用函数指针啦!快去练起来吧!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖

拜托拜托这个真的很重要!

你们的点赞就是博主更新最大的动力!

有问题可以评论或者私信呢秒回哦。


目录
相关文章
|
2月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
124 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
2月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
179 9
|
2月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
64 7
|
2月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
186 6
|
3月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
算法 编译器 程序员
C语言学习笔记—P11(数组<2>+图解+题例+三子棋游戏<初级>)
C语言学习笔记(数组<2>+图解+题例+三子棋游戏<初级>)
147 0
C语言学习笔记—P11(数组<2>+图解+题例+三子棋游戏<初级>)
|
存储 C语言
C语言学习笔记—P10(数组<1>+图解+题例)
C语言学习笔记(数组<1>+图解+题例)
167 0
|
C语言
C语言学习笔记——数组(二)
C语言学习笔记——数组
196 0
C语言学习笔记——数组(二)
|
C语言
C语言学习笔记——数组(一)
C语言学习笔记——数组
180 0
C语言学习笔记——数组(一)
|
机器学习/深度学习 C语言 编译器
【C语言】学习笔记4——数组
我直接把控制语句和循环跳过了。大致看了一下,讲得太繁琐了。这部分在后面用C写数据结构就可以练得很熟了。 1. 数组: 由数据类型相同得一系列元素组成。内存上是一片连续得存储单元。 2. 声明 int nums[5] // 内含5个int类型元素的数组 float ...
1012 0

热门文章

最新文章