辅导5函数.docx
- 文档编号:30741047
- 上传时间:2023-08-20
- 格式:DOCX
- 页数:18
- 大小:46.54KB
辅导5函数.docx
《辅导5函数.docx》由会员分享,可在线阅读,更多相关《辅导5函数.docx(18页珍藏版)》请在冰豆网上搜索。
辅导5函数
函数
一、函数的定义
1、函数概念的引入
1)举例:
计算圆面积的c程序
#include
voidmain()
{doubler=5.0;
doublearea=3.14159*r*r;
printf(”圆面积为:
%f\n”,area);
}
抽取计算圆面积的算法作为独立程序段,程序可改为:
1.#include
2.doubleCalArea()//2~6行是CalArea函数功能的描述(定义)
3.{doubler=5.0;//这个函数只能计算半径为5的圆的面积
4.doublearea=3.14159*r*r;
5.returnarea;
6.}
7.voidmain()
8.{doublearea=CalArea();//执行CalArea函数
9.printf(”圆面积为:
%f\n”,area);
10.}
修改CalArea()函数,使半径的值由主函数决定
1.#include
2.doubleCalArea(doubler)//r为函数CalArea的形式参数
3.{doublearea=3.14159*r*r;
4.returnarea;
5.}
6.voidmain()
7.{doublearea=CalArea(5);//5为函数CalArea的实在参数
8.printf(”圆面积为:
%f\n”,area);
9.}
修改主函数,使程序可以计算半径不同的圆的面积
1.#include
2.doubleCalArea(doubler)//r为函数CalArea的形式参数
3.{doublearea=3.14159*r*r;
4.returnarea;
5.}
6.voidmain()
7.{doubleradius;
8.printf(”请输入半径”);
9.scanf(“%f”,&radius);
10.doublearea=CalArea(radius);//radius为函数的实在参数
11.printf(”圆面积为:
%f\n”,area);
12.}
2)函数的作用
●降低难度及复杂度,实行分工合作,各尽其职
●便于进行分级管理,简化程序设计
3)C程序的执行
总是从main()开始,最后总是在main()结束(不论main()的位置)
main()
{
aaa();
}
aaa()
{
bbb();
}
bbb()
{……}
程序开始
程序结束
2、函数的定义
1)定义格式
返回类型函数名(形参表){函数体}
doubleArea(doubler){return3.1415*r*r;}
2)函数参数
●含义:
是函数完成功能所需要的输入信息
●参数类型:
形式参数实在参数
●组成:
Ø形式参数:
类型参数1,类型参数2,……,类型参数n
Ø实在参数:
参数1,参数2,…,参数n
3)返回类型
●含义:
函数运行结束返回一个结果值,该值的数据类型
●类型包括:
除数组外所有数据类型(默认类型为int)
4)函数体
●含义:
是函数功能的实现(描述)
●组成:
语句
5)函数的类型
●无参函数/有参函数
Ø无参函数
类型函数名()
{函数体}
Ø有参函数
类型函数名(形参表)
{函数体}
●无返回值/有返回值
Ø无返回值
void函数名(形参表)
{……
return;
}
或void函数名(形参表)
{…
}
Ø有返回值
返回值类型函数名(形参表)
{……
return表达式;
}
3、空函数
1)含义:
函数体为空的函数
2)意义:
增加程序的可读性,便于程序的扩充
4、return语句
1)格式:
return〖表达式〗;
表达式为可选项
2)作用:
●终止当前函数的执行,返回主调函数
●向主调函数返回一个值
5、函数原型
1)前提:
所有标识符都必须遵循“先说明,后使用”的原则。
2)结论:
因此在函数的调用前,必须有函数的说明。
3)函数原型与函数定义的区别
●函数定义——定义性说明“从无到有”——提供函数的所有信息
●函数原型——参考性说明“提供函数调用所需的接口信息”
●定义只能有一次,但声明可以多次出现
4)函数原型语句的格式:
返回类型函数名(形参表);
5)函数能正确调用的条件:
函数的定义位于调用之前或函数的原型位于调用之前
6)必须使用函数原型的情况
●多文件程序
●函数递归调用
●使用库函数
二、函数调用
1、函数的调用
1)调用格式:
函数名(实参表);
实参出现在主调函数中
形参出现在被调函数中
2)注意:
●实参与形参的个数要相同,类型要一致(兼容),且一一对应
●常量形参(const):
函数体中不能改变该形参的值。
3)调用方式:
作为表达式(必须是有返回值的函数)/作为语句调用
2、调用过程
1)参数传递
2)执行函数体
3)函数返回
3、参数传递机制(赋值)
1)传值调用
形式对应关系
实参表达式(有确定值)值
形参变量(存储单元)变量
2)传地址调用
形式对应关系
实参变量的地址地址
形参变量指针
●数组名作为实参传递的是数组的首地址。
三、程序运行时的内存分布
●程序运行时的内存分布
程序代码区
全局数据区
堆区
栈区
程序的源代码(系统支配的空间)
全局变量和静态变量(系统支配的空间)
由程序控制,可在运行中由语句动态分配(malloc)及回收(free)
被调用的函数信息,局部变量(程序支配的空间)
注:
红色为数据区,在全局数据区的数据,若没初始化,自动取值为0;
堆、栈区的数据,若没初始化,其值为随机值。
四、函数调用的实现机制
1、函数调用时系统执行的操作:
●建立被调用函数的栈空间
●保护断点(主调函数的运行状态、返回地址)
●参数传递
●被调用函数取得程序的控制权
2、函数执行结束后系统执行的操作:
●若有返回值,将它存到一个临时的空间
●恢复断点(主调函数的运行状态、返回地址)
●释放相应(调用函数所占)的栈空间
●继续执行主调函数
五、作用域
1、作用域:
标识符在程序中起作用(能被使用)的范围
●全局作用域:
始于声明点,终于程序(程序中一般都含有多个.cpp)的结束。
●文件作用域(static):
始于声明点,终于本文件(.cpp)结束处
●局部(块)作用域:
始于声明点,终于“块”结束处
2、存储属性:
1)静态:
全局变量、static变量
2)动态:
堆变量、自动变量、函数的形参、寄存器变量
3、变量的作用域
1)全局变量:
在函数之外定义
●无限制:
可供程序中的所有函数使用
●有限制:
文件域变量--只供本文件中的所有函数使用
2)局部变量:
在复合语句内定义,仅能在该复合语句内使用
3)覆盖问题:
●内层的同名变量总是覆盖外层的同名变量
●作用域小覆盖作用域大的
4)归纳
全局变量
局部变量
无限制
限制:
文件域
在函数外定义
在函数内定义
非静态存储类型
(不带static)
静态存储类型
(带static)
非静态存储类型
(不带static)
静态存储类型
(带static)
其他文件用extern加以声明后可以使用
不让其他文件使用
离开定义它的函数后其值不保留
(释放内存单元)
离开定义它的函数后其值仍保留
(保留内存单元)
初值为0
初值为随机值
初值为0
4、生命期(生存期):
标识符存在(创建到删除之间)的时间。
●静态生命期:
全局变量、静态变量、常量
特点:
编译时分配空间,程序运行结束才释放空间
●动态生命期:
非静态的局部变量——栈区中的变量
特点:
在函数调用时分配存储单元,函数结束就释放空间
●动态生命期:
使用malloc()等函数分配空间的变量
特点:
程序运行中随时根据需要申请分配空间、释放空间(free)
5、举例:
例1:
#include"stdio.h"
voidfun(int,int);
voidmain()
{inta,b;//这个a,b是内部(局部)变量,有效范围(作用域)在此处开始到main结束(})
a=5;b=8;
fun(a,b);
printf("主函数中:
a=%d,b=%d\n",a,b);
}
voidfun(inta,intb)//这个a,b是内部(局部)变量,有效范围(作用域)在此处开始到fun结束())
{intc;//c是内部(局部)变量,有效范围(作用域)在此处开始到fun结束(})
c=a;a=b;b=c;
printf("fun函数中:
a=%d,b=%d\n",a,b);
}
fun也可写成:
voidfun(intx,inty)//这个x,y是局部变量,有效范围(作用域)在此处开始到fun结束(})
{intc;//c是局部变量,有效范围(作用域)在此处开始到fun结束()}
c=x;x=y;y=c;
printf("fun函数中:
a=%d,b=%d\n",x,y);
}
例2:
test6_8_2.c:
#include"stdio.h"
voidfun();
inta,b;//这个a,b是外部(全局)变量,有效范围(作用域)在此处开始到test6_8_2.c文件的最后一行
voidmain()
{
a=5;b=8;
fun();
printf("主函数中:
a=%d,b=%d\n",a,b);
}
voidfun()
{intc;//c是内部(局部)变量,有效范围(作用域)在此处开始到fun结束(})
c=a;a=b;b=c;
printf("fun函数中:
a=%d,b=%d\n",a,b);
}
例3:
程序1:
a.c
#include"stdio.h"
voidfun();
inta,b;//这个a,b是外部(全局)变量,有效范围(作用域)在此处开始到程序结束
voidmain()
{
a=5;b=8;
fun();
printf("主函数中:
a=%d,b=%d\n",a,b);
}
程序2:
b.c
externinta,b;//两个函数不在同一个程序中,要使用其他程序中定义的外部(全局)变量,需要做出声明
voidfun()
{intc;//c是内部(局部)变量,有效范围(作用域)在此处开始到fun结束(})
c=a;a=b;b=c;
printf("fun函数中:
a=%d,b=%d\n",a,b);
}
例4:
程序1:
a.c
#include"stdio.h"
voidfun();
staticinta,b;//这个a,b是静态外部(全局)变量,有效范围(作用域)限制在a.c中
voidmain()
{
a=5;b=8;
fun();
printf("主函数中:
a=%d,b=%d\n",a,b);
fun();
printf("主函数中:
a=%d,b=%d\n",a,b);
}
程序2:
b.c
externinta,b;//虽然做出声明,但无法使用a.c中定义的静态外部变量
voidfun()
{intc;//c是内部(局部)变量,有效范围(作用域)在此处开始到fun结束(})
c=a;a=b;b=c;
printf("fun函数中:
a=%d,b=%d\n",a,b);
}
例5:
#include"stdio.h"
inta,b;//这个a,b是外部(全局)变量,初始值为0,它们的作用范围是整个程序
voidfun();
voidmain()
{inta,b;//这个a,b是内部(局部)变量,初始值为随机值
b=8;//当外部变量和内部变量作用范围重合时,内部起作用
fun();
printf("主函数中:
a=%d,b=%d\n",a,b);//在main范围中,局部变量a,b起作用
}
voidfun()
{a++;
b--;
printf("fun函数中:
a=%d,b=%d\n",a,b);
}
例6:
#include"stdio.h"
voidfun();
voidmain()
{inti;
for(i=1;i<=5;i++)
fun();
}
voidfun()
{inta=0;//a是内部(局部)变量,每次调用fun函数,a重新分配空间
staticintb=0;//b是静态内部(局部)变量,它的值一直保留到程序结束
a++;
b++;
printf("a=%d,b=%d\n",a,b);
}//a和b的作用范围只在fun函数中
六、函数的递归调用
1、递归调用的含义:
直接或间接地调用函数本身。
(a)直接递归(b)间接递归
2、举例:
例用递归方法求n!
1(n=0,1)
n!
=
n*(n-1)(n>1)
#include
doublefactorial(int);
voidmain()
{intx;
printf("求n!
,请输入n值:
");
scanf(“%d”,&x);
printf("%d!
=%f\n",x,factorial(x));
}
doublefactorial(intn)
{if(n==0||n==1)
return1;
else;
returnn*factorial(n-1);
}
retfactorial(3)
6n=3≠0
factorial
(2)×3
2n=2≠0
factorial
(1)×2
1n=1
例利用递归方法求一维数组a[n]中n个元素之和。
关键语句:
if(n==1)
returna[0];
elsereturna[n-1]+sum(a,n-1);//返回第n个元素的值,并继续处理剩余的n-1个元素
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 辅导 函数
![提示](https://static.bdocx.com/images/bang_tan.gif)