DEV C++基础教程之函数.docx

上传人:b****6 文档编号:14100614 上传时间:2023-06-20 格式:DOCX 页数:26 大小:448.27KB
下载 相关 举报
DEV C++基础教程之函数.docx_第1页
第1页 / 共26页
DEV C++基础教程之函数.docx_第2页
第2页 / 共26页
DEV C++基础教程之函数.docx_第3页
第3页 / 共26页
DEV C++基础教程之函数.docx_第4页
第4页 / 共26页
DEV C++基础教程之函数.docx_第5页
第5页 / 共26页
DEV C++基础教程之函数.docx_第6页
第6页 / 共26页
DEV C++基础教程之函数.docx_第7页
第7页 / 共26页
DEV C++基础教程之函数.docx_第8页
第8页 / 共26页
DEV C++基础教程之函数.docx_第9页
第9页 / 共26页
DEV C++基础教程之函数.docx_第10页
第10页 / 共26页
DEV C++基础教程之函数.docx_第11页
第11页 / 共26页
DEV C++基础教程之函数.docx_第12页
第12页 / 共26页
DEV C++基础教程之函数.docx_第13页
第13页 / 共26页
DEV C++基础教程之函数.docx_第14页
第14页 / 共26页
DEV C++基础教程之函数.docx_第15页
第15页 / 共26页
DEV C++基础教程之函数.docx_第16页
第16页 / 共26页
DEV C++基础教程之函数.docx_第17页
第17页 / 共26页
DEV C++基础教程之函数.docx_第18页
第18页 / 共26页
DEV C++基础教程之函数.docx_第19页
第19页 / 共26页
DEV C++基础教程之函数.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

DEV C++基础教程之函数.docx

《DEV C++基础教程之函数.docx》由会员分享,可在线阅读,更多相关《DEV C++基础教程之函数.docx(26页珍藏版)》请在冰点文库上搜索。

DEV C++基础教程之函数.docx

DEVC++基础教程之函数

DEV C++教程

第六章函数

第22课:

函数㈠

前面我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。

用它们可以组成任何程序。

但在应用中,还经常用到子程序结构。

通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复出现,此时可以将这些程序段作为相对独立的整体,用一个标识符给它起一个名字,凡是程序中出现该程序段的地方,只要简单地写上其标识符即可。

这样的程序段,我们称之为子程序。

子程序的使用不仅缩短了程序,节省了内存空间及减少了程序的编译时间,而且有利于结构化程序设计。

因为一个复杂的问题总可将其分解成若干个子问题来解决,如果子问题依然很复杂,还可以将它继续分解,直到每个子问题都是一个具有独立任务的模块。

这样编制的程序结构清晰,逻辑关系明确,无论是编写、阅读、调试还是修改,都会带来极大的好处。

在一个程序中可以只有主程序而没有子程序(本章以前都是如此),但不能没有主程序,也就是说不能单独执行子程序。

在此之前,我们曾经介绍并使用了C++提供的各种标准函数,如abs(),sqrt()等等,这些系统提供的函数为我们编写程序提供了很大的方便。

比如:

求sin

(1)+sin

(2)+...+sin(100)的值。

但这些函数只是常用的基本函数,编程时经常需要自定义一些函数。

一、函数的概念

函数是一种对应关系的描述,即确定了函数自变量到函数值之间的对应关系。

与函数相关的概念如下。

⑴自变量:

函数计算时使用的数据,自变量的取值范围称为函数的定义域。

在程序设计中,函数的自变量称为参数,定义域由参数的类型决定。

⑵函数值:

函数的计算结果,它的取值范围称为值域。

在程序设计中函数值称为函数返回值,返回值的类型称为函数类型。

⑶表达式:

数学中函数的计算过程由表达式来说明,在程序设计中,一个函数的处理过程往往比一个表达式所描述的内容要复杂得多,需要一段程序来描述所有的操作,这就是C++语言一个函数的函数体。

二、函数的分类

分为系统函数和用户定义函数(也叫自定义函数)

1、系统函数

系统函数取出由C++语言系统提供的函数(也称库函数)。

这些函数可以从语言系统的手册上查阅其功能和使用方法,用户不需自己再进行定义说明,就直接调用。

例如我们已经学过的标准函数abs、sqrt、max、min等。

例1:

编写求n!

的函数。

参考程序:

#include

usingnamespacestd;

intfact(intn)//fact为函数名;括号里面的为形式参数,简称为形参。

{

inti,t=1;

if(n<0)

{

cout<<"Error!

"<

return0;

}

for(i=2;i<=n;i++)

t=t*i;

returnt;

}

intmain()

{

intm,x;

cout<<"Inputm:

";

cin>>m;

x=fact(m);//函数调用,返回值赋给变量x。

cout<

="<

return0;

}

三、函数的定义

1.函数定义的语法形式

数据类型函数名(形式参数表)//函数的首部

{//函数体;

说明部分;

语句部分;

}

关于函数的定义有如下说明:

1、函数的数据类型是函数的返回值类型(若数据类型为void,则无返回值)。

2、函数名是标识符,一个程序中除了主函数名必须为main外,其余函数的名字按照标识符的取名规则可以任意选取,最好取有助于记忆的名字。

3、形式参数(简称形参)表可以是空的(即无参函数);也可以有多个形参,形参间用逗号隔开,不管有无参数,函数名后的圆括号都必须有。

形参必须有类型说明,形参可以是变量名、数组名或指针名,它的作用是实现主调函数与被调函数之间的关系,通常将函数所处理的数据、影响函数功能的因素或者函数处理的结果作为形参。

在被调用函数中的参数被称为形参。

4、函数中最外层一对花括号“{}”括起来的若干个说明语句和执行语句组成了一个函数的函数体。

由函数体内的语句决定该函数功能。

函数体实际上是一个复合语句,它可以没有任何类型说明,而只有语句,也可以两者都没有,即空函数。

5、函数不允许嵌套定义。

在一个函数内定义另一个函数是非法的。

但是允许嵌套使用。

6、函数在没有被调用的时候是静止的,此时的形参只是一个符号,它标志着在形参出现的位置应该有一个什么类型的数据。

函数在被调用时才执行,也就是在被调用时才由主调函数将实际参数(简称实参)值赋予形参。

这与数学中的函数概念相似,如数学函数:

    f(x)=x2+x+1

这样的函数只有当自变量被赋值以后,才能计算出函数的值。

三、函数的调用

函数的一般调用形式为:

函数名(实在参数1,实在参数2,…)

若实在参数的个数多于一个时,各实在参数之间用逗号隔开。

若函数无形参,调用形式为:

函数名()

函数名后的一对圆括号不可少。

例2:

任意输入10组三角形的三边,求其面积。

【问题分析】:

已知三角形的三条边求其面积,用海伦公式:

【算法设计】:

我们可以定义一个已知三角形三条边分别为a,b,c,求其面积的函数,设为area(a,b,c)。

程序如下:

#include

#include

usingnamespacestd;

doublearea(doublex,doubley,doublez)

{

doubles1,p;

p=(x+y+z)/2;

s1=sqrt(p*(p-x)*(p-y)*(p-z));

returns1;

}

intmain()

{

doublea,b,c;

inti;

for(i=1;i<=10;++i)

{

cout<<"inputa,b,c"<

cin>>a>>b>>c;

if((a+b<=c)||(a+c<=b)||(b+c<=a))

cout<<"dataerror!

"<

elsecout<<"s="<

}

return0;

}

注意:

在函数说明中,如果形参的个数不止一个,那么在程序中调用函数的实参个数一定要与形参的个数一致;第一个实参对应第一个形参,第二个实参对应第二个实参,……,次序不能对调。

例3:

无参函数

编程序打印如下图:

----------

||||

----------

||||

----------

||||

----------

【问题分析】:

共有四个横行,每行10个“-”;共有四个竖行,每行4个“|”

【算法设计】:

设计一个专门的函数只输出横线。

另外一个函数专门输出竖线。

参考程序:

#include

#include

usingnamespacestd;

voidhx()

{

inti;

for(i=1;i<=10;i++)

cout<<'-';

cout<

}

voidsx()

{

intj;

cout<<'|';

for(j=1;j<4;j++)

cout<

cout<

}

intmain()

{

intk;

for(k=1;k<4;k++)

{

hx();

sx();

}

hx();

return0;

}

