Maple6ch51程序设计.docx

上传人:b****6 文档编号:3620116 上传时间:2022-11-24 格式:DOCX 页数:29 大小:669.59KB
下载 相关 举报
Maple6ch51程序设计.docx_第1页
第1页 / 共29页
Maple6ch51程序设计.docx_第2页
第2页 / 共29页
Maple6ch51程序设计.docx_第3页
第3页 / 共29页
Maple6ch51程序设计.docx_第4页
第4页 / 共29页
Maple6ch51程序设计.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

Maple6ch51程序设计.docx

《Maple6ch51程序设计.docx》由会员分享,可在线阅读,更多相关《Maple6ch51程序设计.docx(29页珍藏版)》请在冰豆网上搜索。

Maple6ch51程序设计.docx

Maple6ch51程序设计

第五章程序设计

§5.1简单的程序设计

前面已经用过很多Maple的内部函数和程序包带的外部程序。

现在我们要学着自己建立函数了。

先来看一个关于log函数的源代码,这样能熟悉一下Maple编程的一般规则。

>interface(verboseproc=2):

先调用函数interface,设置参数

>readlib(log);调log的源代码。

改log为sin等,就能看这些函数的源代码

5.1.1过程和函数

过程和函数差得不是很多,它们都可以实现对方的功能,如果没有特别说明,我们对

这两种概念将不做区分。

一个Maple语言的过程定义的格式如下:

proc(argseq)

locallseq;

globalgseq;

optionsoseq;

descriptionstringseq;

statseq

endproc

一个过程一定是以proc开头,以endproc(或)结束。

过程可以带一个或几个参数argseq,也可以不带;在过程的内部我们可以定义全局变量gseq,局部变量lseq(下节讲),选项部分(oseq)和描述部分(stringseq)(后面讲);当然在过程中我们也可以按照自己的要求写入语句或者调用Maple提供的过程。

下面我们动手自己编一个程序,如下:

>restart;

>Area:

=proc(r)#Area为变量,是过程名可以直接调用,procedure

>Pi*r^2;#程序带一个形参

>endproc;

>Area(10);调用函数Area计算半径为10时圆面积的值

>evalf(%);

多参数的过程编写跟单参数的编写是完全相同的,只是在各个形参间直接用逗号隔开,下面我们举一个三参数的例子——给定三角形的两边长度及其夹角,求其面积:

>TripleArea:

=proc(a,b,q)

>a*b*sin(q)/2;

>endproc;

>TripleArea(3,4,Pi/2);

但上面的程序并不完善,他们不能判断形参的形式,不能对过程异常给出有用的信息,而这是一个好的过程所必须具备的条件,在本章的后面我们将给出求三角形面积的改进过程。

5.1.2全局变量和局部变量

先看由上面圆面积计算程改造后的程序:

>restart;

Area:

=proc(s)#AreaΪ±äÁ¿£¬Êǹý³ÌÃû¿ÉÒÔÖ±½Óµ÷Óã¬procedure

localr,u;#定义局部变量

globalt;#定义全局变量

r:

=10;

t:

=15;

r*t;

Pi*s^2;#³ÌÐò´øÒ»¸öÐβÎ

endproc;

>Area(10);

>r;#程序中的局部变量,在程序之外没有定义

>t;

>t^2;

C语言中在函数里面定义的变量一般叫局部变量,相对应的在函数外面定义的变量变叫做全局变量了。

而在Maple里全局变量和局部变量的区分跟C语言中有点出入:

在Maple的过程里定义的也可能是全局变量,在上面讲到过程的定义的时候,我们曾经介绍过一个参数gseq,它就是在过程中用global标示符声明的一个全局变量;但有一点可以肯定的是:

在过程外面的肯定是全局变量,因此可以说局部变量肯定在过程里面。

在过程里面的变量怎么判断其是全局变量还是局部变量呢?

一般说来可以看其定义:

如果是用global标示符标示的肯定是全局变量,而用local标示符标示的肯定是局部变量;假如变量没有经过标示定义,以下两种情况Maple自动认为是局部变量:

(1)出现在赋值符左边的变量;

