C_study - 第8天

日期: 星期二, 2024年3月18日

时间: 下午10:10

递归

递归是一种编程技术,其中一个函数直接或间接地调用自身。它是一种强大的工具,尤其是在处理那些可以分解为更小、相似问题的任务时。递归函数的两个主要特点是:

  1. 基本情况(Base Case):确保递归有一个结束点,以防无限循环。
  2. 递归步骤(Recursive Step):调用自身来解决子问题。

递归的经典例子包括计算阶乘、遍历树结构等。但需要注意的是,不当使用递归可能导致栈溢出错误,因为每个函数调用都会在栈上占用一定的空间。因此,合理控制递归深度是非常重要的。

示例分析

考虑以下递归示例,打印一个整数的每一位:

void print(unsigned int n) {
    if (n > 9) {
        print(n / 10);
    }
    printf("%d\n", n % 10);
}

这段代码演示了递归的基本结构:有一个明确的递归结束条件(当n小于等于9时),以及一个递归步骤(继续处理n的其他位)。

函数调用

在C语言中,函数是组织代码的基本单元。函数可以嵌套调用,但不能嵌套定义。一个函数的结果可以作为另一个函数的参数,这种操作被称为链式调用。

传值调用与传址调用
  • 传值调用(Call by Value):函数接收的是参数值的副本。在函数体内部对参数的修改不会影响原始数据。
  • 传址调用(Call by Reference):函数接收的是参数的地址。这意味着在函数内部可以直接修改原始数据。
示例:递增一个变量
void Add(int *p) {
    (*p)++;
}

这个函数演示了传址调用的使用,其中函数接收一个整数的地址,并通过解引用来递增该整数的值。

内存管理

在C语言中,内存被划分为几个区域,主要包括栈区、堆区和静态区。

  • 栈区:自动管理,存储函数的局部变量和函数参数。栈空间有限,过深的递归或过大的局部变量可能导致栈溢出。
  • 堆区:通过malloc等函数动态分配内存,使用灵活,但需要手动管理内存的分配和释放,避免内存泄漏。
  • 静态区:存储全局变量和静态变量,程序结束时由系统释放。

错误和建议

  1. 无限递归:示例中的main函数递归调用自身而没有终止条件,这会导致栈溢出。递归函数必须有一个明确的退出条件。

  2. 函数声明:函数应该在使用前声明或定义。尽管在某些情况下,如函数定义在使用之前,可以不显式声明,但最佳实践是在头文件中声明函数,然后在源文件中实现它们。

  3. 不完整的代码片段:一些代码示例没有完整展示如何正确使用函数,如binary_search函数调用未给出完整定义和示例中sz未定义。

代码改进与补充

对于原始代码中的不足,我们可以进行以下改进:

  • 确保所有函数在使用前都已声明或定义。
  • 避免无限递归,确保有清晰的递归退出条件。
  • 在使用动态内存分配时,确保合理分配并及时释放内存,避免内存泄漏。

二分查找算法

二分查找是一种在有序数组中查找特定元素的高效算法。它通过比较数组的中间元素与目标值来逐步缩小搜索范围,直到找到目标值或确定目标值不存在。

示例:实现二分查找
int binary_search(int arr[], int key, int size) {
    int left = 0;
    int right = size - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == key) {
            return mid;
        } else if (arr[mid] < key) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}
  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小毓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值