练习:

求:

1!

+2!

+3!

+……+10!

第23课:

函数㈡

例1:

使用标识符sum_double求两个浮点数之和。

【问题分析】:

在C++的库函数中,很多由常用程序组成的函数可以直接调用,它们用的就是标识符。

【算法设计】:

函数sum_double(doublex,doubley)有两个参数,参数的类型为双精度实数。

调用函数时要传递两个双精度实数。

参考程序:

#include

usingnamespacestd;

doublesum_double(doublex,doubley)

{

returnx+y;

}

intmain()

{

doublea,b,sum;

cout<<"Inputa,b:

";

cin>>a>>b;

sum=sum_double(a,b);

cout<<"sum="<

return0;

}

四、函数调用的传递方式

函数的调用分为传值调用和传地址调用两种,这两种调用的区别在于参数的传递机制不同。

1、传值调用

在被调用的函数中形参的改变不会影响到实在参数的值,换句话说,实参的值是被复制给了形参名字所标识的一个对象中,函数内部对形参的改变并不能影响到实在参数。

2、传地址调用

传地址调用时,实参用的是地址值,而形参则是我们之后要学到的指针变量。

在这章我们先掌握它的调用形式和作用。

在C++语言中,数据只能从实际参数单向传递给形式参数,称为“按值”传递。

例2:

以下两个程序,哪一个能交换两个数的值。

参考程序一:

#include

usingnamespacestd;

voidswap(inta,intb)

{

inttmp=a;a=b;b=tmp;

}

intmain()

{

intc=1,d=2;

swap(c,d);

cout<

return0;

}

参考程序二:

#include

usingnamespacestd;

voidswap(int&a,int&b)

{

inttmp=a;a=b;b=tmp;

}

intmain()

{

intc=1,d=2;

swap(c,d);

cout<

return0;

}

在参考程序一中,虽然在swap函数中交换了a,b两数的值,但是在main中却没有交换。

因为swap函数只是交换c,d两变量的值,主程序传递给函数c、d的是变量的值

在参考程序二中,因为swap函数的参数为传地址调用,所以,在函数swap中修改a,b的值相当于在主函数main中修改c,d的值。

所以参考程序一运行完成后结果为:

12;参考程序二运行完成后结果为:

21。

除了用地址表示符“&”表示传的是地址之外,也可以用指针表示。

参考程序三:

#include

usingnamespacestd;

voidswap(int*a,int*b)

{

inttmp=*a;

*a=*b;

*b=tmp;

}

intmain()

{

intc=1,d=2;

swap(c,d);

cout<

return0;

}

五、函数的全程变量、局部变量及它们的作用域

在函数外部定义的变量称为外部变量或全局变量,在函数内部定义的变量称为内部变量或局部变量。

1、全局变量

全局变量的作用域是从变量定义的位置起直至本源文件结束止,即从定义位置之后的所有函数都可以访问该全局变量。

下面通过例子来说明这一点。

例3:

全局变量的应用。

#include

#include

usingnamespacestd;

intx,y;//定义全局变量x,y

intfun1(ints)

{//访问全局变量x,y

x=10;

y=x*s;

returnx+y;

}

floata,b;//定义全局变量a,b

voidfun2(intc)

{

cout<<"x="<

}

intmain()

{

intm,n;

cin>>m>>n;

cout<

fun2(n);

  cout<<"a="<

  return0;

}

当在键盘上输入69后程序的执行结果是:

70

x=10y=60

a=0b=0

程序中主函数先调用fun1(),实参是6,将实参值传给形参s(即s=6),函数fun1中x值为10,y值为60,return语句将x+y的和返回,fun1()结束。

主函数输出返回值之后,调用fun2(),在fun2()中输出全局变量x和y的值,之后返回主函数。

在主函数中输出全局变量a和b值。

由于a、b在声明时未赋初值,系统的默认值为0。

使用全局变量的说明:

在一个函数内部,既可以使用本函数定义的局部变量,也可以使用在此函数前定义的全局变量。

全局变量的作用是使得函数间多了一种传递信息的方式。

如果在一个程序中多个函数都要对同一个变量进行处理,即共享,就可以将这个变量定义成全局变量,使用非常方便,但副作用也不可低估。