(2)在for循环或seq、add、mul命令中表示计数性质的变量。

除了这两种情况以外的其它变量,Maple将认为是全局变量。

为了对这些有一个较清晰

的了解,我们来看下面的这个过程:

>temp:

=proc()

>globalnG;

>localnL;

>nG:

=1;

>nL:

=2;

>nTemp:

=3;

>forifrom1to10do

>nTemp:

=0;

>od;

>end;

Warning,`nTemp`isimplicitlydeclaredlocaltoprocedure`temp`

Warning,`i`isimplicitlydeclaredlocaltoprocedure`temp`

上面两行末出现的“`temp`”表示程序名

由于我们定义变量i和nTemp,Maple给出了警告信息,并提醒用户这两个变量将被作为局部变量,在生成过程中的例子中我们能很清楚的看到这一点,Maple将这两个变量用示符local定义了。

我们介绍了局部变量和全局变量的判别,下面来看看它们之间的区别。

全局变量不属于过程,它可以存在于过程之外,而局部变量只能存在于过程之内,当过程创建时,局部变量也同时被创建,而当过程销毁时,局部变量也同时被销毁。

我们来看看上面那些变量:

>temp();先调用此函数,才能给出其内的全局部或局部变量的情况

>nL;

>nG;

>nTemp;

>i;

>Log(exp

(1));

>log(exp

(1));

变量nG是我们定义的一个全局变量,当过程Temp结束时,它的值仍然存在,说明变量没有销毁,而局部变量nL在过程之外就存在了,另外两个没有定义,但被Maple默认为局部变量的变量nTemp和i都不存在。

虽然Maple能判断未定义的变量,但对我们来说有点模糊,为了使变量定义比较明了,建议对每一个变量都进行定义。

Maple将不同过程中的局部变量看成是单独的变量,即使变量名相同,它们之间也不会受影响,并且一个过程中的局部变量不会影响同名全局变量,在过程中使用这个变量时,过程内定义的变量优先,即这个变量的值将是局部变量的值,而与同名的全局变量无关,我们来看下面例子:

>Temp1:

=proc()要与前段程序先后执行,才能有下面的调出结果

>localnG;

>nG:

=10;将局部变量赋值为10

>nG;

>end;

>Temp1();

>nG;此为上程序段外变量,仍是前段程序中的全局变量

我们可以看到我们在过程Temp1中将nG定义为局部变量,并在过程中赋值10,但在过程外nG的值不变,还是等于1,上面这些规则跟C语言都是相同的,但关于全局部量的规则有些不同,在Maple中全局变量能够重复定义,后面的定义将覆盖前面的变量(其实是在赋值时覆盖,在定义时不覆盖),我们可以从下面看出:

>Temp2:

=proc()

>globalnG,nG1;

>nG1:

=nG;此时的是上段程序的结果:

nG=1

>nG:

=10;对上面重新定义的全局变量nG赋值为10

>end;

>

>Temp2();

>nG1;

>nG;

为了查看全局变量在定义以后的数值,我们另外定义了一个全局变量nG1,从运行后的结果来看,重新定义后其值并没有改变,直到赋值后其值才改变了。

在程序设计时要注意一点:

在过程中对全局变量进行赋值时要特别小心,因为别的过程也可能在使用这个全局变量,任何全局变量的改变将影响到所有使用这个变量的过程,而用户往往注意不到这一点,因此在选择变量的类型时要特别注意。

另外为了保持程序的模块化、增强程序的可读性,一般不在过程内部定义全局变量,假如过程内需要用到全局变量的值,一般都用参数来传递,这些原则跟其他高级语言的程序设计原则是一样的。

5.1.3参数声明和标识符args的使用

在调用过程中我们往往要用到形参,Maple允许不定义参数的类型而直接使用,但有时为了限制参数的类型,希望在输入的参数与我们预先定义的参数不匹配时,系统能够给出出错的信息,我们就应该进行参数类型的声明,参数声明的语法如下:

parameter:

:

type;

parameter是参数名,type为参数的类型。

先来看下面的这个过程

>CircleArea:

=proc(r:

:

positive)

>Pi*r^2;

>end;

这个过程前面已经出现过,但那里并没有设定参数的类型——r应为正数。

注:

Maple参数的类型多种多样,读者可以利用命令?

type来查看帮助。

在C语言中传递参数都是通过定义函数的形参来确定的,这就需要知道形参的具体个数和类型,但有时我们在定义的过程中并不知道参数的个数,或者参数的个数是可变的,碰到这种情形C语言一般都是很让人头疼的,但在Maple中事情就变得很简单,Maple提供了一个全局变的标识符args来传递参数,我们可以在定义过程中不定义形参,而直接使用args,因为在调用过程时Maple会自动将参数传给args,来看一个例子:

>SSum:

=proc()

>locali,total;

>total:

=0:

>forifrom1tonargsdo

>total:

=total+args[i];

>enddo;

>total;

>end;

这个过程没有任何形参的定义,除了用到标识符args以外,还用到了一个参数nargs,它是系统用来存储参数个数的一个变量,当我们调用过程时,系统自动将参数个数赋给它,这一点给我们编程带来了很大的方便,下面我们分别代入1、2、3个参数来看看结果:

>SSum(12);

>SSum(10,11);

>SSum(10,11,12);

>

这个过程输入的参数除了可以是具体的数外,还可以是序列,如下:

>seq1:

=seq(n,n=1..100);

利用标识符args,再结合参数nargs,我们就能很方便地处理形参个数不定的情形了。

5.1.4参数声明和标识符args的使用

为了增强程序的可读性,我们经常要在程序的开头或各条语句的后面加上注释语句,系统在编译时忽略注释语句。

Maple用“#”作为注释语句的标志:

>T:

=proc()

>localx;#xisalocalviarable

>x:

=10;

>end;

>T();

另外也可放在过程的开头或前面注释过程的用途:

>#******************#

>#procCircleArea#

>#ComputetheAreaofaCircle#

>#******************#

>CircleArea:

=proc(r:

:

positive)#可先写过程行,再注释

>pi*r^2;

>end;

描述语句类似于注释语句,它对程序的功能也没有影响,但系统编译的时候并不能忽略它,并且在程序的编译后能够给出一条注释语句,其具体形式如下:

descriptionstringseq;

参数stringseq就是我们希望过程编译后提供注释的内容,描述语句在编译后的过程中存在,但在过程运行时并不显示:

>CircleArea:

=proc(r:

:

positive)

>description"ComputetheAreaofacircle";

>Pi*r^2;

>end;

>CircleArea(10);

要查看一个过程可以用print函数,比如:

>print(CircleArea);

5.1.5过程返回值设置

一般为了得到返回值,要用Maple的过程返回值的设置,在默认情况下,过程返回值是过程语句中最后一条语句的值,这种返回方式我们已在前面见过,如上程序的返回值:

>f:

=CircleArea

(1);

求圆面积的过程的返回值就是一个求面积的语句计算么到的结果,这条语句就是最后一条语句,假如在求面积的语句后面再加上一条语句(显示半径的语句),返回的将是新加上去的语句的值,如下:

>CircleArea:

=proc(r:

:

positive)

>pi*r^2;

>r;

>end;

>f:

=CircleArea

(2);

上面我们都是返回一个参数,其实默认的返回方式也可以实现多参数的返回,只需将要返回的语句写在同一条语句里即可,看下面的例子:

>CircleArea:

=proc(r:

:

positive)

>r,pi*r^2;

>end;

>CircleArea(10);

要将多个返回值赋给外面的全局变量,我们只需要像以前那样赋值即可:

>r:

=%[1];

>area:

=%%[2];

参数的返回除了用系统默认的返回方式外,还可以用给形式参数赋值的方式来返回所需要的结果,这种方法跟C语言的参数赋值返回是一样的:

>CircleArea(10,q,area);

>q;

>area;

为了将第二、三个参数作为被赋值的参数,我们将它们声明为evaln类型,这个类型能将一个变量名传入。

除了以上两种方式能够实现过程值的返回以外,还有一种很常见的返回方式:

