C语言中的函数,实参,形参,递归

1:什么是函数

2:定义带形式参数的函数和带实际参数的函数

3:递归

---------------------------------------------------------------------------------------------------------------------------------

1:在 C 语言中,函数是一个可重复使用的代码块,用于执行特定任务或计算。它可以接收输入(称为参数),执行代码,并根据需要返回一个值。函数有助于将程序分解为更小、易于管理的部分,促进代码的复用和组织。

函数的特点:

  1. 封装性:函数将特定的功能或逻辑封装在一个独立的代码块中,外界只需调用函数,而无需关心内部实现。

  2. 参数传递:可以通过参数将数据传递给函数,函数根据传入的参数执行不同的操作。

  3. 返回值:函数可以通过 return 语句将结果返回给调用者。

  4. 代码复用:定义一次函数,可以在多个地方调用,避免重复代码。

函数的组成:

  • 函数声明(或函数原型):提供给编译器关于函数的返回类型、名称及参数类型的信息。
  • 函数定义:指定函数的实际实现,包括要执行的代码。
  • 函数调用:执行函数时通过名称调用函数,并传递必要的参数。

 

----------------------------

2:在 C 语言中,定义带形式参数(也称为形参)的函数时,函数的定义包含参数的类型和名称。这些形参在函数定义中使用,用于接收调用函数时传递的实际参数(也称为实参)。形参相当于函数的占位符,实参会在函数调用时赋值给形参。 

定义带形式参数的函数的基本格式:

返回类型 函数名(参数类型1 形参名1, 参数类型2 形参名2, ...) {
    // 函数体
    return 返回值;  // 如果有返回值
}

关键点:

  1. 形参:在函数定义的参数列表中,指定参数类型和名称。形参仅在函数内部有效,函数外部无法访问。
  2. 参数传递:函数调用时,将实参传递给形参,形参接受对应的数据并用于函数内部操作。

示例:带形式参数的函数

#include <stdio.h>

// 函数定义:接收两个整数作为参数,并返回它们的和
int add(int a, int b) {
    return a + b;  // 使用形参 a 和 b
}

int main() {
    int x = 5;
    int y = 3;
    
    // 函数调用,将实参 x 和 y 传递给形参 a 和 b
    int result = add(x, y);
    
    printf("%d + %d = %d\n", x, y, result);  // 输出结果
    return 0;
}
解释:
  1. 形参abadd 函数的形式参数,它们在函数内部用于计算。
  2. 实参:在 main 函数中,xy 是实际参数,调用 add(x, y) 时,x 的值传递给 ay 的值传递给 b

示例:带多个形式参数的函数

#include <stdio.h>

// 函数定义:计算矩形的面积
int calculateArea(int length, int width) {
    return length * width;
}

int main() {
    int l = 10;
    int w = 5;

    // 函数调用,将实参 l 和 w 传递给形参 length 和 width
    int area = calculateArea(l, w);

    printf("The area of the rectangle is: %d\n", area);
    return 0;
}
解释:
  1. 形参lengthwidth 是函数 calculateArea 的形参。
  2. 实参:在 main 中,lw 是实参,调用 calculateArea(l, w) 时,l 传递给 lengthw 传递给 width,并计算矩形的面积。

------------------------------------ 

递归(Recursion)是指在程序或函数中调用自身的一种编程技术。递归是一种解决问题的方法,通过将问题分解为规模更小的子问题,直到遇到最小的子问题(称为基准情况),然后再逐步解决这些子问题。

在 C 语言中,递归函数是指直接或间接调用自己的函数。递归函数必须有一个基准条件(base case)来防止无限递归,否则程序将导致栈溢出(Stack Overflow)。

递归的基本结构:

递归函数一般包含两部分:

  1. 基准条件(Base case):递归终止条件,防止函数无限调用自身。
  2. 递归条件(Recursive case):函数在适当的情况下调用自身。

递归的基本形式:

返回类型 函数名(参数类型 参数名, ...) {
    if (基准条件) {
        // 结束递归,返回结果
    } else {
        // 递归调用函数自身
    }
}

 

