[ C语言 ] 函数的嵌套调用--链式访问--声明--定义--递归--练习--函数(完)

文章目录

  • 前言
  • 一,函数的嵌套调用
  • 二,函数的链式访问
  • 三,函数声明
  • 四,函数的定义
  • 五,递归
  • 六,递归练习
  • 总结





前言

本节内容主要记录函数的剩余内容,前段内容可以参考上篇文章(为了方便起见,下方是上篇文章的链接)

[C语言] 函数:库函数--自定义函数--函数的调用--练习--详解<个人>------(1)_小白又菜的博客-CSDN博客

本次记录的主要内容包括:

函数的嵌套调用--链式访问--声明--定义--递归。

———————————————————————————————————————————

                                                                        ****正文开始****

一,函数的嵌套调用

函数是可以嵌套调用的,具体理解我们用下面这个代码理解:

void new_line() {

	printf("hehe\n");
}
void three_line() {

	int i = 0;
	for (i = 1; i <= 3; i++) {
		new_line();
	}
}
int main() {

	three_line();

	return 0;
}

我们先看一下运行结果:

 我们可以看到,打印了 3 个 hehe.

通过这张图,我们可以清晰地根据颜色箭头看到,在three_line函数内部嵌套了一个new_line函数

所以函数是允许嵌套调用的

注:函数可以嵌套调用 但是不能嵌套定义 :就是不能在一个函数里面再写一个函数

二,函数的链式访问

函数的链式访问就是把一个函数的返回值作为另外一个函数的参数。

我们也是通过一段代码对这个知识点进行理解:

int main() {

	//int len = strlen("abc");
	//printf("%d\n", len);
	//                 函数
	printf("%d\n", strlen("abc"));
	//      参数1       参数2

	//链式访问: 把一个函数的返回值作为另外一个函数的参数

	return 0;
}

我们看一下演示结果:

 在这段代码中,strlen函数是作为printf打印函数的第二个参数,它是把自己的返回值3返回给了printf函数,所以最终打印结果是:3

为了加深理解,我们看一下这段代码,它的打印结果到底是什么?

int main() {

	printf("%d", printf("%d", printf("%d", 43)));// 打印: 4321
 //          1             2          43 

	return 0;
}

我们看一下运行结果:

 奇怪?他为什么会打印出4321呢?其实这里就是函数的链式访问,我们逐一分析就可做出回答。分析如下:

我们先在MSDN里面搜索了解一下printf函数

 我们了解到:

printf函数的返回值是打印在屏幕上字符的个数

 因此我们现在就可以清晰地理解这段代码的结果是:4321

三,函数声明

1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。
2. 函数的声明一般出现在函数的使用之前。要满足 先声明后使用
3. 函数的声明一般要放在头文件中。

具体体现在代码中是这样的:

如果我现在写一个Add函数(两数相加)

int Add(int x, int y) {

	int z = 0;
	z = x + y;
	return z;

}
int main() {
	int a = 10;
	int b = 20;
	int ret = Add(a, b);
	printf("%d\n", ret);

	return 0;
}

如果这时候我们把函数写到了主函数的下面,这时候编译器会抛出一个错误:

 它会告诉我们说:Add未定义,这时候我们只要在主函数前声明Add函数即可已解决问题:

具体解决放下如下:

只需在主函数前加上:

int Add(int x, int y);

完整代码和演示结果:

四,函数的定义

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

例如:上一个Add函数的定义

int Add(int x, int y) {

	int z = 0;
	z = x + y;
	return z;

}

五,递归

(1)什么是递归?

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

(2)递归的两个必要的条件是什么?

1>存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2>每次递归调用之后越来越接近这个限制条件。

为了加深对这两个必要条件的理解,我们以一个举例为例子:

题目:接受一个整数,按照顺序打印每一位

实现代码如下:

void Print(unsigned int n) {

	if (n > 9) { 

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

int main() {

	unsigned int num = 0;
	scanf("%u",&num);
	Print(num);

	return 0;
}

演示结果:

详细分析如下:

 通过这个案例我们理解两个必要条件:

1>存在限制条件,当满足这个限制条件的时候,递归便不再继续。
如果说不加限制条件代码如下:
void Print(unsigned int n) {

	//if (n > 9) { 

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

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

 因此这两个条件是必要条件,如果递归成立,一定会满足这两个条件。

六,练习

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

注意:这题的要求是不允许创建临时变量,所以下面这种写法是错误的:

int main() {

	//求字符串的长度
	char arr[] = "abc";
	int len = strlen(arr);
	printf("%d\n", len);

	return 0;
}

int my_strlen(char* s) {

	int count = 0; // 临时变量
	//printf("%c\n", *s);
	while(*s != '\0') {
		
		count++;
		s++;
	}
	return count;
}

因为count属于临时变量,正确代码应该为:

int my_strlen(char* s) {
	if (*s == '\0') {
		return 0;
	}
	else {
		return 1 + my_strlen(s + 1);
	}
}
int main() {

    //求字符串的长度
	char arr[] = "abc";
	//arr是数组名,数组名是数组首元素的地址
	int len = my_strlen(arr);//char*
	printf("%d\n", len);
	return 0;
}

具体分析:

 

运行结果:

 

题目:求n的阶乘

解决代码:

int fac(n) {
	
	if (n <= 1) {
		return 1;
	}
	else {
		return n * fac(n - 1);
	}
}

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

                                                                  ****正文结束 ****

———————————————————————————————————————————




总结

本节主要记录了函数的嵌套调用--链式访问--声明--定义--递归

个人觉得 递归  还是很难以理解的 还需要多加练习

好啦,本节内容就记录到这里,由于本人技术水平有待提高,若各位大佬们发现错误请及时指正。

创作不易,来波点赞+关注呗 QAQ 

嘿嘿~

  • 44
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白又菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值