C语言学习笔记(八)--超详细的函数讲解--part 2

目录

前言

一.函数的递归调用和递归函数

二.变量的作用域

三.变量的生存期

                1.自动变量

                2.静态变量

                3.外部变量

                4.寄存器变量


前言

接着上一部分,这篇文章从函数的递归调用和递归函数开始。

一.函数的递归调用和递归函数

如果一个对象部分地由它自己组成或按它自己定义,则我们称它是递归的。

阶乘是可以根据其自身来定义的问题,因此阶乘也是可递归求解的典型事例,下面我们用递归方法实现计算整数n的阶乘n!。

代码如下:

#include<stdio.h>
long Fact(int n);
int main(void)
{
	int n;
	long result;
	printf("Input n:");
	scanf("%d", &n);
	result = Fact(n);
	if (result == -1)
	{
		printf("n<0,data error!\n");
	}
	else
	{
		printf("%d!=%ld", n, result);
	}
	return 0;
}
//函数功能:用递归法计算n!,当n>=0时,返回n!,否则返回-1
long Fact(int n)
{
	if (n < 0)						//处理非法数据
	{
		return -1;
	}
	else if (n==0||n==1)			//递归终止条件
	{
		return 1;
	}
	else
	{
		return(n * Fact(n - 1));	//递归调用,利用(n-1)!计算n!
	}
}

通过上面的代码,我们可以知道,一个递归函数必须包含如下俩个部分:

1.由其自身定义的于原始问题类似的更小规模的子问题,它使递归过程持续进行,称为一般情况。

2.递归调用的最简形式,它是一个能够用来结束递归调用过程的条件,通常称为基线情况。

像这种“在函数内直接或间接地自己调用自己”的函数调用,就称为递归调用,这样的函数称为递归函数。

 

 

二.变量的作用域

1.程序中被花括号括起来的区域,叫做语句块。函数体是语句块,分支语句和循环体也是语句块。

2.变量的作用域规则是:每个变量仅在定义它的语句块内有效,并且拥有自己的存储空间。

3.不在任何语句块内定义的变量称为全局变量。全局变量的作用域为整个程序,即全局变量在程序的所有位置均有效。在与main()平行的位置即不在任何语句块内定义的变量,在整个程序的所有位置均有效。相反,在除整个程序以外的其他语句块内定义的变量,称为局部变量。

三.变量的生存期

变量的生存期是由变量的存储类型声明的,变量的存储类型决定了变量的生存期,变量的存储类型的一般声明方式如下:

存储类型 数据类型 变量名表

 存储类型主要分为以下几种:

1.自动变量

自动变量的标准定义格式:

auto 类型名 变量名;

例如:auto int temp;

由于自动变量极为常用,所以auto可以省略不写。如果没有指定变量的存储类型,那么变量的存储类型就缺省为auto。

自动变量的自动体现在进入语句块时自动申请内存,退出语句块时自动释放内存,它仅能被语句块中的语句访问,在退出语句块后就不能访问了,所以自动变量也称为动态局部变量

看下面代码,观察和分析程序的运行结果:

#include<stdio.h>
long Func(int n);
int main(void)
{
	int i, n;
	printf("Input n:");
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		printf("%d!=%ld\n", i, Func(i));
	}
	return 0;
}
long Func(int n)
{
	auto long p = 1;
	p = p * n;
	return p;
}

运行结果如下:

这说明俩个问题:

① 自动变量在定义时不会自动初始化

②自动变量在退出函数后,其分配的内存立即被释放,再次进入语句块,该变量被重新分配内存,所以不会保持上一次退出函数前所拥有的值。

2.静态变量

一个自动变量在退出定义它的函数后,因系统给它分配的内存已经被释放,下次再进入该函数时,系统会重新给它分配内存,因此它的值是不会被保留的。这时我们就要用到静态变量static,这个关键字定义的变量称为静态变量。

定义格式为:

static 类型名 变量名;

 下面程序利用静态变量计算n的阶乘,代码如下:

#include<stdio.h>
long Func(int n);
int main(void)
{
	int i, n;
	printf("Input n:");
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		printf("%d!=%ld\n", i, Func(i));
	}
	return 0;
}
long Func(int n)
{
	static long p = 1;
	p = p * n;
	return p;
}

 运行结果如下:

我们对比发现:静态变量与程序是“共存亡的”,而自动变量是与程序块“共存亡的” 

在下一次进入函数时,静态局部变量的值仍保持上一次退出函数前所拥有的值,这使得定义了静态局部变量的函数具有一定的记忆功能。然而,函数的这种记忆功能也使函数对于相同的输入参数输出不同的结果,因此还是尽量少用静态局部变量。

3.外部变量

如果在所有函数之外定义的变量没有指定其存储类型,那么它就是一个外部变量。外部变量是全局变量,它的作用域是从它的定义点到本文将的末尾。但是如果要在定义点之前或者在其他文件中使用它,那么就需要用关键字extern对其声明(不是定义,编译器不对其分配内存

格式为:

extern 类型名 变量名;

和静态变量一样,外部变量也是在静态存储区分配内存,其生存期是整个程序的运行期,没有显示初始化的外部变量由编译程序自动初始化为0 

4.寄存器变量

寄存器变量就是用寄存器存储的变量,定义格式为:

register 类型名 变量名;

 寄存器是CPU内部的一种容量有限但速度较快的存储器,由于CPU访问内存的操作是很耗时的,因此将需要频繁访问的数据放在CPU内部的寄存器里,可以避免CPU对存储器的频繁访问,使程序更小,执行速度更快。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
C语言是一种广泛应用于计算机科学和软件开发的编程语言。它具有强大的功能和灵活性,适用于开发各种类型的应用程序。 C语言专题精讲篇是一个对C语言进行深入学习讲解的系列文章或课程。它汇总了C语言相关的重要知识点和技巧,旨在帮助学习者更好地理解和运用C语言。 这个专题中的笔记涵盖了C语言的各个方面,包括基本语法、数据类型、运算符、流程控制、函数、数组、指针、结构体、文件操作等。通过系统性的学习和总结,这些笔记可以帮助学习者逐步掌握C语言的核心概念和常用技巧。 在这个专题中,学习者可以学到如何编写简单的C程序,如何使用变量和运算符进行计算,如何使用条件和循环语句控制程序流程,如何使用函数进行代码的模块化,如何使用数组和指针进行数据的处理,如何使用结构体组织复杂数据,如何进行文件的读写等等。 C语言专题精讲篇的目的是帮助学习者全面、深入地了解C语言的各个方面,并能够独立编写和调试简单到中等难度的C程序。通过反复实践和练习,学习者可以逐渐提高自己的编程能力,并为进一步学习更高级的编程语言打下坚实的基础。 总之,C语言专题精讲篇的笔记汇总是一份重要的学习资料,可以帮助学习者系统地学习和掌握C语言的基础知识和常用技巧,为他们未来的编程之路打下坚实的基石。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

瑟瑟发抖的可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值