11特殊函数

一、递归函数

  • 递归概念:如果一个函数内部,包含了对自身的调用,则该函数称为递归函数。
  • 要点:
    • 只有能被表达为递归的问题,才能用递归函数解决。
    • 递归函数必须有一个可直接退出的条件,否则会进入无限递归。
    • 递归函数包含两个过程,一个逐渐递进(答案越来越接近)的过程,和一个逐渐回归(条件越来越接近)的过程。
  • 递归问题:
    • 依次输出 n 个自然数:
    • 阶乘。 写一个函数,输入参数数据(阶乘数),比如5,返回1*2*3*4*5
  • 示例代码:
#include <stdio.h>// 例子1:输出自然数
void func1(int num)
{if (num < 0)                 // 1、可退出条件(自然数:非负整数){return;}func1(num-1);                // 2、逐渐回归(条件越来越接近)的过程printf("%d ", num);          // 3、逐渐递进(答案越来越接近)的过程
}// 例子2:阶乘
int func2(int num)
{if (num > 1)                 // 1、可退出条件(自然数:非负整数){num = num*func2(num-1);  // 2、逐渐回归(条件越来越接近)的过程}return num;                  // 3、逐渐递进(答案越来越接近)的过程
}// 主函数
int main(void)
{// 例子1:func1(10);// 例子2:int ret = func2(5);printf("ret == %d\n", ret);return 0;
}

可以理解为,如果条件成立,就可以一直调用自己,然后就是每次调用都有打印,但不是立即输出出来,而是当退出条件满足时它才把所有之前打印的按倒序打印出来。例如下图可以帮助理解。

 

二、静态函数

  • 背景知识:普通函数都是跨文件可见的,即在文件 a.c 中定义的函数可以在 b.c 中使用。
  • 静态函数:只能在定义的文件内可见的函数,称为静态函数。
  • 语法:
staitc void f(void) // 在函数头前面增加关键字 static ,使之成为静态函数
{// 函数体
}
  • 要点:
    • 静态函数主要是为了缩小函数的可见范围,减少与其他文件中重名函数冲突的概率。
    • 静态函数一般被定义在头文件中,然后被各个源文件包含。
  • 图解:

 

  • 示例代码:

main.c文件

#include <stdio.h>extern int num;
extern void A_func1(void);
extern void B_func1(void);// 主函数
int main(int argc, char const *argv[])
{num = 200;printf("num == %d\n", num);A_func1();// B_func1();   // 此函数在b.c中,但是被static关键字屏蔽了,无法在此处使用return 0;
}

a.c文件:

#include <stdio.h>// 一、全局变量和函数
// 全局变量
int num = 100;// 全局函数
void A_func1(void)
{printf("A_func1........\n");
}// 二、本文件的变量和函数
// 全局变量// 全局函数

b.c文件

#include <stdio.h>// 一、全局变量和函数
// 全局变量// 全局函数// 二、本文件的变量和函数
// 全局变量
static int num = 100;// 全局函数
static void B_func1(void)
{printf("B_func1........\n");
}

三、回调函数(一般不用)

  • 概念:函数实现方不调用该函数,而由函数接口提供方间接调用的函数,称为回调函数。
  • 要点:
    • 示例中函数 sighandler 是回调函数。
    • signal() 将函数回调函数传递给内核,使得内核可以在恰当的时机回调 sighandler。
    • 应用开发者和内核开发者只要约定好回调函数的接口,即可各自开发,进度互不影响。
  • 示例1:系统中的信号处理,是一个典型的利用回调函数的情形。

  • 示例2:间接调用
#include <stdio.h>
void func1(void)
{printf("1111111111\n");
}void func2(void)
{func1();
}int main(int argc, char const *argv[])
{// 1、直接调用func1();// 2、间接调用func2();// 为什么我们要间接调用???// 普通函数的写法void func(void){}  // 线程函数的写法:void* PT_func(void){func();}return 0;
}
  • 示例3:涉及函数指针的回调函数
#include <stdio.h>
// 普通函数
// 加法
int add(int a, int b)
{return a+b;
}// 减法
int substration(int a, int b)    // 该函数的类型:int  (int, int);
{return a-b;
}// 回调函数(间接调用)
int callback(int a, int (*p)(int, int), int b)
{printf("%d\n", p(a, b));
}// 主函数
int main(int argc, char const *argv[])
{// 1、直接使用回调函数callback(100, add, 200);callback(100, substration, 200);// 2、间接使用回调函数(觉得这个名字不够准确表达,可以利用这个方式进行重新命名)int (*count)(int, int (*)(int, int), int) = callback;count(100, add, 200);count(100, substration, 200);return 0;
}

