您的位置:首页 > 其它

函数和递归

2020-12-23 22:42 1351 查看

函数:分为库函数和自定义函数
自定义函数和库函数一样,有函数名、返回值类型和函数参数;但是不一样的是这些都是我们自己来设计。

函数的调用:
传值调用:
函数的形参和实参分别占用不同的内存块,对形参的修改不会影响实参
传址调用:
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式
这种传参方式可以让函数和函数外部的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

void Swap2(int pa, int pb)
{
int tmp = 0;
tmp = pa;
pa = pb;
pb = tmp;
}

int main()
{
int a = 10;
int b = 20;
printf("a=%d b=%d\n", a, b);
Swap2(&a, &b);
printf("a=%d b=%d", a,b);
return 0;

}

//int main()
//{
// int a = 10;
// int pa = &a;
// pa = 20;
// printf("%d\n", a);
// return 0;
//}

//void Swap(int x, int y)
//{
// int tmp = 0;
// tmp = x;
// x = y;
// y = tmp;
//}
//
//int main()
//{
// int a = 10;
// int b = 20;
// /int tmp = 0;/
// printf("a=%d b=%d\n", a, b);
// Swap(a, b);
// /tmp = a;
// a = b;
// b = tmp;/
// printf("a=%d b=%d\n", a, b);
// return 0;
//}
练习:
1、写一个函数可以判断一个数是不是素数。
2、写一个函数判断一年是不是闰年。
3、写一个函数,实现一个整形有序数组的二分查找
4、写一个函数,每调用一次这个函数,就会将num的值增加1。

函数的递归:
程序调用自身的编程技巧称为递归,递归作为一种算法在程序设计语言中广泛应用,一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题求解,递归策略只需少量的程序既可以描述出解题过程所需要的多次重复计算,大大地减少了代码量。递归的主要思考方式在于:把大事化小
递归的两个必要条件:
1、存在限制条件,当满足这个条件的时候,递归便不再继续。
2、每次递归调用之后越来越接近这个限制条件。
//函数的递归
//int main()
//{
// printf("hehe\n");
// main();//栈溢出
// return 0;
//}

void print(int n)//1234
{
if (n > 9)//递归的条件1
{
print(n / 10);//递归的条件2
}
printf("%d", n % 10);
}

int main()
{
unsigned int num = 0;
scanf("%d", &num);//1234
print(num);
return 0;
}

编写函数不允许创建临时变量,求字符串长度
#define _CRT_SECLRE_NO_WARNINGS 1

#include <stdio.h>

//创建临时变量,求字符串的长度
//int my_strlen(char str)
//{
// int count = 0;
// while (str != '\0')
// {
// count++;
// str++;
// }
// return count;
//}

//创建函数不允许创建临时变量,求字符串的长度用递归的方法
int my_strlen(char str)
{
if (str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
//巴大事化小
//my_strlen("bit");
//1+my_strlen("it");
//1+1+my_strlen("t");
//1+1+1+my_strlen("\0");
//1+1+1+0;
//3
}

int main()
{
char arr[] = "bit";
//int len = strlen(arr);//求字符串长度
//printf("%d\n", len);
//模拟实现一个strlen函数
int len = my_strlen(arr);//arr是数组,数组传参,传过去的不是整个数组,而是一个元素的地址
printf("len = %d\n", len);

return 0;

}

递归与迭代
递归:函数自己调用自己就是递归;
迭代:就是重复去计算一个事情,重复去做一个事情;
求n的阶乘
#define _CRT_SECLRE_NO_WARNINGS 1

#include <stdio.h>

////循环
//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;
//}

//递归
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
#define _CRT_SECLRE_NO_WARNINGS 1

#include <stdio.h>

//迭代
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 0;
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}

int main()
{
int n = 0;
int ret = 0;
scanf("%d", &n);
ret = Fib(n);
printf("ret = %d\n", ret);
return 0;
}

////递归
//int count = 0;
//int Fib(int n)
//{
// if (n == 3)//测试第三个斐波那契数的计算次数
// {
// count++;
// }
// int ret = 0;
// if (n <= 2)
// return 1;
// else
//
// return Fib(n - 1) + Fib(n - 2);
//
//}
//
//int main()
//{
// int n = 0;
// int ret = 0;
// scanf("%d", &n);
// ret = Fib(n);
// printf("ret = %d\n", ret);
// printf("count =%d\n",count);
// return 0;
//}

函数递归的几个经典题目(自主研究):
1、汉诺塔问题
2、青蛙跳台问题
《剑指offer》67道笔试题

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: