#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>



#include"add.h"

//int main()

//{

// int a = 10;

// int b = 20;

// int sum = Add(a, b);

// printf("%d\n", sum);

// return 0;

//}




//             函数递归

//什么是递归?

//  程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用

//    一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,

//    它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,

//    递归策略只需少量的程序就可描述出过程所需要的多次重复计算,大大地减少了了程序的代码量。

//    递归的主要思考方式在于:把大事化小。

//递归的两个必要条件

//1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

//2.每次递归调用之后越来越接近这个限制条件。


//什么是递归

//举个栗子

//int main()

//{

// printf("hehe\n"); //stack overflow--栈区溢出

// main();

// return 0;

//}


//栈区放的什么东西?->    局部变量  函数形参

//堆区放的什么东西?->    动态开辟的  内存  malloc calloc

//静态区放什么东西?->    全局变量   static修饰的变量



//练习1:接受一个整型值(无符号),按照顺序打印它的每一位。例如:1234,输出 1 2 3 4.


//void fun(int n)

//{

// if (n > 9)

// {

//  fun(n / 10);

// }

// printf("%d ", n % 10);

//}

//int main()

//{

// unsigned int num = 0;

// scanf("%d", &num);//123

// //递归

// fun(num);

//

// return 0;

//}



//练习2

//编写函数不允许创建临时变量,求字符串的长度。

#include<string.h>

//创建临时变量法

//int my_strlen(char* str)

//{

// int count = 0;//创建了临时变量,  这是计数器

// while (*str != '\0')

// {

//  count++;

//  str++;

// }

// return count;

//}


//递归的方法--不创建临时变量法

//把大事化小

//my_strlen("bit");

//1 + my_strlen("it");

//1 + 1 + my_strlen("t");

//1 + 1 + 1 + my_strlen("");

//1+1+1+0

//3

//int my_strlen(char* str)

//{

// if (*str != '\0')

//  return 1 + my_strlen(str + 1);

// else

//  return 0;

//}

//int main()

//{

// char arr[] = "bit";

// //int len = strlen(arr);//求字符串长度

// //printf("%d\n", len);

// //自己写一个函数去求字符串的长度。

//

// int len = my_strlen(arr);//arr是数组,数组传参,传过去的不是整个数组,而是第一个元素的地址

// printf("len = %d\n", len);

//

// return 0;

//}



//递归与迭代

//练习3:求n的阶乘。(不考虑溢出)

//循环的方式

//int Fac1(int n)

//{

// int i = 0;

// int ret = 1;

// for (i = 1; i <= n; i++)

// {

//  ret *= i;

// }

// return ret;

//}

//int main()

//{

// //求n的阶乘

// int n = 0;

// int ret = 0;

// scanf("%d", &n);

// ret = Fac1(n);//循环的方式

// printf("%d\n", ret);

// return 0;

//}


//递归的方法

/* n<=1 1

  n>1  n*Fac(n-1)           递归思维                       */  

//int Fac2(int n)

//{

// if (n <= 1)

//  return 1;

// else

//  return n * Fac2(n - 1);

//}

//int main()

//{

// //求n的阶乘

// int n = 0;

// int ret = 0;

// scanf("%d", &n);

// ret = Fac2(n);//循环的方式

// printf("%d\n", ret);

// return 0;

//}



//练习四:求第n个斐波那契数。(不考虑溢出)

//斐波那契额数列

//1 1 2 3 5 8 13 21 34 55...



//描述第n个斐波那契数

//   n<=2, 1

//   n>2,  Fib(n-1)+Fib(n-2)

//递归的方式

//int count = 0;//测试第3个斐波那契数的计算次数

//int Fib(int n)

//{

// if (n == 3)  //测试第3个斐波那契数的计算次数

// {

//  count++;

// }

// if (n <= 2)

//  return 1;

// else

//  return Fib(n - 1) + Fib(n - 2);

//}

//int main()

//{

// int n = 0;

// int ret = 0;

// scanf("%d", &n);

// //TDD-测试驱动开发

// //先去想这个函数怎么用怎么测,然后再去想这个函数怎么去写怎么去开发

// ret = Fib(n);

// printf("ret = %d\n", ret);

// printf("count = %d\n", count);

// return 0;

//}


//循环的方式

//int Fib(int n)

//{

// int a = 1;

// int b = 1;

// int c = 1;

//

// while (n > 2)

// {

//  c = a + b;

//  a = b;

//  b = c;

//  n--;

// }

// return c;

//}

//int main()

//{

// int n = 0;

// int ret = 0;

// scanf("%d", &n);

// //TDD-测试驱动开发

// //先去想这个函数怎么用怎么测,然后再去想这个函数怎么去写怎么去开发

// ret = Fib(n);

// printf("ret = %d\n", ret);

// return 0;

//}




//函数递归的几个经典题目(自主研究):

//1.汉诺塔问题

//2.青蛙跳台阶问题



//2.青蛙跳台阶问题

//n个台阶

//1次可以跳1个台阶

//1次也可以跳2个台阶


//这只青蛙要跳到第n个台阶,有多少种跳法?