学习目标:
函数以及函数递归
学习内容:
如果用两个变量写交换函数用于交换两个变量的值的话,会发现交换不了。原因是:写函数时用的两个形参x和y有独立的指针,与主函数中的实参a和b的指针不一样,所以交换数值的操作只会存在于形参中(也就是x和y之间确实交换了,但是主函数中的实参之间没有交换)。
交换两变量的值,需要通过指针来定位到变量的位置。
自定义函数练习:判断并打印素数
函数递归:函数自己调用自己。
递归的两个必要条件:
1.存在限制条件,当满足限制条件后,递归便不再继续。
2.每次递归调用后越来越接近限制条件。
举例:此函数可以把输入的数字逐个打印出来。例如输入1234,第一次可以得到123,
第二次可以得到12,
第三次输入12,得到1,
第四次输入1,不满足if条件,不再进行递归,而是打印1,
然后执行上一次循环的printf指令,打印出2,
然后再执行上上次循环的printf指令,打印出3,
最后返回到最开始的1234,打印出4。
递归练习题有:
1.不使用除形参之外的临时变量的情况下,写输出字符串个数的函数。
#include<stdio.h>
int geshu(char* str)
{
if (*str != '\0')
{
return 1 + geshu(str + 1);//**指针+1代表从原来指向第一个字符“a”,到指向第二个字符“s”,以此类推:指向第三个字符、指向第四个字符...**
}
else
return 0;
}
int main()
{
char arr[] = "asdf";
int g = geshu(arr);
printf("%d\n", g);
return 0;
}
2.求n的阶乘。
#include<stdio.h>
int jiecheng(int n)
{
if (n >= 2)
{
return n * jiecheng(n - 1);
n--;
}
return 1;
}
int main()
{
int a;
scanf("%d", &a);
int b=jiecheng(a);
printf("%d", b);
return 0;
}
3.斐波那契数列。
#include<stdio.h>
int feibo(int x)
{
if (x > 2)
{
return feibo(x - 1) + feibo(x - 2);//因为从第三个数开始,每个数字都是前两个数字之和,所以第n个数字就是第n-1个和第n-2个数字的和。
}
return 1;
}
int main()
{
int a;
scanf("%d", &a);
int b=feibo(a);
printf("%d", b);
return 0;
}
4.汉诺塔问题。
汉诺塔(Tower of Hanoi),有三根柱子,在一根柱子上从下往上按照大小顺序摞着n片圆盘。现在要把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。现在计算放n个圆盘,需要移动多少次。
由于数学不好,我没看出来移动次数与圆盘数的规律,所以直接找了个公式:f(n)=(2^n)-1。
第一次写的没用递归,忘记了…
#include<stdio.h>
int shu(int n)
{
int a = 1;
while (n >= 1)
{
a = a * 2;
n--;
}
return a - 1;
}
int main()
{
int x ;
scanf("%d", &x);
int y = shu(x);
printf("%d", y);
return 0;
}
然后第二次用递归。当时在想返回值应该怎么写,后来想到f(n)=2n-1 , f(n+1)=2 n+1-1=2x(2n-1)+1=2xf(n)+1 合理
#include<stdio.h>
int ci(int n)
{
if (n == 0)
return 0;
else
return 2 * ci(n - 1) + 1;
}
int main()
{
int x;
scanf("%d", &x);
int y = ci(x);
printf("%d", y);
return 0;
}
5.蜗牛爬台阶问题。(对比斐波那契数列题,根据if判断条件不同,看情况添加/不添加n–)
蜗牛每次走1个或者2个台阶,计算走n个台阶有多少种走法。
以走4个台阶为例,走到4之前只有两种情况:
(1)在2处,下一步必须走2才能到4;
(2)在3处,下一步必须走1才能到4;
所以到4处的方法有到2处和到3处的方法之和。
#include<stdio.h>
int cishu(int n)
{
if (n >= 2)//如果是n>某个数,那么需要n--,来让函数收敛;如果是n<某个数,那就不需要n--,因为它最终会收敛。
{
return cishu(n - 1) + cishu(n - 2);
n--;
}
return 1;
}
int main()
{
int a;
int b;
scanf("%d", &b);
a = cishu(b);
printf("%d", a);
return 0;
}