一、递归函数
- 递归概念:如果一个函数内部,包含了对自身的调用,则该函数称为递归函数。
- 要点:
-
- 只有能被表达为递归的问题,才能用递归函数解决。
- 递归函数必须有一个可直接退出的条件,否则会进入无限递归。
- 递归函数包含两个过程,一个逐渐递进(答案越来越接近)的过程,和一个逐渐回归(条件越来越接近)的过程。
- 递归问题:
- 依次输出 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,译音八分贝,道友,下期见!