链式访问与递归
1. 链式访问
1.1链式访问进一步理解
在函数2的内容中,我们只是简单利用了strlen函数来简单表达了一下链式访问,在这篇中,我们来更近一步了解一下。
一个函数的返回值做了另一个函数的参数,这个返回值如同链条串起了两个函数
我们来看个例子
#include <stdio.h>
int funcA()
{
// 我们假定这个函数是一个整型的计算函数,它的返回值就是计算结果
int result = 42; // 我们假定计算结果为 42
return result; // 返回计算结果
}
void funcB(int value)
{
// 这个函数我们要用来打印funcA函数的计算结果,那么这个函数的参数就是funcA函数的返回值
printf("funcB接收到的值为:%d\n", value);
}
int main()
{
// 使用链式访问
funcB(funcA()); // 首先调用funcA,然后将返回值作为funcB的参数
return 0;
}
上述代码的运行结果如下
1.2 链式访问例题
这里有一道关于链式访问的典型例题
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
// 结果是啥?
return 0;
}
在这个例子中,printf函数被嵌套调用了三次,每次调用,他都会返回一个整数(成功打印字符的个数)
- 最里层的printf函数没有发生调用, 而是打印了43这个整数,并返回打印的字符数(这里是2,因为打印了’4’和’3’两个字符)。
- 接着,这个返回值(2)被传递给外一层的printf作为参数,即printf(“%d”, 2);。它会打印数字2,并返回1(因为它打印了’2’这一个字符)。
- 最后,这个返回值(1)再次被传递给最外层的printf作为参数,即printf(“%d”, 1);。它会打印数字1。
最后的运行结果如下
由上述两个实例,我们来对链式访问进行小结
1.3 链式访问的特点
- 简化代码:链式访问可以减少中间变量的使用,使代码更加简洁。
- 可读性:当函数之间的调用关系清晰且逻辑紧密时,链式访问可以提高代码的可读性。
- 注意返回值:链式访问要求前一个函数有返回值,并且该返回值可以作为后一个函数的参数。
- 函数调用顺序:链式访问中函数的调用顺序是固定的,从前往后依次执行。
1.4 注意事项
- 返回值类型匹配:确保前一个函数的返回值类型与后一个函数的参数类型相匹配。
- 错误处理:链式访问中,如果前一个函数出现错误并返回了错误码或特殊值,需要确保后一个函数能够正确处理这些值。
- 可读性权衡:虽然链式访问可以简化代码,但过度使用可能会导致代码可读性下降。因此,在使用时需要权衡可读性和简洁性之间的关系。
2. 递归
2.1 引言
在编程中,递归是一个强大的工具。它允许函数直接或间接地调用自身,从而解决一些看似复杂的问题。本文将深入解析C语言中的递归,并通过实战应用来加深理解。
2.2 递归的基本思想
递归,简单来说就是函数直接或间接地调用自身。递归包含两个关键部分:递归关系和递归终止条件。递归关系定义了函数如何调用自身,而递归终止条件则指定了递归何时停止。
在C语言中,递归函数需要满足以下条件:
- 基准情况(Base Case):递归函数必须有一个或多个基准情况,即不需要递归调用就能直接返回结果的情况。基准情况是递归的“出口”,防止无限递归。(递归终止条件)
- 递归情况(Recursive Case):递归函数包含对自身的调用,但每次调用时,问题的规模或复杂性应该有所减少,直到达到基准情况。(递归关系)
递归的核心思想是大事化小
2.3 递归的应用
实例一:阶乘计算
在之前的博客中,我曾经利用循环计算过阶乘,在本篇中,我将用递归来实现
int factorial(int n)
{
// 基准情况
if (n == 0) {
return 1;
}
// 递归情况
else {
return n * factorial(n - 1);
}
}
int main()
{
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}
上述代码满足的条件:
- 基准情况:
factorial(0) = 1
也是递归函数终止的条件- 递归情况:
factorial(n) = n*factorial(n-1)
递归关系
了解了这些之后,我们通过运算来了解这个函数的工作原理
我们假定
n = 5
,也就是factorial(5)
- 1.
factorial(5)
不是基准情况,所以进入递归情况,即5*factorial(5-1)
- 2.
factorial(4)
不是基准情况,进入递归情况,即4 * factorial(4-1)
- …………
- 以此类推,直到满足基准情况
1*factorial(0)
用一幅图来加深理解
通过这张图可以看出,factorial(5)
到最后就可以写成 5×4×3×2×1×1
2.4 递归的注意事项
- 递归关系必须明确,否则会导致程序逻辑错误;
- 递归终止条件必须明确,以防止无限递归;
- 递归调用的次数应在可接受的范围内,以避免栈溢出;
总结
以上就是本篇的所有内容,关于C语言中的经典递归,还有汉诺塔问题和二分查找本篇没有涉及,放在以后的内容中。