至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/72028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用useContext进行全局状态管理?

在 React 中&#xff0c;使用 useContext 进行全局状态管理是一种有效的方法&#xff0c;尤其在需要在多个组件之间共享状态时。useContext 允许你在组件树中传递数据&#xff0c;而无需通过每个组件的 props 逐层传递。以下是关于如何使用 useContext 进行全局状态管理的详细指…

鸿蒙 ArkUI 实现敲木鱼小游戏

敲木鱼是一款具有禅意的趣味小游戏&#xff0c;本文将通过鸿蒙 ArkUI 框架的实现代码&#xff0c;逐步解析其核心技术点&#xff0c;包括动画驱动、状态管理、音效震动反馈等。 一、架构设计与工程搭建 1.1 项目结构解析 完整项目包含以下核心模块&#xff1a; ├── entry…

神经性肺纤维的预防方法

神经性肺纤维的预防方法 一、引言 神经性肺纤维化是一种慢性进行性肺部疾病&#xff0c;其病因复杂&#xff0c;包括遗传、环境等多种因素。该病不仅影响患者的呼吸功能&#xff0c;还可能对神经系统造成损害。因此&#xff0c;预防神经性肺纤维化显得尤为重要。本文将详细介…

azure sql 网络安全组 网络安全sql注入

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 SQL注入 1、原理 针对注入的攻击行为可描述为通过用户可控参数中注入SQL语法&#xff0c;破坏原有SQL结构&#xff0c;达到编写程序意料之外结果的攻击行为。 其…

【Day50 LeetCode】图论问题 Ⅷ

一、图论问题 Ⅷ 1、dijkstra算法 堆优化 采用堆来优化&#xff0c;适合节点多的稀疏图。代码如下&#xff1a; # include<iostream> # include<vector> # include<list> # include<queue> # include<climits>using namespace std;class myco…

利用node.js搭配express框架写后端接口(一)

Node.js 凭借其高效的非阻塞 I/O 操作、事件驱动架构以及轻量级的特点&#xff0c;成为了开发高性能服务器应用的热门选择。Express 框架作为 Node.js 上最流行的 Web 应用框架之一&#xff0c;以其简洁的 API 和丰富的中间件生态系统&#xff0c;极大地简化了 Web 后端开发流程…

【小白数学】为什么可以用拉格朗日乘子法求函数的极值【二】

我们在上一篇【小白数学】- 为什么可以用拉格朗日乘子法求函数的极值【一】已经介绍了一种较为“严谨“的方法来说明为什么拉格朗日乘子法可以帮助我们求具有等式约束条件下的函数的极值。虽然在我们的例子中”等式约束“中只有一个等式。但其实很容易推广到多个等式约束的情况…

JAVA面试_进阶部分_netty面试题

1.BIO、NIO 和 AIO 的区别&#xff1f; BIO&#xff1a;一个连接一个线程&#xff0c;客户端有连接请求时服务器端就需要启动一个线程进行处理。线程开销大。 伪异步 IO&#xff1a;将请求连接放入线程池&#xff0c;一对多&#xff0c;但线程还是很宝贵的资源。 NIO&#x…

考研出分24小时,人类精神状态图鉴

2月24日&#xff0c;上午10点起&#xff0c;各省考研初试成绩陆续公布&#xff0c;考生们或紧张的输入准考证号&#xff0c;或抱团等待“审判”。然而更魔幻的还在后头——下午4点&#xff0c;教育部竟在同一天直接发布了《2025年研考国家分数线》。 不少网友表示&#xff1a;…

川翔云电脑优势总结

在数字化时代&#xff0c;川翔云电脑依托云计算技术&#xff0c;为用户解决硬件性能瓶颈问题。川翔云电脑使用云渲码&#xff1a;【2355】 卓越硬件配置&#xff1a;配备 RTX 3090、48G 显存的 RTX 4090plus&#xff0c;支持 1 - 8 卡机配置&#xff0c;多卡并行计算能力强&am…

