C语言初阶—函数(函数的声明和定义,函数递归)

        函数声明:

        1.告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但是具体是不是存在,函数声明决定不了。

        2.函数的声明一般出现在函数使用之前,要满足先声明后使用。

        3.函数的声明一般要放在头文件中。

        函数定义:

        函数定义是指函数的具体实现,交代函数的功能实现。

        函数定义在后面,在前面使用,会产生警告,因为是从前往后执行的。

        在函数使用之前,加上函数声明就不会产生警告。

        函数递归

        程序调用自身的编程技巧称为递归。

        递归作为一种算法在程序设计语言中广泛应用,一个过程或函数在其定义或说明中有直接或间接调用自身的。

        一种方法,它通常把一个大型复杂的问题层层转换为与一个与原问题相似的规模较小的问题来求解,递归策略。

        只需少量的程序就可描述出解题过程中需要的多次重复计算,大大减少了程序的代码量。

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

        递归的两个必要条件

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

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

//输入1234,按位输出:1 2 3 4

把大事化小:

print(1234) ---> print(123)  4 ---> print(12)  3 4 ---> print(1) 2 3 4  ---> 1 2 3 4

#include <stdio.h>

void print(int x){
	if(x / 10 != 0)
    {
		print(x / 10);
    }
	printf("%d\n",x % 10);
}
//输入1234,输出:1 2 3 4
int main()
{
	int n = 0;
	scanf("%d",&n);
	print(n);
	return 0;
}

        自定义求字符串长度的函数

#include <stdio.h>

//int my_strlen(char* ch){
//	int count = 0;
//	while(*ch != '\0')
//	{
//		count++;
//		ch++;
//	}
//		return count;
//}
//不创建临时变量,求字符串长度
int my_strlen(char* ch){
	if(*ch != '\0')
	{
		//return my_strlen(++ch) + 1;
		//这种写法虽然可以,但是会改变ch
		return my_strlen(ch + 1) + 1;
	}
	else
		return 0;
}
int main()
{
	int length = 0;
	char ch[12] = "Hello World";
	length = my_strlen(ch);
	printf("%d\n",length);
	system("pause");
	return 0;
}

        上面一种注释掉的方法是用while循环,并创建临时变量来辅助计数,也可以使用递归:

my_strlen("abc") ---> 1 + my_strlen("bc") ---> 1 + 1 + my_strlen("c") ---> 1 + 1 + 1 + my_strlen("") ---> 1 + 1 + 1 + 0 = 3

        计算k的阶乘

#include <stdio.h>

//计算k的阶乘

//递归实现
//int fac(int x){
//	if(x != 1)
//		return x * fac(x - 1);
//	else
//		return 1;
//}

//迭代实现
int fac(int x){
	int i = 0;
	int ret = 1;
	for(i = 1;i <= x;i++)
		ret = ret * i;
	return ret;
}
int main()
{
	int k = 0;
	int n = 0;
	scanf("%d",&k);
	n = fac(k);
	printf("%d\n",n);
	return 0;
}

        斐波那契数列:

#include <stdio.h>

//斐波那契数列
//递归
//int Fibonacci(int x){
//	if(x <= 2)
//		return 1;
//	else
//		return Fibonacci(x - 1) + Fibonacci(x - 2);
//}
//非递归
int Fibonacci(int x){
	int i = 0;
	int a = 1;
	int b = 1;
	int c = 0;
	if(x <= 2)
		return 1;
	else
		for(i = 3;i <= x;i++){
			c = a + b;
			a = b;
			b = c;
		}
		return c;
}
//1 1 2 3 5 8
int main()
{
	int k = 0;
	int n = 0;
	scanf("%d",&k);
	n = Fibonacci(k);
	printf("%d\n",n);
	return 0;
}

        系统分配给程序的栈空间是有限的,但是如果出现了死循环或死递归,这样有可能导致一直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们成为栈溢出。

        如何解决上述问题:

1.将递归改写为非递归

2.使用 static 对象替代 nonstatic 局部对象。在递归函数设计中,可以使用static对象替代nonstatic局部对象(即栈对象),这不仅可以减少每次递归调用和返回时产生和释放nonstatic对象的开销,而且static对象还可以保存递归调用的中间状态,并且可为每个调用层所访问。

  • 58
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值