C语言 递归函数计算(函数)
递归和尾递归 (图解+实例)

1 如果 n=0,n=1f(n)=nf(n) 如果 n>1图1:以递归的方式计算4的阶乘上图(1)展示了利用递归计算4!的过程。
它也说明了递归过程中的两个基本阶段:递推和回归。
在递推阶段,每一个递归调用通过进一步调用自己来记住这次递归过程。
当其中有调用满足终止条件时,递推结束。
比如,在计算n!时,终止条件是当n=1和n=0,此时函数只需简单的返回1即可。
每一个递归函数都必须拥有至少一个终止条件;否则递推阶段永远不会结束了。
一旦递推阶段结束,处理过程就进入回归阶段,在这之前的函数调用以逆序的方式回归,直到最初调用的函数为止,此时递归过程结束。
以递归的方式计算n的阶乘的函数实现:C函数fact的工作方式如下:它接受一个整数n作为参数,如果n小于0,该函数直接返回0,这代表一个错误。
如果n等于0或1,该函数返回1,这是因为0!和1!都等于1,以上是终止递归的条件。
否则,函数返回n-1的阶乘的n倍。
而n-1的阶乘又会以递归的方式再次调用fact来计算,如此继续。
代码实例(1):fact.c1/*fact.c*/2#include "fact.h"3int fact(int n){4if (n<0)5return0;6else if(n==0)7return1;8else if(n==1)9return1;10else11return n*f(n-1);12}为理解递归究竟是如何工作的,有必要先看看C语言中函数的执行方式。
我们先来看看C程序在内存中的组织方式(见图2-a)。
基本上,一个可执行程序由4个区域组成:代码段、静态数据区、堆与栈。
代码段包含程序运行时所执行的机器指令。
静态数据区包含在程序生命周期内一直持久的数据,比如全局变量和静态局部变量。
堆包含程序运行时动态分配的存储空间,比如malloc分配的内存。
栈包含函数调用的信息。
当C中调用了一个函数时,栈中会分配一块空间来保存与这个调用相关的信息。
【C语言】用递归法解决倒水问题(源码)

}
}
}
if(Before[2]!=0)
{
if(Before[0]<Max[0])
{
memcpy(Temp,Dump(Before,2,0),sizeof(Temp));
if(Temp[0]==Aim||Temp[1]==Aim||Temp[2]==Aim)
else if(StopFlag<Dep)
{
sprintf(temp,"%s-CA",step);
sprintf(str,"%s",Recursive(Temp,StopFlag+1,temp));
if(str[0]!=0)return str;
}
}
if(Before[1]<Max[1])
{
memcpy(Temp,Dump(Before,2,1),sizeof(Temp));
if(Temp[0]==Aim||Temp[1]==Aim||Temp[2]==Aim)
{
sprintf(str,"\r\n倒法是:%s-CB\r\n 一共:%d步\r\n结果是:[%d,%d,%d]\r\n",step,StopFlag,Temp[0],Temp[1],Temp[2]);
else if(StopFlag<Dep)
{
sprintf(temp,"%s-AC",step);
sprintf(str,"%s",Recursive(Temp,StopFlag+1,temp));
if(str[0]!=0)return str;
c语言编写函数,使用递归的方法求1+2+3+……+n的值

c语言编写函数,使用递归的方法求1+2+3+……+n的值以下是使用递归方法求解1 + 2 + 3 + ... + n的C语言函数:```c#include <stdio.h>// 递归函数int sumUpToN(int n) {// 基本情况:当n 等于0 时,返回0if (n == 0) {return 0;}// 递归情况:返回n 加上前n-1 项的和else {return n + sumUpToN(n - 1);}}int main() {int n;// 获取用户输入printf("Enter a positive integer n: ");scanf("%d", &n);// 检查输入是否为正整数if (n < 1) {printf("Please enter a positive integer.\n");} else {// 调用递归函数并输出结果int result = sumUpToN(n);printf("Sum of 1 to %d is: %d\n", n, result);}return 0;}```这个程序包含一个递归函数`sumUpToN`,该函数接受一个正整数`n` 作为参数,计算1 + 2 + 3 + ... + n的和。
递归函数的基本情况是当`n` 等于0 时返回0,递归情况是返回`n` 加上前`n-1` 项的和。
在`main` 函数中,用户输入一个正整数`n`,然后调用递归函数并输出结果。
程序会检查输入是否为正整数,并在必要时提供错误消息。
C语言第七讲 函数(2)

21
一、变量的存储空间分配概念
变量定义位置 变量的作用域 空间 (变量的使用范围)
变量的存储类别变量的生存期 时间
26
局部变量
二、变量的作用域——
局部变量(local variable)与全局变量(global variable)
例
void swap( ) { int t,x,y; t=x;x=y;y=t; } main() { int x=3,y=5; printf("x=%d,y=%d\n",x,y); swap( ); printf("x=%d,y=%d\n",x,y); }
斐波那契数列的递归方法实现。计算并输出斐波 那契数列的前7个数据。
1 当n =0, 1时
fib(n) =
fib(n-1)+ fib(n-2) 当n > 1时
int fib(int n) { if(n==0||n==1) return 1; else return fib(n-1)+fib(n-2); }
10
void main() { int n; for(n=11;n<=99;n++) if( absoluteprime(n) ) printf("%d\t",n); } /*判断一个数是否为绝对素数*/ int absoluteprime (int n) /*函数定义*/ { if(prime(n)==0) return 0; else if(prime(invert(n))==1) return 1; else return 0; }
c语言return的用法

c语言return的用法C语言中的return语句是非常重要的一个语句,它可以用来结束函数的执行并返回一个值。
在本文中,我们将详细介绍return语句的用法及其注意事项。
1. return语句的基本用法return语句的基本语法如下:return [expression];其中,expression是可选的,表示要返回的值。
如果省略expression,则函数返回void类型。
下面是一个简单的例子:int add(int a, int b){return a + b;}在这个例子中,add函数接受两个整数参数a和b,并返回它们的和。
当函数执行到return语句时,它会返回a + b的值。
2. return语句的注意事项在使用return语句时,需要注意以下几点:2.1. return语句可以出现在函数的任何位置,但是它必须是函数的最后一条语句。
2.2. 如果函数返回值的类型是void,则可以省略return语句。
2.3. 如果函数返回值的类型不是void,则必须在函数中包含至少一个return语句。
2.4. 如果函数返回值的类型不是void,并且函数中没有return语句,则会发生未定义的行为。
2.5. 如果函数返回值的类型不是void,并且函数中有多个return 语句,则只有第一个被执行的return语句会返回值。
下面是一个例子,演示了return语句的注意事项:int max(int a, int b){if (a > b){return a;}else{return b;}}在这个例子中,max函数接受两个整数参数a和b,并返回它们中的最大值。
如果a大于b,则返回a,否则返回b。
注意,这个函数中有两个return语句,但是只有一个会被执行。
3. return语句的高级用法除了基本用法之外,return语句还有一些高级用法,可以让我们更加灵活地使用它。
3.1. 在循环中使用return语句在循环中使用return语句可以提前结束循环并返回一个值。
递归求阶乘和

递归求阶乘和在数学中,阶乘和指的是阶乘的总和,即n!(n≥1)的总和。
它也称为阶乘序列的和。
此外,它也是数学表达式的一部分。
阶乘和的求解在许多数学领域都有重要的应用,如数论、概率论等。
阶乘和的求解可以用递归的方法实现。
递归的思想是,根据已知条件,逐步求解每一项,最后求出阶乘和。
在实现递归程序时,一般采用递归函数的形式,即定义一个函数,用它来求解每一项。
例如,要求解n!(n≥1)的阶乘和,可以定义如下函数,f(n)=f(n-1)+n!(n≥1)可以看出,这个函数的输入是n,而输出也是f(n),这实现了递归的思想。
同时,也可以看出,函数的定义满足终止条件f(1)=1,并且需要实现有效的循环,以解决阶乘和。
接下来,我们用c语言实现阶乘和的递归求解程序。
首先定义函数:long long facsum(long n){if(n==1)return 1;elsereturn facsum(n-1)+n!;}接着,实现循环:long long sum=0;for(long i=1;i<n;i++)sum+=facsum(i);最后,返回总和:return sum;上述的程序实现了求解n!(n≥1)的阶乘和的递归算法。
由于递归算法具有结构清晰,运算精确,代码量小,编程难度大等优点,它具有很好的适用性,在许多数学计算中都得到了广泛的应用。
阶乘和的求解只是递归算法的一个例子,可以有更多的应用。
比如,运用递归思想可以实现许多复杂函数的求解,比如,三角函数、特殊函数等;另外,递归算法还可以用于搜索问题,如求解最短路径问题;另外,递归算法还可以用于求解动态规划问题,如求解背包问题。
递归求解阶乘和的重要性不言而喻,它可以帮助我们快速求解阶乘和,从而更好地使用数学表达式,研究复杂的数学问题。
总之,递归求解阶乘和是一种高效的算法,为我们提供了很大的帮助。
c语言函数自我调用
c语言函数自我调用C语言函数自我调用自我调用是指函数在执行过程中调用自身的行为。
在C语言中,函数自我调用是一种常见的编程技巧,可以用来解决一些需要重复执行的问题,如递归算法等。
本文将详细介绍C语言函数自我调用的原理、应用场景以及注意事项。
一、函数自我调用的原理函数自我调用的原理是通过在函数体内部使用函数名来调用函数本身。
当函数被调用时,会创建一个新的函数执行上下文,并将参数传递给新的函数。
在函数内部,可以通过条件判断语句来决定是否继续调用函数自身,从而实现重复执行的效果。
二、函数自我调用的应用场景1. 递归算法:递归是指函数调用自身的过程。
递归算法常用于解决具有递归结构的问题,如求解阶乘、斐波那契数列等。
通过函数自我调用,可以简化递归算法的实现,使代码更加简洁和可读。
例如,以下是一个计算阶乘的递归函数:```cint factorial(int n) {if (n == 0 || n == 1) {return 1;} else {return n * factorial(n - 1);}}```2. 链表操作:链表是一种常见的数据结构,通过指针将一组节点按顺序连接起来。
在对链表进行操作时,函数自我调用可以用来遍历链表、查找节点等。
例如,以下是一个递归函数,用于计算链表的长度:```cint getLength(Node* head) {if (head == NULL) {return 0;} else {return 1 + getLength(head->next);}}```3. 树的遍历:树是一种重要的数据结构,常用于表示层次结构的数据。
在对树进行遍历时,函数自我调用可以用来实现先序遍历、中序遍历、后序遍历等。
例如,以下是一个递归函数,用于实现树的先序遍历:```cvoid preOrderTraversal(TreeNode* root) {if (root != NULL) {printf("%d ", root->value);preOrderTraversal(root->left);preOrderTraversal(root->right);}}```三、函数自我调用的注意事项1. 递归终止条件:递归函数必须包含一个终止条件,否则会导致无限递归,最终导致栈溢出。
c语言递归判断回文数
c语言递归判断回文数C语言是一种广泛应用于计算机编程的高级编程语言,其灵活性和强大的功能使其成为开发人员的首选。
在C语言中,递归是一种常见的编程技巧,可以用来解决各种问题。
本文将以C语言递归判断回文数为主题,介绍如何使用递归算法来判断一个数是否是回文数。
我们需要明确回文数的定义。
回文数是指正着读和倒着读都一样的数,例如121、12321等。
判断一个数是否是回文数的方法有很多种,其中一种简单而有效的方法是使用递归算法。
在C语言中,递归是一种函数调用自身的方法。
通过将问题分解为更小的子问题,递归能够简化复杂的计算过程。
对于判断回文数来说,我们可以将问题分解为判断首尾两个数字是否相等,并将剩余的数字作为子问题进行递归判断。
下面是使用递归算法来判断一个数是否是回文数的C语言代码:```c#include <stdio.h>int isPalindrome(int num, int temp) {// 递归的终止条件if (num == 0) {return temp;}// 提取最后一位数字temp = temp * 10 + num % 10;// 递归调用,判断剩余的数字是否是回文数return isPalindrome(num / 10, temp);}int main() {int num;printf("请输入一个整数:");scanf("%d", &num);int result = isPalindrome(num, 0);if (result == num) {printf("%d是回文数\n", num);} else {printf("%d不是回文数\n", num);}return 0;}```在上面的代码中,我们定义了一个名为`isPalindrome`的递归函数,该函数接受两个参数:`num`和`temp`。
c语言函数的嵌套和递归调用方法的实验小结
C语言函数的嵌套和递归调用方法的实验小结一、引言在C语言程序设计中,函数的嵌套和递归调用是两种常用的方法,它们在解决问题和实现特定功能时具有重要作用。
本文将结合实验结果,对C语言函数的嵌套和递归调用方法进行总结和分析,旨在加深对这两种方法的理解和应用。
二、函数的嵌套1. 概念与特点函数的嵌套是指在一个函数内部调用另一个函数。
当函数A中调用了函数B,函数B又调用了函数C,函数C又调用了函数D时,就形成了函数的嵌套调用。
函数的嵌套具有以下特点:(1)提高了程序的模块化和可读性,减少了代码的复杂度。
(2)可以在不同的函数之间传递参数,实现更灵活的功能组合。
(3)需要注意函数的声明顺序和作用域,避免出现未声明的函数引用错误。
2. 实验验证为了验证函数的嵌套调用,在实验中我们设计了一个简单的例子:编写两个函数,分别实现计算阶乘和计算组合数的功能,然后在主函数中进行嵌套调用,计算组合数的值。
实验结果表明,函数的嵌套调用可以实现相互依赖的功能模块,在程序设计中具有一定的灵活性和适用性。
三、递归调用1. 概念与特点递归调用是指一个函数在执行过程中调用了自身,从而形成了一种函数调用的循环结构。
通过递归调用,可以使函数不断重复执行,直到满足特定的条件才停止。
递归调用具有以下特点:(1)简化了程序的结构,使代码更加清晰和易于理解。
(2)能够处理一些需要多级嵌套的问题,极大地提高了代码的复用性和灵活性。
(3)需要设置递归调用的终止条件,避免形成无限循环,导致程序崩溃。
2. 实验验证为了验证递归调用的功能和特点,我们设计了一个典型的递归程序:计算斐波那契数列的前n项值。
实验结果表明,递归调用在实现该问题时具有简洁、高效的特点,使得代码易于阅读和理解,优雅地解决了该问题。
四、两种方法的比较1. 灵活性与适用性函数的嵌套调用主要适用于需要实现不同功能模块之间的交互和依赖关系的情况,具有较强的灵活性和可扩展性。
递归调用主要适用于解决问题具有明显的递归结构或需要多级嵌套的情况,具有较好的适用性和简洁性。
C语言与程序设计ppt-第12章递归
第12章 递 归
华中科技大学计算机学院 卢萍
华中科技大学计算机学院C语言课
2021/4/25
程组
1
本章讲授内容
递归(recursion)是一项非常重要的编 程技巧,可以使程序变得简洁和清晰,是 许多复杂算法的基础。本章介绍 递归、递归函数的概念; 递归的执行过程; 典型问题的递归函数设计; 分治法与快速排序; 回溯法; 递归在动态规划等算法中的应用。
12
【例12.3】 设计一个求解汉诺塔问题的算法。
这是一个典型的用递归方法求解的问题。要移动n个 盘子,可先考虑如何移动n 1个盘子。分解为以下3 个步骤:
(1)把A上的n-1个盘子借助C移到B。 (2)把A上剩下的盘子(即最大的那个)移到C。 (3)把B上的n-1个盘子借助A移到C。 其中,第(1)步和第(3)步又可用同样的3步继
2021/4/25
华中科技大学计算机学院C语言课程组
2
12.1 递归概述
递归是一种函数在其定义中直接或间接调用 自己的编程技巧。递归策略只需少量代码就 可描述出解题过程所需要的多次重复计算, 十分简单且易于理解。
递归调用:函数直接调用自己或通过另一函 数间接调用自己的函数调用方式
递归函数:在函数定义中含有递归调用的函 数
续分解,依次分解下去,盘子数目n每次减少1,直 至n为1结束。这显然是一个递归过程,递归结束条 件是n为1。
2021/4/25
华中科技大学计算机学院C语言课程组
13
函数move(n,a,b,c)
为了更清楚地描述算法,可以定义一个函数 move(n,a,b,c)。该函数的功能是:将n个盘 子从木桩a上借助木桩b移动到木桩c上。算法 的第(1)步和第(3)步的实现都是递归调 用,分别为move(n-1,a,c,b)和move(n1,b,a,c)。