💬欢迎交流:在学习过程中如果你有任何疑问或想法,欢迎在评论区留言,我们可以共同探讨学习的内容。你的支持是我持续创作的动力! 👍点赞、收藏与推荐:如果你觉得这篇文章对你有所帮助,请不要忘记点赞、收藏,并分享给更多的小伙伴!你们的鼓励是我不断进步的源泉! 🚀推广给更多人:如果你认为这篇文章对你有帮助,欢迎分享给更多对编程感兴趣的朋友,让我们一起进步,共同提升!
编程中,形参是函数定义时的占位符,实参是调用时传递的具体值。递归通过函数自我调用解决问题,理解它们的关系有助于写出高效、健壮的代码。 本文我们主要来介绍形参 实参 和递归
但是这很可能类型不匹配
例如:
#include <stdio.h>
void cheer(int i)
{
printf("cheer %d\n", i );
}
int main()
{
cheer(2.4);
return 0;
}
输出结果:
cheer 2
void swap(int a, int b)//形式参数 ;
int main()
{
int a = 5;
int b = 6;
swap(a,b);//实际参数
printf("a=%d\n b=%d\n", a, b);
return 0;
}
C语言在调用函数时 永远只能传值给函数
接下来 我们详细来看
首先我们来举个例子,假设我们需要求10到20的和:
#include <stdio.h>
void sum()
{
int num1 = 10;
int num2 = 20;
int sum = num1 + num2;
printf("%d\n",sum);
}
int main(){
sum();
return 0;
}
我们可以很轻松地得到输出结果:
30
可是如果我们改一下题目,要求20到30的和,或者30到40的和,就会特别麻烦,因为要一直修改
num1
和num2
的值。
这个问题的本质原因在于,代码中的加法操作涉及的数字是固定的。在实际编程中,我们希望代码能够灵活处理不同的输入值。为了解决这个问题,我们可以将num1
和num2
定义为函数的参数。
void sum(int num1, int num2) //这里仅定义,未赋值
那么我们应该如何调用这个函数呢?这时就需要在调用时传入具体的数值:
#include <stdio.h>
void sum(int num1, int num2)
{
int sum = num1 + num2;
printf("%d\n",sum);
}
int main(){
sum(10, 20); //在这里传入实际的值
return 0;
}
这样,我们就可以更灵活地得到输出结果:
30
void sum(int num1, int num2) //这里只是定义了参数
在调用函数时,我们根据需要传入不同的实际参数:
函数名(参数1, 参数2, ....)
虽然num1
和num2
在函数中都被称为“参数”,但是它们实际上有不同的作用与含义:
int num1, int num2
。sum(10, 20)
中的10
和20
。形参与实参必须一一对应,即在函数定义时声明的参数和调用时传入的参数数量、类型需一致。
通过这种方式,函数能够灵活地处理不同的输入数据,从而提高代码的通用性和复用性。
在C语言中,函数不仅可以执行操作,还可以返回结果。带有返回值的函数通过return语句返回一个值给调用者。返回值可以是任何有效的数据类型,如int、float、char等。函数的返回类型需要在函数定义时声明。
void sum(int num1,int num2)
{
int sum = num1 + num2;
printf("%d\n",sum);
}
其实上面这篇代码还有一点点缺陷 我们来继续往下看
int main(){
sum(10,20);
return 0;
}
我们其实可以看到 上面并没有把最终的结果交给调用者 而是说直接打印在了控制台上,调用者拿不到最终结果。如果我们遇到复杂的题目时,就不可以这么写了,这时我们就需要带返回值了。
返回值类型 函数名(形参1,形参2...)
{
函数体;
return返回值;//返回值要和上面的类型一致
}
调用方式:
1. 变量 = 函数名(实参)
2. printf("占位符",函数名(实参))
题目:计算小明考试成绩基础分90 附加题得分5分 小红基础分85 附加题得分8分
#include <stdio.h>
int sum(int base, int additional) // 形参
{
int sum = base + additional; // 局部变量
return sum; // 返回函数调用者
}
int main()
{
int score1 = sum(90, 5); // 小明的总成绩
int score2 = sum(85, 8); // 小红的总成绩
if (score1 > score2)
{
printf("小明的成绩优于小红\n");
} else {
printf("小红的成绩优于小明\n");
}
return 0;
}
输出结果:
小明的成绩优于小红
带返回值的函数:返回类型在函数定义时明确,返回结果通过return语句传递给调用者。 return语句:终止函数并返回结果,确保函数能够将计算结果传递给外部。 数据类型匹配:返回值的类型与函数声明的返回类型必须一致。 灵活性:带返回值的函数提高了代码的灵活性和复用性,且可用于处理更复杂的任务。
递归(Recursion)是指函数在其定义中直接或间接地调用自身。在C语言中,递归是一种强大的编程技巧,通常用于解决可以分解为类似子问题的任务。递归的关键是要有一个终止条件,防止函数无限调用自己,导致栈溢出。
递归函数通常包含两个主要部分:
递归函数通常遵循以下结构:
返回类型 函数名(参数)
{
// 基本情况:如果满足终止条件,返回一个值,停止递归
if (满足某个条件)
{
return 基本情况的结果;
}
// 递归步骤:调用自身,并传递修改后的参数
else
{
return 函数名(修改后的参数); // 递归调用
}
}
阶乘是一个经典的递归问题,定义如下:
n! = n * (n-1) * (n-2) * ... * 1
递归形式:
n! = n * (n-1)!
1! = 1 (基本情况)
代码示例:计算阶乘
#include <stdio.h>
// 递归函数计算阶乘
int factorial(int n)
{
// 基本情况:当n等于1时,返回1
if (n == 1)
{
return 1;
}
// 递归步骤:n * (n-1)!
else
{
return n * factorial(n - 1);
}
}
int main()
{
int num = 5;
int result = factorial(num); // 调用递归函数
printf("%d! = %d\n", num, result); // 输出结果
return 0;
}
输出结果:
5! = 120
以factorial(5)
为例,递归调用过程如下:
factorial(5)
调用 factorial(4)
,然后返回 5 * factorial(4)
factorial(4)
调用 factorial(3)
,然后返回 4 * factorial(3)
factorial(3)
调用 factorial(2)
,然后返回 3 * factorial(2)
factorial(2)
调用 factorial(1)
,然后返回 2 * factorial(1)
factorial(1)
返回 1
(基本情况)递归开始“展开”,依次返回每一层的计算结果,最终返回 120
。
递归的优点
递归的缺点:
尾递归是一种优化递归方式,要求递归调用是函数的最后一步操作。尾递归可以被编译器优化为迭代,从而避免不必要的栈帧开销。
例如,尾递归形式的阶乘计算可以这样实现:
#include <stdio.h>
// 尾递归计算阶乘
int factorial_tail_recursive(int n, int accumulator)
{
if (n == 1)
{
return accumulator;
}
else
{
return factorial_tail_recursive(n - 1, n * accumulator);
}
}
int main()
{
int num = 5;
int result = factorial_tail_recursive(num, 1); // 从1开始递归
printf("%d! = %d\n", num, result); // 输出结果
return 0;
}
在这种实现中,accumulator
参数用于保存中间结果,从而避免递归调用时每次都重新计算。
递归常见应用
在 C 语言中,形参、实参和递归是重要的概念,理解它们能够帮助我们更高效地编写程序。
通过合理使用形参、实参和递归,可以实现灵活、可复用的程序设计,提高代码的效率与可维护性。
那么我想以上这就是【C 语言篇】形参实参密钥与递归魔法之门:C 语言编程中开启算法奥秘的奇妙旅程的内容了,通过对形参、实参和递归的学习,使我们可以在编程中更好的解决问题。❤️