DeepSeek开源周Day4:三连发!突破 AI 训练瓶颈的立体解决方案,并行计算三剑客DualPipe、EPLB与Profile-data

项目地址&#xff1a; https://github.com/deepseek-ai/DualPipehttps://github.com/deepseek-ai/eplbhttps://github.com/deepseek-ai/profile-data 开源日历&#xff1a;2025-02-24起 每日9AM(北京时间)更新&#xff0c;持续五天 (4/5)&#xff01; ​ ​ 一、背景概述 …

基于W2605C语音识别合成芯片的智能语音交互闹钟方案-AI对话享受智能生活

随着科技的飞速发展&#xff0c;智能家居产品正逐步渗透到我们的日常生活中&#xff0c;其中智能闹钟作为时间管理的得力助手&#xff0c;也在不断进化。基于W2605C语音识别与语音合成芯片的智能语音交互闹钟&#xff0c;凭借其强大的联网能力、自动校时功能、实时天气获取、以…

Vite与Turbopack现代构建工具架构解析:秒级构建的性能奥秘

引言&#xff1a;传统构建工具的效能瓶颈 Shopify将前端仓库迁移至Vite后&#xff0c;HMR更新时间从Webpack的4.2秒缩短至48毫秒。Turbopack在Vercel生产环境测试中&#xff0c;增量构建速度较Webpack快700%。ChromeOS团队采用Vite后&#xff0c;生产构建从Webpack的17分钟优化…

网络基础知识-2

N个节点完全互联的网型网即N个节点的无向完全图&#xff0c;无向完全图的边数计算如下&#xff1a;每个节点都要指向其他N-1个节点&#xff0c;但是因为无向两个节点之间的边会重复&#xff0c;因此有N(N-1)/2条边HDLC&#xff08;高级数据链路控制协议&#xff09;是一种面向比…

视频级虚拟试衣技术在淘宝的产品化实践

作为一种新的商品表现形态&#xff0c;内容几乎存在于手淘用户动线全流程&#xff0c;例如信息流种草内容、搜索消费决策内容、详情页种草内容等。通过低成本、高时效的AIGC内容生成能力&#xff0c;能够从供给端缓解内容生产成本高的问题&#xff0c;通过源源不断的低成本供给…

蓝桥备赛(三)- 条件判断与循环(下)

一、for循环 1.1 for 循环语法形式 for 循环是三种循环中使用最多的 &#xff0c; for 循环的语法形式如下&#xff1a; 1.2 执行流程 for 循环中 &#xff0c; 表达式1&#xff08;初始化&#xff09;只执行一次 &#xff01; 1.3 实践 练习&#xff1a;使用 for 循环在屏幕…

VMware Fusion 虚拟机Mac版 安装CentOS 7 系统

介绍 CentOS是Community Enterprise Operating System的缩写&#xff0c;也叫做社区企业操作系统。是企业Linux发行版领头羊Red Hat Enterprise Linux的再编译版本&#xff08;是一个再发行版本&#xff09;&#xff0c;而且在RHEL的基础上修正了不少已知的 Bug &#xff0c;相…

如果更换ip地址会怎么样?网络ip地址怎么更换

IP地址&#xff0c;作为网络设备的数字身份证&#xff0c;其稳定性和安全性对于网络通讯至关重要。然而&#xff0c;在某些特定情况下&#xff0c;我们可能需要更换设备的IP地址&#xff0c;以满足安全、隐私或网络管理的需求。那么&#xff0c;如果更换IP地址会怎么样&#xf…

网络通信/IP网络划分/子网掩码的概念和使用

文章目录 概述子网的考题子网掩码的历史有/无类地址子网划分!子网掩码超网技术/CIDR子网掩码和路由IP子网掩码定义 网络规划网络规划-拆子网网络规划-组超网子网划分案例 区分于其他特殊IP地址IP地址和网络地址子网掩码和网络地址子网掩码和广播地址 子网间的通信其他 概述 本…

评估自动驾驶(AD)策略性能的关键指标

以下是针对自动驾驶&#xff08;AD&#xff09;策略性能评测指标的详细解读&#xff0c;结合其物理意义与工程价值&#xff1a; 核心评测指标分类与含义 1. 安全性指标&#xff08;Safety&#xff09; 动态碰撞率&#xff08;Dynamic Collision Ratio, DCR&#xff09; 定义&a…