递归示例:计算阶乘

阶乘是递归的经典例子。一个整数 n 的阶乘 n! 定义为:

  • n = 0n = 1 时,n! = 1(基准条件)。
  • n > 1 时,n! = n * (n - 1)!(递归条件)。
#include <stdio.h>

// 递归函数:计算 n 的阶乘
int factorial(int n) {
    if (n == 0 || n == 1) {  // 基准条件
        return 1;
    } else {
        return n * factorial(n - 1);  // 递归调用
    }
}

int main() {
    int number = 5;
    printf("%d! = %d\n", number, factorial(number));  // 输出 5! = 120
    return 0;
}

 

解释:
  • 基准条件:当 n 等于 01 时,返回 1,表示递归终止。
  • 递归条件:当 n > 1 时,函数调用自身,计算 n * (n - 1)!

例如,计算 factorial(5) 时:

  • factorial(5) 会调用 factorial(4)
  • factorial(4) 调用 factorial(3)
  • 依次类推,直到 factorial(1) 返回 1,然后逐步返回计算结果,最终得出 5! = 120

递归示例:斐波那契数列

斐波那契数列也是递归的一个常见例子。斐波那契数列的定义是:

  • F(0) = 0F(1) = 1(基准条件)。
  • 对于 n >= 2F(n) = F(n-1) + F(n-2)(递归条件)。
斐波那契数列的递归实现:
#include <stdio.h>

// 递归函数:计算斐波那契数列的第 n 项
int fibonacci(int n) {
    if (n == 0) {  // 基准条件
        return 0;
    } else if (n == 1) {  // 基准条件
        return 1;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);  // 递归调用
    }
}

int main() {
    int number = 10;
    printf("Fibonacci(%d) = %d\n", number, fibonacci(number));  // 输出第 10 项的斐波那契数
    return 0;
}

 

解释:
  • 基准条件F(0) = 0F(1) = 1,表示递归的终止条件。
  • 递归条件:对于 n >= 2,返回 F(n-1) + F(n-2),即前两项之和。

例如,fibonacci(5) 的计算过程如下:

  • fibonacci(5) = fibonacci(4) + fibonacci(3)
  • fibonacci(4) = fibonacci(3) + fibonacci(2)
  • 依次类推,直到递归调用到基准条件 fibonacci(0)fibonacci(1) 返回 0 和 1 为止。

递归的优缺点:

优点:
  1. 简洁易懂:对于一些问题,递归可以将问题的复杂逻辑简化为更直观、易于理解的代码。
  2. 自然分解:递归非常适合解决那些可以被分解为相同类型子问题的问题,例如树结构、图遍历等。
缺点:
  1. 性能问题:递归调用会占用更多的栈空间,对于较深的递归调用,可能会导致栈溢出。此外,每次递归调用都涉及函数的创建和销毁,这样会增加开销。
  2. 效率低:有些递归问题(如斐波那契数列)存在大量重复计算,递归的效率不高,可能需要优化(如使用记忆化技术或改写为迭代形式)。

递归与迭代的比较:

递归和迭代是两种解决问题的不同方法:

  • 递归:通过函数调用自身解决问题,依赖于函数的栈结构,通常代码简洁,但效率可能较低。
  • 迭代:通过循环结构解决问题,占用的栈空间较少,效率通常更高。
斐波那契数列的迭代实现:
#include <stdio.h>

// 迭代方法:计算斐波那契数列的第 n 项
int fibonacci_iterative(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    int a = 0, b = 1, result;
    for (int i = 2; i <= n; i++) {
        result = a + b;
        a = b;
        b = result;
    }
    return result;
}

int main() {
    int number = 10;
    printf("Fibonacci(%d) = %d\n", number, fibonacci_iterative(number));  // 输出第 10 项的斐波那契数
    return 0;
}

 

总结:

  • 递归 是解决问题的一种重要技术,通过函数调用自身来解决问题。
  • 递归函数必须有一个基准条件,防止无限递归。
  • 尽管递归在某些场景下代码简洁优美,但在性能和效率上可能不如迭代,特别是在处理大规模问题时需要谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值