过多地使用全局变量,会增加调试难度。

因为多个函数都能改变全局变量的值,不易判断某个时刻全局变量的值。

过多地使用全局变量,会降低程序的通用性。

如果将一个函数移植到另一个程序中,需要将全局变量一起移植过去,同时还有可能出现重名问题。

全局变量在程序执行的全过程中一直占用内存单元。

全局变量在定义时若没有赋初值,其默认值为0。

2、局部变量

⑴局部变量的作用域是在定义该变量的函数内部。

换句话说,局部变量只在定义它的函数内有效。

在一个子程序内定义的变量也是局部变量,其作用域是该子程序。

函数的形参也是局部变量。

⑵由于局部变量的作用域仅局限于本函数内部,所以,在不同的函数中变量名可以相同,它们分别代表不同的对象,在内存中占据不同的内存单元,互不干扰。

⑶一个局部变量和一个全局变量是可以重名的,在相同的作用域内局部变量有效时全局变量无效。

即局部变量可以屏蔽全局变量。

练习一:

编程求5!

+7!

+9!

+11!

的值。

练习二:

求正整数2和100之间的完全数。

 完全数:

因子之和等于它本身的自然数,如6=1+2+3

练习三:

如果一个自然数是素数,且它的数字位置经过对换后仍为素数,则称为绝对素数,例如13。

试求出所有二位绝对素数。

第24课:

函数的综合运用

例1:

计算如图多边形的面积。

【问题分析】:

从图中可以看出,五边形的

面积是三个三角形面积之和。

【算法设计】:

五边形的5条边分别设为

b1、b2、b3、b4、b5,两条对角线分别为

b6、b7,然后利用海伦公式分别求出三个

三角形的面积,三个三角形的面积之和即为

五边形的面积。

参考程序:

#include

#include

#include

usingnamespacestd;

doublearea(doublea,doubleb,doublec);

intmain()

{

doubleb1,b2,b3,b4,b5,b6,b7,s;

cout<<"pleaseinputb1,b2,b3,b4,b5,b6,b7:

"<

cin>>b1>>b2>>b3>>b4>>b5>>b6>>b7;

s=area(b1,b5,b6)+area(b2,b6,b7)+area(b3,b4,b7);

printf("s=%10.3lf\n",s);

return0;

}

doublearea(doublea,doubleb,doublec)

{

doublep=(a+b+c)/2;

returnsqrt(p*(p-a)*(p-b)*(p-c));

}

此程序中的函数位置与前面的函数不同,放在了主程序的后面。

只在主程序前面放了一个函数的声明。

如果不做声明就放在了主程序后,是会出错的。

六、函数的声明

调用函数之前先要声明函数原型。

在主调函数中,或所有函数定义之前,按如下形式声明:

类型说明符被调函数名(含类型说明的形参表);

如果是在所有函数定义之前声明了函数原型,那么该函数原型在本程序文件中任何地方都有效,也就是说在本程序文件中任何地方都可以依照该原型调用相应的函数。

如果是在某个主调函数内部声明了被调用函数原型,那么该原型就只能在这个函数内部有效。

函数原型和函数定义在返回值类型、函数名和参数个数与类型必须完全一致,否则,就会发生编译错误。

下面对max()函数原型声明是合法的。

intmax(intx,inty);

也可以:

intmax(int,int);

可以看到函数原型声明与函数定义时的第一行类似,只多了一个分号,成为了一个声明语句而已。

2、函数的返回值

在组成函数体的各类语句中,值得注意的是返回语句return。

它的一般形式是:

return(表达式);

其功能是把程序流程从被调函数转向主调函数并把表达式的值带回主调函数,实现函数的返回。

所以,在圆括号表达式的值实际上就是该函数的返回值。

其返回值的类型即为它所在函数的函数类型。

当一个函数没有返回值时,函数中可以没有return语句(在TC++和VC++,函数类型定义为void,可以没有return语句;函数类型定义为int,必须有返回值),直接利用函数体的右花括号“}”,作为没有返回值的函数的返回。

也可以有return语句,但return后没有表达式。

返回语句的另一种形式是:

return;

这时函数没有返回值,而只把流程转向主调函数。

例2:

定义一个函数check(n,d),让它返回一个布尔值。