利用return(或RETURN)来实现强制返回,函数的具体表达式如下:

returnexpr1,expr2,…;

return(expr1,expr2,…);

RETURN(expr1,expr2,…)

参数expr1,expr2,…是返回的值(也可以是表达式或字符串),返回的值可以为空。

使用时要注意没有RETURNexpr1,expr2,…这种格式:

>CircleArea:

=proc(r:

:

positive)

>returnr,pi*r^2;

>end;

>CircleArea(10);

return(RETURN)返回语句将结束过程返回,其后面的语句将不再被执行,所以这条语句也可以作为中断过程进行强制返回的语句:

>CircleArea:

=proc(r:

:

positive,area:

:

evaln)

>returnr,pi*r^2;

>area:

=Pi*r^2;

>end;

>CircleArea(20,area);

>area;

上面这个过程中,我们在return语句后面的赋值语句并没有被执行,全局变量的值仍然是100,而不是我们希望的400。

因此在设计程序时,假如要返回多个参数,都应该用一条return语句带回多个返回值,避免用多条return语句返回。

return语句很简单,功能也很单一,但在结构化程序设计中,这条语句非常有用,我们在后面还将经常用到。

5.1.6格式输出函数printf

函数printf能输出若干个任意类型的数据,其一般格式为

printf(fmt,x1,…,xn);

参数fmt表示“格式控制”,是用双引号括起来的字符串,也称“转换控制字符串”,它包括两种信息:

(1)式说明,由“%”和格式字符组成,如%d,%f等。

它的作用是将输出的数据转换

为指定的格式输出。

格式说明总是由“%”字符开始的。

(2)通字符,即需要原样输出的字符。

参数x1,…,xn是函数将要输出的一些数据,

也可以是表达式。

printf(“%d%d”,a,b);printf(“a+b=%,a-b=%d”,a+b,a-b)

>a:

=10:

b:

=6:

>printf("%d,%d",a,b);

10,6

>printf("a+b=%d,a-b=%d",a+b,a-b);

a+b=16,a-b=4

函数printf的格式字符有很多种,几种最常用的格式字符为:

(1)d格式——输出十进制数:

1)%d,按整数型数据的实际长度输出;2)%md,字符m指定输出值段的宽度,如果数据的位数小于m,则左端补以空格,若大于m,则按实际们数输出。

如:

>a:

=12345:

b:

=123:

>printf("%4d,%4d",a,b);

12345,123后面的数的前面有一空格

(2)o格式——以八进制数形式输出整数,由于是将内存单元中的各位的值(0或1)按八进制形式输出,因此输出的数值不带符号,即将符号位也一起作为八进制的一部分输出。

>a:

=-1:

>printf("%d,%13o,%8o",a,a,a-a);

-1,37777777777,0

(3)x格式——以十六进制数形式输出整数。

同样也不会出现负的十六进制数。

(4)f格式——用来输出实数(包括单、双精度),以小数形式输出。

有以下几种用法:

1)%f,不指定字段宽度,由系统自动指定,使整数部分全部如数输出,并输出6位小数。

如:

>f:

=12.111:

>printf("%f",f);

12.111000

2)%m.nf,指定输出的数据共点m列,其中有n位小数,注意小数点也占一列,

如果数值长度小于m,则左端补空格。

>printf("%5.2f,%10.3f",f,f);

12.11,12.111

3)%-m.nf,与%m.n基本相同,只是输出的数值向左端靠,右端补空格。

(5)e和E格式符——以指数形式输出实数。

可用以下形式:

1)%e,不指定输出数据所占的宽度和数值部分小数位,由系统自动给出6位小数,指数部分占4位,数值按标准化指数形式输出(小数点前仅有一个非零数字)。

>e:

=12.111:

>printf("%e",e);

1.211100e+01

2)%m.ne,%-m.ne,两者的含义同前

>printf("%5.2e,%-20.5e,%10.2e",e,e,e);

1.21e+01,1.21110e+01,1.21e+01

(6)g格式符——用来输出实数,它根据数据的大小,自动选f格式或e格式(选择输出时占宽度较小的一种),且不输出无意义的零。

