PASCAL语言基础及基础训练 第 26 页 共 48页
S[I].sum:=s[I].chinese+s[I].mathe; S[I].average:=s[i].sum/2 End; ????
{如果程序要求打印或排序,只需在此增加这些功能语句} end.
第四节、字符串
在PASCAL语言中,字符串的处理是非常方便的,在定义字符串时,我们不仅可以定义成CHAR型(单个字符);STRING型(任意个字符);STRING[N]型(指定只有N个字符)。在后两种类型中,我们都可以使用:变量名[I],来指定字符串中的第I字符,以便得到它的值或对其赋值。而且,我们还可以使用如下函数对字符串进行各种操作:
1、 CHR(N):返回N(ASCII码)对应的字符。如:CHR(66)的值是?b?; 2、 UPCASE(C):把字符串全部转成大写字母。 3、 CONCAT(S1,S2):把两个字符串相加,如:CONCAT(‘ABC’,‘123’)的结果是‘ABC123’; 4、 COPY(S,M,N):这是很有用的一个函数,它的作用是取字符串S第M个字符开始的N个
字符作为一个新的子串。如:COPY(‘ABCDE’,3,2)的值是‘CD’; 5、 LENGTH(S):求字符串S的长度。如:LENGTH(‘ABCD’)的值是4; 6、 DELETE(S,M,N):与COPY的功能正好相反,作用是把字符串S的第M个字符开始的N个
字符删除掉。如DELETE(‘ABCDEF’,3,2)的结果是‘ABEF’; 7、 INSERT(S1,S2,N):把字符串S1插入到字符串S2中,插在S2的第N个字符。如:INSERT
(‘ABCD’,‘12345’,2)的结果是:‘1ABCD2345’。 8、 POS(S1,S2):这是一个非常有用的函数,其作用是判断S1是否是S2的子串,返回结果
是:(1)如果是子串,只返回S1在S2中的起始位置;(2)如果不是子串,则返回0。如:POS(‘123’,‘ABCDEF’)的值为0;POS(‘AB’,‘BABCD’)的值为2;
另外,我们还可以使用如下几个过程: 1、 STR(N,S):这是一个过程,作用是把N这个数值转化为S这个字符串。如:STR(123,S),
作用是把S的值赋成了‘123’; 2、 VAL(S,N,CODE):这也是一个过程,作用是把S这个字符串转化为N这个数值,并且同
时返回CODE这个错误代码(整数型)。如:VAL(‘135’,N,C);作用是把N的值赋成了135这个数值,而且返回C这个错误代码。为什么会有错误代码呢?大家看这个语句是否错误,错在哪里:VAL(‘12ABC’,M,C);
[例6、3]把26个英语字母正向、逆向打印出来。 Const s:string[26]=?abcdefghijklmnopqrstuvwxyz?; Var t:string[26];
I:integer; Begin
t:=? ?; {共26个空格} For I:=1 to 26 do begin
T[I]:=s[27-I]; End;
Writeln(s); Writeln(t); End.
[例6、4]找出所有的四位回文数:(回文数就是一个数从左往右读与从右往左读都是同一个数) var s:string[4];
n:integer; begin
for n:=1000 to 9999 do begin
str(n,s);
26
PASCAL语言基础及基础训练 第 27 页 共 48页
if (s[1]=s[4]) and (s[2]=s[3]) then write(n:6); end; end.
或者用如下程序: var n:integer;
s,t:string; begin
for n:=10 to 99 do begin
str(n,s);
t:=s+s[2]+s[1]; write(s:6); end; end.
上述两个程序,哪个快,哪个慢?
第八章、自定义函数和过程
PASCAL语言提供了大量的标准函数及标准过程供我们直接使用,但有时我们也会用到非标准的函数或过程,尤其是在做递归、回溯、搜索问题时,使用PASCAL语言的自定义函数、过程功能,与BASIC相比,能帮我们节省至少一半以上的时间。同样一个搜索问题,用BASIC语言如果要2个小时编出程序,用PASCAL语言就可能不要1个小时。
第一节、自定义函数
自定义函数也是在程序头部说明,其本身就相当于一个小程序,也有其头部及主体。语法如下: FUNCTION 函数名(形式参数表):函数值的数据类型; 函数的头部(常/变量说明); BEGIN 函数语句;(其中一定要有一句对函数名的赋值) END; {注意:这里是分号}
以上整个部分都位于程序的头部。自定义函数由“FUNCTION”引导,名称自定,形式参数表是指一个函数要求输入的参数(如:ABS(3.12),括号中的3.12就是形式参数),而每一个函数都是得到具体的值,所以也必须要说明该函数的值(即结果)的数据类型。
函数定义好后,就可在程序中调用,调用时和调用标准函数方法一样,都是把函数作为表达式或表达式中的一部分,放在赋值语句中或直接放在输出语句中。
[例7、1]编一程序,求两个自然数的最大公约数。 Var n,m:integer; 说明程序主体中的两个变量M,N Function num(a,b:integer):integer; 定义一个函数NUM,要求输入两个形式参数,值Var c:integer; 为整数 Begin 说明只在函数中用到的变量C If a>b then c:=b else c:=a; 函数主体开始 C:=c+1; Repeat C:=c-1; Until (a mod c=0) and (b mod c=0); Num:=c; End; 在函数语句中必不可少的一句:对函数名赋值 Begin 函数结束 Write(?please input 2 numbers:?); 程序主体开始 Readln(m,n); Writeln(num(m,n));
27
PASCAL语言基础及基础训练 第 28 页 共 48页
End. 在WRITELN语句中调用NUM函数 程序主体结束 在上述程序头部,定义了一个名为NUM的函数,所以在程序主体中,我们就可以随时调用它了。但一定要注意:在函数程序语句中一定要对函数名赋值,否则,该函数是无效的。另外:输入的数值的类型一定要和形式参数的类型相同。
两个重要概念:全局变量、局部变量
全局变量是在程序主体的头部说明的变量,是可以在程序的各个部分(包括主体、自定义函数、自定义过程)直接使用的。
局部变量是在程序的自定义函数或自定义过程的程序头部说明的变量,它们只能在所在的函数或过程中使用,不能在程序的其它部分使用。
如上述程序中的变量M,N就是全局变量,而变量C就是局部变量。A,B是形式参数(数值参数),是常量而不是变量。
所以,大家在编写PASCAL程序时一定要注意变量的命名,全局变量与局部变量不要取相同的名称。
递归函数
递归函数是PASCAL语言编程中通向高级算法的必由之路,要掌握递归函数必须要先掌握递归这个概念。
什么是递归呢?我们来看一个例题,在此之前我们先学会什么是数列。数列即一序列数的总称,如:1,2,3,4,5,6,7,8??是自然数数列;2,4,6,8,10,??是自然偶数数列;象这种以某种关系定义的数的序列就叫数列。数列的名称可任取,象上述第一个数列如果名为A,第二个数列名为B,则第一个数列的各个数字的名字就为:A1,A2,A3,A4??或A(1),A(2),A(3)??。数列A的数字关系是:(1)A(N)=A(N-1)+1(N>1);(2)A(1)=1;由此两个关系,我们只要知道该数列中任何一个数的序号,就可推知该数的数值。
那么如果对于数列A,我想知道A(100)是多少该如何推算呢? 由上述关系我们已经知道:
A(100)=A(99)+1,即要知道A(100),我们就必须先知道A(99);而 A(99)=A(98)+1;即要知道A(99)就必须先知道A(98);由此类推 A(98)=A(97)+1; ??????
A(3)=A(2)+1;
A(2)=A(1)+1;而此时就已经不用继续推算下去了,因为A(1)是已知的了。
而实际上,上述推算过程就是递归过程。即要完成某个计算,必须先完成其前的另一个计算,以此类推,直到推到一个已知的值为止。
[例7、2]有一个数列N,已知:N(1)=1,N(X)=N(X-1)*3-1(X>1),求N(100); 我们已经知道,由递归关系,我们要求N(100),就必须知道N(99)??N(1),而最终N(1)是已知的,所以这个递归关系我们就可以用PASCAL语言很好地表现出来。以下我们用递归函数来完成,请大家注意递归的实现方法,即自己调用自己。 Var n100:integer; 定义程序主体中的变量 Function dg(n:integer):integer; 定义自定义函数DG,形式参数1个,用以记录现在Begin 是推算到了第几个数。 If n:=1 then dg:=1 递归出口是当N等于1时,DG的值为1 Else begin Dg:=dg(n-1)*3-1; 如果N不等于1,我们就继续递归,这就是递归关 End; 系式 End; Begin N100:=dg(100); 程序主体 Writeln(n100); 调用递归函数 End. 由上可以看出,用递归函数来实现算法,程序主体可以变得非常简单,只需少数几句即可。而递归函数就显得至关重要了,由上述程序可以看出,递归函数的实现实际上就是一个自己调用自己
28
PASCAL语言基础及基础训练 第 29 页 共 48页
的函数。直到调用到已知的数为止。递归问题我们还将在递归过程中详细分析。
由上可见,递归过程实际上只有一句,IF 条件 THEN 出口 ELSE 调用下一次递归;
第二节、自定义过程
我们已经学过很多的标准过程,如:WRITE,READLN,STR等等,这些都是PASCAL的标准过程,我们可以随时调用。但有的时候,我们在程序中的不同地方会用到相同的一些语句,这时,我们就会把这些语句组合成一个自定义过程,以便在不同地方调用,这样,就可以节省大量的时间。并且,利用自定义过程,我们能够非常简单的实现递归、回溯。
自定义过程的说明语法如下(在程序头部说明): procedure 过程名(形式参数表); 过程变量(局部变量)说明部分; begin
语句体;
end; {此处是分号!}
自定义过程的调用语法如下: 过程名(数值参数表);
自定义过程实际上就是一个小的程序,只不过是划分开来,成为一个过程,然后在程序主体中以过程名来调用这些语句。
自定义过程的形式参数与自定义函数的用法一样,是输入过程中要用到的不同的输入值。如果过程中不要用到形式参数值,那么在说明过程的时候,过程名后面就不用加括号来说明形式参数。
[例7、3]编写一个程序,在屏幕上打印以下图形。 $$$$$ $$$$$ $$$$$ $$$$$ $$$$$
分析,我们已经编写过类似的程序,这里我们将用一个过程来打印每一行的五个“$”号。只不过每一行开头的位置不同,所以我们把控制开头位置的数值做为一个形式参数,另外,把每行要把多少个“$”也作为形式参数之一。 Var I:integer; Procedure printrow(n,m:integer); 形式参数N控制每行前多少个空格,M为每行多少Var r:integer; 字符 Begin Write(? ?:n); For r:=1 to m do begin 打印每行前N个空格 Write(?$?); 每行打印M个字符 End; Writeln; End; Begin For I:=1 to 5 do begin Printrow(I,5); End; 输入数值参数,每行前I个空格,每行5个字符 End. 上述过程中我们只有两个需输入的参数,有时我们的过程中也会用到输出的参数,如STR(N,S)过程,N是输入的参数,而S是输出的参数,即输入N转化为字符串S输出。这种有输出参数的过程在形式参数说明中有所不同,即输出参数要用VAR来引导。下例就是这种情况。
[例7、4]编写一个程序,求X的N次方。 我们知道,PASCAL语言中没有求乘方的标准函数或过程,这里我们将自己编一个求乘方的过程,
29
PASCAL语言基础及基础训练 第 30 页 共 48页
而该过程的形式参数就必须有两个输入参数,另外,我们计算出的幂值必须输出到一个变量中,这个变量也必须放在形式参数中,只不过这个参数与输入参数是不同的,所以必须以VAR引导加以说明,程序如下: Var x,n:integer; 说明主程序中要用到的X,N变量; C:longint; 说明乘幂C,用长整数型 Procedure cm(a,b:integer;var d:longint); 过程CM,二个输入函数,D为输出变量 Var I:integer; Begin D:=1; For I:=1 to b do begin D:=d*a; End; End; Begin 程序主体开始 Write(?please input x,n: ?); Readln(x,n); Cm(x,n,c); 调用CM过程,输入X,N,输出为C Writeln(c); End. 请大家一定要看懂得上述程序的形式参数部分,分清其中的输入与输出参数。
递归过程
我们从一个例题中来看看递归的实际实现及运行过程。 [例7、5]打印‘A’、‘B’、‘C’、‘D’、‘E’这五个字符任意排列的所有情况。
分析,此题可用五重循环来做,但那样就把此题给复杂化了,运行速度也要慢很多,而此题用递归过程来做的话就要简单许多。我们把递归过程定为每次从五个字符中取一个字符,当然这个字符必须与已经取得的字符全不相同,而我们取得的字符存放在一个字符串中,并把它作为形式参数(这一点至关重要,否则答案将完全错误)。当我们已经取完五个字符后,在取第六个字符时,递归过程就将结束。这就是递归的出口。这样我们就能把所有结果找出来。程序如下: Var t:longint; 计算答案总数的计数器 Procedure dg(n:integer;s:string); 递归过程有两个形式参数,N表示当前取第N个Var I:char; 字符,S存放已经取得的N-1个字符; Begin If n=6 then begin N等于6时,递归到了一个答案 T:=t+1; 答案总数加1 Writeln(t:5,? ?,s); 把答案数及答案打印出来 End else begin 从此句中返回调用此过程的上一过程 For I:=?A? to ?E? do begin 从A—E五个字符中取一个 If pos(I,s)=0 then begin 如果这个字符在已经取得的N-1个字符中没有出 Dg(n+1,s+I); 现 End; 就调用下一次递归,即调用自己,只不过参数NEnd; 变为N+1,即下次将取第N+1个字符(相对于当 End; 前来说),而输入的S参数也变为已经加入第N个End; 字符的新字符串。 Begin T:=0; Dg(1,??); 程序主体开始 End. 答案总数初值为0 调用递归过程,输入值1表示要找第1个字符,??表示已经找到的0个字符 上述程序的运行过程如下:
30
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库PASCAL语言基础总成含题目(6)在线全文阅读。
相关推荐: