前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言函数专题攻略附练习讲解(从0到1)【纯干货】(自定义函数+递归+应用实例)

C语言函数专题攻略附练习讲解(从0到1)【纯干货】(自定义函数+递归+应用实例)

作者头像
see.
发布2024-06-04 12:40:29
2340
发布2024-06-04 12:40:29
举报
文章被收录于专栏:C++破军之路

一、C语言中函数的分类:

1.库函数:

为了提高工作效率,把使用频率高的一些代码封装成库函数,使用时直接引用即可。

注:使用库函数,必须包含#include对应的头文件。

库函数虽然多,但没必要完全背过,要学会MSDN等一些c语言词典进行查询

点赞后给博主发私信即可获取MSDN简化版安装包。

2.自定义函数:

在以上两个自定义函数中,第一个运行正常,第二个与它的设计相仿,函数正常调用,但运行结果并不是我们想要的,说明我们设计的函数出了问题。

错误原因:由前面初始指针的基础可知,每创建一个变量就会开辟一个新的内存空间。因此,上方函数中的参数和下方公式调用的参数是两个独立的空间,上方参数的改变影响不到下方。

这里可以看到Swap1函数在调用的时候,X,y拥有自己的空间,同时拥有了和实参一模一样的内容。所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝。swap1是传值调用,swap2是传址调用。

函数的参数

实际参数(实参): 真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。 形式参数(形参): 形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

函数的基本应用

这里可能会有人问sz不能直接扔到函数中去吗,答案是不能。

数组arr传参,,实际传递的不是数组本身,而是仅仅传递过去了数组首元素的地址

如果函数内部需要参数部分传过来某个数组的元素个数,一定要在外面求好元素个数。

二、函数的嵌套调用和链式访问

这是一个最简单的嵌套调用,函数可以嵌套使用,却不能嵌套定义。

链式访问就是把步骤压缩,strcpy的返回值做了printf的参数,如下图:

上图为printf的返回值,可以看到printf每次返回上次打印数字的个数,由此可以做一道练习。

 三、函数递归

什么是递归 ?

程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在于:把大事化小。

递归的两个必要条件

存在限制条件,当满足这个限制条件的时候,递归便不再继续每次递归;

调用之后越来越接近这个限制条件。

下面例子展示了函数递归可以把复杂的问题简单化。

函数递归存在一些限制条件:栈溢出(stack overflow)

 函数的每一次调用都会在栈区分配一块空间,内存的栈区空间有限,当内存不足时就会出现栈溢出的情况。

递归的两点要求:1.不能死递归,都有跳出条件,每次递归逼近跳出条件。2.递归的层次不能太深

函数递归的应用实例

汉诺塔问题

汉诺塔问题本身十分复杂,但是借助函数递归实现时使用大事化小的方法,分析结果如何得到。汉诺塔问题的本质就是把起始柱子上最大的圆环借助于中间柱放在目标柱上,可进一步简化为:把n-1个圆环放在中间柱上,然后把第n个圆环放在目标柱上,最后把n-1个圆环放在目标柱子上,问题就可以得到解决。

四、练习

计算1/1-1/2+1/3-……+1/99-1/100的值

代码语言:javascript
复制
#include<stdio.h>
int main()
{
	int i = 0;
	double sum = 0;
	int flag = 1;
	for (i = 1; i <= 100; i++)
	{
		sum += flag* 1.0 / i;//也可使用if函数
		flag = -flag;
	}
	printf("%lf\n", sum);
	return 0;
}

求十个整数中的最大值

解法:左图为初步设想,但是如果这么写会出现一个致命bug,如果里面放的是负数的话就没办法正确比较得出结论。以打擂台为例,在一个班中找出打擂台最厉害的人,要在班级内部比较,而不是跟泰森比较。当十个整数都为负数时,输出结果会为0,由此可见max赋值错误,应该赋给数组内部的某个值然后开始比较。

计算一个数的每位之和(递归实现)

题目内容:输入一个非负整数,创造函数DigtSum使得结果为该数每一位之和,例如输入1788,则为1+7+8+8,结果为24.

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int DigtSum(int a)
{
	if (a > 9)
	{
		return DigtSum(a/10) + a % 10;
	}
	else
		return a;

}
int main()
{
	int num = 0;
    scanf("%d",&num);
	int pro = DigtSum(num);
	printf("%d\n", pro);
	return 0;
}

利用递归的方法求解n的k次方

代码语言:javascript
复制
//利用递归求解n的K次方
double pow(int n,int k)
{
	if (k == 0)
		return 1;
	else if (k > 0)
		return n * pow(n, k - 1);
	else
		return 1.0 / (pow(n, -k));
}
int main()
{
	int n = 0;
	int i = 0;
	scanf("%d %d", &n,&i);
	double power = pow(n, i);
	printf("%lf\n", power);

	return 0;
}

利用递归和非递归的方法分别求解斐波那契数列

其中 ,递归方法看似较为简单,但是实际上它的时间复杂度高于非递归方法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、C语言中函数的分类:
    • 1.库函数:
      • 2.自定义函数:
        • 函数的参数
        • 函数的基本应用
    • 二、函数的嵌套调用和链式访问
    •  三、函数递归
      • 什么是递归 ?
        • 递归的两个必要条件
          • 函数递归的应用实例
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档