>printf("%g%g%g\n",123,123/456,123456789);

123.2697371.234568e+08

(7)c格式符——用来输出一个字符。

>c:

='c':

>printf("%c",c);

c

(8)s格式符——用来输出一个字符串。

有几种用法:

1)%s,按实际长度输出字符串。

2)%ms,输出字符串占m列,如字符串本身大于m列,则突破m的限制,将字符全部输出,若串长小于m,则左补空格(%-ms右):

3)%m.ns,输出占m列,但只取字符串中左端n个字符输在右侧,左侧补空。

(%-m.n)

>s:

="It'sme!

":

>printf("%s,%-12s,%12s,%3.6s,%10.4s",s,s,s,s,s);

It'sme!

It'sme!

It'sme!

It'sm,It's

(9)a,A格式符和q,Q格式符——a和A用来准确地输出Maple中的表达式。

而q和Q跟a的功能相似,只是这个格式符将后面所有的表达式序列都用a格式转换后输出:

>a:

=-1:

b:

=123:

f:

=12.111:

e:

=12.111:

c:

='c':

>printf("head=%a\ntail=%q\n",a,b,c,d,e,f);

head=-1

tail=123,c,d,12.111,12.111

§5.2选择结构

判断给定的条件是否满足,并根据判定的结果(真或假)决定执行给出的两种操作之一,这种程序结构就是选择结构。

Maple里的选择结构跟其他高级语言一样,也是用if语句来实现的,下面分三种形式介绍,并简略介绍一下if语句嵌套结构的使用。

普通的if语句可以分成三种形式:

5.2.1if(表达式)then语句1fi

当表达式的值为真时,过程转入语句1执行,否则跳出选择语句:

>Max:

=proc(x:

:

numeric,y:

:

numeric)

>if(x>=y)thenreturnx;

>fi;也可用“endif”

>end;

>Max(1,2);跳出

>Max(3,2);

5.2.2if(表达式)then语句1else语句2fi

当表达式的值为真时,执行语句1,否则执行语句2:

>Max:

=proc(x:

:

numeric,y:

:

numeric)

>if(x>=y)thenreturnx;

>elsereturny;

>endif;

>end;

>Max(1,2);

>Max(3,2);

5.2.3多语句选择结构

if(表达式1)then语句1

elif(表达式2)then语句2

elif(表达式3)then语句3

elif(表达式n)then语句n

else语句n+1

endif

>Test:

=proc(x:

:

numeric)

>if(x>100)thenreturn("xismorethan100");

>elif(x>=10)thenreturn("xisbetween10end100");

>elif(x>0)thenreturn("xisbetween0and10");

>elsereturn("xislessthan0");

>endif;

>end:

>Test(101);

>Test(50);

>Test(5);

>Test(-10);

注:

if还可以嵌套组合使用,就是一个语句中含多个if语句,它们的一般形式如下:

if(表达式1)then

if(表达式2)then语句1

else语句2

endif

else

if(表达式3)then语句3

else语句3

endif

endif

当然各个语句中也可以没有else语句部分,且嵌套的层数可以不止一层,子if语句下面还可以嵌套if语句,如:

>Test:

=proc(x:

:

numeric)

>localy;

>if(x>100)then

>if(x>200)then

>y:

=2;

>return(y);

>elsey:

=1;

>return(y);

>endif;

>elsey:

=0;

>return(y);

>endif;

>end;

>Test(400);

>Test(200);

>Test(100);

§5.3循环结构

5.3.1for…do循环

for变量名i[from表达式1][by表达式2]to表达式3do

语句

enddo;

变量名i是用来控制循环的一个变量,既可以是全局变量也可以是局部变量;from语句后放一个能计算出数值的代数表达式,表示变量i开始的值,这个语句放在方括号中表示这部分可以省略,当语句省略时,系统默认值1;by语句用来设置变量变化的增量(步长),可以是正值也可以负值,此语句也可以省略,省略时步长为1;表达式3表示的数值是变量i的最后界限,当步长为正,变量i的值大于表达

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

当前位置:首页 > 工作范文 > 制度规范

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1