如果数字d在正整数n的某位中出现则送回true,否则送回false。

例如:

check(325719,3)==true;check(77829,1)==false;

【问题分析】:

本题是利用函数求位数是否相同的题目,函数的返回值为布尔(boolean)变量。

【算法设计】:

利用While循环语句,一位一位的取出给定数字n各位上的数,与给的数d比较,如果相等则函数返回true,否则则返回false。

参考程序:

#include

usingnamespacestd;

boolcheck(int,int);

intmain()

{

inta,b;

cout<<"inputa,b"<

cin>>a>>b;

if(check(a,b)==true)cout<<"true"<

elsecout<<"false"<

return0;

}

boolcheck(intn,intd)

{

while(n)

{

inte=n%10;

n/=10;

if(e==d)returntrue;

}

returnfalse;

}

例3:

求正整数2和100之间的完全数。

 完全数:

因子之和等于它本身的自然数,如6=1+2+3

【问题分析】:

首先判断2-100中的任何一个数是否为完全数,然后在主程序中输出该数。

【算法设计】:

由于2-100之间的任何一个数大于一半就不能被本数整数,所以在函数中判断是否为完全数时只须到一半(即i/2)即可。

参考程序:

#include

usingnamespacestd;

boolwqx(intn);

intmain()

{

inti;

for(i=2;i<=100;i++)

if(wqx(i))printf("%d",i);

return0;

}

boolwqx(intn)

{

intx,s=0;

for(x=1;x<=n/2;x++)

if(n%x==0)s=s+x;

if(s==n)returntrue;

returnfalse;

}

练习一:

求出1-n之间有所有素数之和。

练习二:

编写函数gcd,功能是利用辗转相除法求两个正整数m和n的最大公约数,并由函数值返回。

练习三:

编写一个求两个数约分,求互质数的程序。

第24课:

函数的嵌套和递归

一、函数的嵌套

函数的嵌套调用指的是一个函数调用另一个函数,而被调用函数又可调用其它函数。

例如,在调用A函数的过程中,可以调用B函数,在调用B函数的过程中,还可以调用C函数……当C函数调用结束后,返回到B函数,当B函数调用结束后,再返回到A函数。

这就是函数的嵌套调用过程。

例1:

函数的嵌套应用举例

【问题分析】:

主程序中调用函数1,函数1调用函数2,函数2调用函数3。

【算法设计】:

主程序调用无参数的函数p1(),在p1()中函数调用f(i),而函数f(i)中调用函数p2(i),函数逐级返回。

p2(i)返回f(i),f(i)返回到p1(),p1()返回到主函数。

参考程序:

#include

usingnamespacestd;

inti=10;

voidp2(inti1)

{

i1*=2;

cout<<"i1="<

}

intf(inti)

{

p2(i);

return(3*i);

}

voidp1()

{

i=f(i);

}

intmain()

{

cout<<"i="<

p1();

cout<<"i="<

return0;

}

由上图来看,主程序调用无参函数p1,p1函数调用函数f,而函数f调用函数p2,它们的调用的基本规则是上一层调用下一层。

从上图来看,它们之间的关系是逐层相包,完全套住的。

套住其它函数的函数叫外层函数,被其它函数套住的函数叫内层函数。

对于多层嵌套来说,内层和外层是相对的。

 

二、函数的递归

1、欣赏图片

2、听一个古老的故事

Ø"从前有座山山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:

Ø"从前有座山山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:

Ø"从前有座山山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:

……

Ø

"从前有座山山上有座庙,庙里有个老和尚,老和尚在给小和尚讲故事:

Ø这就是递归

3、递归的概念

函数直接或间接地自己调用自己,称为递归调用。

递归形式一般有两种——间接递归和直接递归。

间接递归——子程序A调用子程序B,子程序B又调用子程序A

在现实生活中,通过间接递归计算两个并列函数或过程的情况并不多见,比较多的递归方式是直接递归。

直接递归——子程序要求自己调用自己

我们研究的是直接递归,它是设计和描述算法的一种有力的工具。

递归结束的要件:

满足某个条件后递归终止。

4、递归所能解决的问题

递归通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的能力在于用有限的语句来定义对象的无限集合。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 卡通动漫

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2