信息学奥林匹克竞赛教程

第一课初识Pascal语言

信息学奥林匹克竞赛是一项益智性的竞赛活动,核心是考查选手的智力和使用计算机解题的能力。选手首先应针对竞赛中题目的要求构建数学模型,进而构造出计算机可以接受的算法,之后要写出高级语言程序,上机调试通过。程序设计是信息学奥林匹克竞赛的基本功,在青少年朋友参与竞赛活动的第一步必须掌握一门高级语言及其程序设计方法。

一、Pascal语言概述

PASCAL语言也是一种算法语言,它是瑞士苏黎世联邦工业大学的N.沃思(NiklausWirth)教授于1968年设计完成的,1971年正式发表。1975年,对PASCAL语言进行了修改,作为“标准PASCAL语言”。

PASCAL语言是在ALGOL60的基础上发展而成的。它是一种结构化的程序设计语言,可以用来编写应用程序。它又是一种系统程序设计语言,可以用来编写顺序型的系统软件(如编译程序)。它的功能强、编译程序简单,是70年代影响最大一种算法语言。

二、Pascal语言的特点

从使用者的角度来看,PASCAL语言有以下几个主要的特点:

⒈它是结构化的语言。PASCAL语言提供了直接实现三种基本结构(顺序、分支、循环)的语句以及定义“过程”和“函数”(子程序)的功能。可以方便地书写出结构化程序。在编写程序时可以完全不使用GOTO语句和标号。这就易于保证程序的正确性和易读性。PASCAL语言强调的是可靠性、易于验证性、概念的清晰性和实现的简化。在结构化这一点上,比其它(如BASIC,FORTRAN77)更好一些。

⒉有丰富的数据类型。PASCAL提供了整数、实型、字符型、布尔型、枚举型、子界型以及由以上类型数据构成的数组类型、集合类型、记录类型和文件类型。此外,还提供了其它许多语言中所没有的指针类型。沃思有一个著名的公式:"算法+数据结构=程序"。指出了在程序设计中研究数据的重要性。丰富的数据结构和上述的结构化性质,使得PASCAL可以被方便地用来描述复杂的算法,得到质量较高的程序。

⒊能适用于数值运算和非数值运算领域。有些语言(如FORTRAN66,ALGOL60)只适用于数值计算,有些语言(如COBOL)则适用于商业数据处理和管理领域。PASCAL的功能较强,能广泛应用于各种领域。PASCAL语言还可以用于辅助设计,实现计算机绘图功能。⒋PASCAL程序的书写格式比较自由。不象FORTRAN和COBOL那样对程序的书写格式有严格的规定。PASCAL允许一行写多个语句,一个语句可以分写在多行上,也不区分大小写,这样就可以使PASCAL程序写得象诗歌格式一样优美,便于阅读。

由于以上特点,许多学校选PASCAL作为程序设计课程中的一种主要的语言。它能给学生严格而良好的程序设计的基本训练。培养学生结构化程序设计的风格。但它也有一些不足之处,如它的文件处理功能较差等。

三、Pascal语言程序的基本结构

任何程序设计语言都有着一组自己的记号和规则。PASCAL语言同样必须采用其本身所规定的记号和规则来编写程序。尽管不同版本的PASCAL语言所采用的记号的数量、形式不尽相同,但其基本成分一般都符合标准PASCAL的规定,只是某些扩展功能各不相同罢了。下面我们首先来了解Pascal语言的程序基本结构。

为了明显起见先举一个最简单的PASCAL程序例子:【例1】

从这个简单的程序可以看到:

⒈一个PASCAL程序分为两个部分:程序首部和程序体(或称分程序)

⒉程序首部是程序的开头部分,它包括:

⑴程序标志。用“program”来标识“这是一个PASCAL程序”。PASCAL规定任何一个PASCAL程序的首部都必须以此字开头。在turbopascal语言中,首部也可省略。

⑵程序名称。由程序设计者自己定义(但受一些规则限制),如例中的exam1。

注:在写完程序首部之后,应有一个分号。

⒊程序体是程序的主体,在有的书本里也称“分程序”。程序体包括说明部分(也可省略)和执行部分两个部分。

⑴说明部分用来描述程序中用到的变量、常量、类型、过程与函数等。本程序中第二行是"变量说明",用来定义变量的名称、类型。

PASCAL规定,凡程序中用到所有变量、符号常量、数组、标号、过程与函数、记录、文件等数据都必须在说明部分进行定义(或称“说明”)。也就是说,不允许使用未说明先使用。

⑵执行部分的作用是通知计算机执行指定的操作。如果一个程序中不写执行部分,在程序运行时计算机什么工作也不做。因此,执行部分是一个PASCAL程序的核心部分。

执行部分以“begin”开始,以“end”结束,其间有若干个语句,语句之间以分号隔开。

注:执行部分之后有一个句点,表示整个程序结束。

⒋PASCAL程序的书写方法比较灵活。当然,书写不应以节省篇幅为目的,而应以程序结构清晰、易读为目的。在编写程序时尽量模仿本书中例题程序格式。

⒌在程序中,一对大括号间的文字称为注释。注释的内容由人们根据需要书写,可以用英语或汉语表示。注释可以放在任何空格可以出现的位置。执行程序时计算机对注释不予理睬。

四、TurboPascal语言系统的使用(FreePascal与之类似)

目前,常用的Pascal语言系统有TurboPascal7.0、BorlandPascal7.0、

FreePascal1.0.10,下面我们就来学习TurboPascal7.0系统的使用。

1.系统的启动(上面的这几个版本都可在DOS、WINDOWS下使用)

方式一:只适合在WINDOWS下,在桌面上建立快捷方式,然后双击快捷方式即可

方式二:进入相应的系统目录下,执行主程序(TurboPascal的主程序为TURBO.EXE;FreePascal的主程序为FP.EXE),具体的操作步骤如下

进入DOS命令行(这是在WIDOWS下要做的,WIN98及以前的版本是在“运行”窗口中输入COMMAND命令;WINXP及以上版本是在“运行”窗口中输入CMD命令)

输入以下命令行即可启动相应的编译集成环境:

cd\tp\bin{进入主程序所在的文件夹,Freepascal是cd\pp\bin\go32v2}turbo{Freepascal是fp}

系统启动后,屏幕上出现如图1所示的集成环境。

2.TurboPascal系统集成环境简介

最顶上一行为主菜单。中间蓝色框内为编辑窗口,在它个编辑窗口内可以进行程序的编辑。最底下一行为提示行,显示出系统中常用命令的快捷键,如:将当前编辑窗口中文件存盘的命令快捷键为F2,获得系统帮助的快捷键为

F1,等等。

3.新建程序窗口

按F10进入主菜单,选择FILE菜单,执行其中New命令。就可建立一个新的程序窗口(默认文件名为Noname00.pas或Noname01.pas等)。

4.程序的输入、编辑与运行

在当前程序窗口中,一行一行的输入程序。事实上,程序窗口是一个全屏幕编辑器。所以对程序的编辑与其它编辑器的编辑方法类似,这里不再重复。

当程序输入完毕之后,一般要先按Alt+F9(或执行compile菜单中compile命令)对程序进行编译。如果程序有语法错误,则会在程序窗口的第一行处显示第一个红色错误信息。若无语法错误,则窗口正中央会出现一个对话框,提示编译成功。接下来,我们可以运行程

序了。

程序的运行可以通过按ALT+R打开RUN菜单中的RUN命令,或直接按快捷键CTRL+F9。则可以在用户窗口中输出运行结果。通常在程序运行结束后系统回到Pascal系统的集成环境,因此要查看运行结果,要按ALT+F5将屏幕切换到用户屏幕。

5.程序的保存与打开

当我们想把程序窗口中的程序存入磁盘时,可以通过按F2键(或执行File菜单中的save命令)来保存程序。第一次保存文件时屏幕上会出现一个对话框要求输入文件名(默认扩展名为.pas)。

当我们要将磁盘上的程序文件中的PASCAL程序装入窗口时,可按F3(或执行File菜单中的Open命令)来装入程序,此时系统也会弹出一个对话框要求输入要打开的文件名,或直接在文件对话框列表中选择所要的文件,然后回到打开文件。

6.退出TurboPascal:直接按组合键ALT+X或选择“File”菜单中的“Exit”

五、第一个程序

为让大家了解程序设计的基本过程(编辑→编译/解释→连接→运行),请大家输入下面的程序并运行,学会用自己的描述它的功能是什么?

programsample;

var

i,n,number:integer;

begin

write('Number=');

readln(number);

fori:=1tonumberdo

begin

ifimod2=1then

begin

forn:=1to(number-i)div2dowrite('');

forn:=1toidowrite('*');

writeln;

end;

end;

readln

end.

请输入上面的程序,将其存盘、关闭。然后再打开并运行序。(中途要在不退出Pascal的情况下进入命令行状态查看程序的运行结果,可以选择“File”菜单中的“Commandshell”,TurboPascal为“Dosshell”,返回请输入EXIT命令,不分大小写。

作业:模仿本课中出现的例程及学到的知识,完成下列编程任务

1.提示用户输入圆的半径,计算并输出圆的周长

2.提示用户输入两个数,计算并输出这两个数的和

第二课赋值语句、输出语句

上节课,我们学习了Pascal语言的程序基本结构,在一个程序中,所有的操作都由执行部分来完成,而执行部分又都是由一个个语句组成的。因此,下面开始我们要学习pascal语言的基本语句,并且在学习过程中逐步学会程序设计的基本方法。

这节课我们要学习两种语句,即赋值语句与输出语句。在语句学习之前我们要先了解一些pascal语言的基础知识。

一、常量、变量与算术表达式

(一)常量:在程序运行过程中,其值不能被改变的量称为常量。如123,145.88,'abc',true等。

1、整型常量:整型常量采用我们平常使用的十进制整数表示,包括正整数、负整数和零。如:138,0,-512等都是整型常量,而18.或18.0都不是整型常量。pascal中有一个标准标识符Maxint,它代表所使用的计算机系统允许的最大整型数,而最小的整型数即为-Maxint-1;TurboPascal还定义了长整数常量MaxLongInt,其值为2147483647。

注:计算机系统能表示的整型数的范围取决于其字长,如:现在大部分机器的字长字长为16,它们所能支持的整型数的范围为+215至-215-1,即-32768至+32767,这里涉及到有符号数和补码方面的知识;要想知道你所使用的计算机所能表示的整型数的范围,用这样的语句就可以知道了:WRITE(-maxint-1,'',maxint)

2、实型常量:包括正实数、负实数和实数零,其实就是常说的小数,pascal中表示实型常量的形式有两种。

⑴十进制表示法:这是人们日常使用的带小数点的表示方法,如0.0、-0.0、+5.61、-8.0、-6.050等都是实型常量,而0.、.37都不是合法的实数形式

⑵科学记数法:采用指数形式的表示方法,如1.25×105可表示成1.25E+05。在科学记数法中,字母"E"表示10这个"底数",而E之前为一个十进制表示的小数,称为尾数,E之后必须为一个整数,称为"指数"。如-1234.56E+26、+0.268E-5、1E5是合法形式,而.34E12、

2.E5、E5、E、1.2E+0.5都不是合法形式的实数。

无论实数是用十进制表示法还是科学表示法,它们在计算机内的表示形式是一样的,总是用浮点方式存储。

和整数相比,实数能表示的范围大得多,但值得注意的是实数的运算比整数的运算速度慢且无法像整数那样精确表示,只能近似表示。

3、字符常量:在Pascal语言中,字符常量是由单个字符组成,所有字符来自ASCII字符集,共有256个字符。在程序中,通常用一对单引号将单个字符括起来表示一个字符常量,如:'a','A','0'等;特殊地,对于单引号字符,则要表示成''''。对于ASCII字符集中,按每个字符在字符集中的位置,将每个字符编号为0-255,编号称为对应字符的序号,因此字符也存在大小,如:'A''a'

4、布尔常量:布尔型常量仅有两个值,真和假,分别用标准常量名true和false表示,它们的序号分别为1和0。

5、符号常量:它是由程序员自己定义的,一个常量即可以直接用字面形式表示(称为直接常量,如124,156.8),也可以用一个标识符来代表一个常量,称为"符号常量"。但符号常量必须在程序中的说明部分定义,也就是说先定义,后使用。

定义符号常量的一般格式:CONST=;如:

CONSTPI=3.1415926;

E=2.71828;

说明:常量说明部分以关键字const开头,后面的标识符为常量标识符,其中"="号后的常量为整数、实数、字符、字符串(字符串常量在后面章节中将作介绍);而且在常量说明部分可以将几个常量说明成符号常量,共用一个关键字"const",例如:

则在本程序中pi和zero作为符号常量,分别代表实数3.14159和整数0;也就是说,常量说明部分既定义了常量名及其值,又隐含定义了常量的类型。

关于符号常量,应注意下列几点:

⑴、符号常量一经定义,在程序的执行部分就只能使用该常量标识符,而不能修改其值⑵、使用符号常量比直接用数值更能体现"见名知义"的原则,也便于修改参数,故一个较好的程序中,应尽量使用符号常量,在执行部分基本上不出现直接常量。

(二)变量:变量代表了一个存储单元,其中的值是可变的,故称为变量。如游戏"魂斗罗"中玩者命的个数最初为3,当你死了一次命减少一,这里命的个数就是一个变量(或者说命的个数存储在一个存储单元中)。即在程序运行过程中,其值可以改变的量,称为变量。

变量有三个要素是:变量名、变量类型、变量值

一个程序中可能要使用到若干个变量,为了区别不同的变量,必须给每个变量(存贮单元)取一个名(称为变量名),该变量(存贮单元)存放的值称为变量的值,变量中能够存放值的类型为变量的类型。例如"魂斗罗"游戏中用于存放"命"的变量,在游戏程序中的名字可取为N,它的类型为整型,游戏初始时这个变量的值为3

1.变量名:用一个合法的标识符代表一个变量。如n,m,rot,total等都是合法变量名。在程序中用到的变量必须在说明部分加以说明,变量名应遵循自定义标识符的命名规则,并注意“见名知义”的原则,即用一些有意义的单词作为变量名

“自定义标识符”的命名规则为:自定义标识符必须以字母(包含下划线"_")开头,后面的字符可以是字母或数字,标识符长度不超过63个字符

2.变量的类型:常量是有类型的数据,变量在某一固定时刻用来存放一个常量,因此也应有相应的类型;如整型变量用来存放整数,实型变量用来存放实数;也就是说,变量的类型取决于将要存放的数据的类型,并且其类型一旦定义了,就不能再改变,也不能把其他类型的数据赋给它

3.变量说明:在程序中若要使用变量,变量的名称及类型在程序的变量说明部分加以定义,变量的值则在程序的执行部分中才能赋给,变量说明的一般格式:VAR[,]:;(中括号内部分表示可省,下同)

其中VAR是pascal保留字,表示开始一个变量说明段,每个变量标识符或由逗号隔开的多个变量标识,必须在它的冒号后面说明成同一类型。一个程序中,可以说明许多不同类型的变量,每种类型变量之间用分号隔开,共用一个VAR符号。例如:

var

age,day:integer;

amount,average:real;

其中:Integer(整型)、Real(实型)、Boolean(布尔型)、Char(字符型)是标准标识符,

它们是"类型标识符",代表了确定的类型,如age和day被定义为整型变量,amount和average被定义为实型变量。

一旦定义了变量,就确定了它的类型,也就是说,就确定了该变量的取值范围和对该变量所能进行的运算。

(三)算术表达式

⑴算术表达式的定义:pascal语言中的算术表达式是由符合pascal语法规定的运算对象(包括常量、变量、函数)、算术运算符、圆括号组成的有意义的式子。如:

A+3.14159*5/8.4-Abs(-1123)

⑵算术运算符,常用的有以下6个算术运算符:

①+(加)

②-(减)

③*(乘)

④/(实数除)得到结果为实型.如5.0/2.0=2.5,5/2=2.5,4/2=2.0而不等于2。⑤DIV(整除)DIV它要求除数和被除数均为整型,结果也为整型。如10DIV2=5,10DIV3=3,5DIV10=0.-15DIV4=-3,DIV运算只取商的整数部分,参与DIV运算的两个对象不能为实型

⑥mod(求余),也只能用于整数运算,结果为整数。例如:10mod4=2,-17mod4=-1,4mod(-3)=1,-4mod3=-1,即amodb=a-(adivb)*b

(3)运算优先顺序,如果一个表达式里出现两个或两个以上的运算符,则必须规定它们的运算次序,pascal规定

①表达式中相同优先级的运算符,按从左到右顺序计算

②表达式中不同优先级的运算符,按从高到低顺序计算

③括号优先级最高,从内到外逐层降低

在算术运算中运算符的优先顺序与数学上的四则运算一致,即“先乘除后加减”(注:MOD、DIV运算的优先级与*、/相同)

二、赋值语句

变量既然代表一个存储单元,其值是可变的,那么其中的值是怎么提供的,又是怎么改变的呢?可以通过赋值语句来进行

1、赋值语句的格式

变量名:=表达式;

其中“:=”称为赋值号,是赋值语句的标志

2、执行过程:计算机先计算赋值号右边表达式的值,然后将表达式的值赋给变量名代表的变量,如:

A:=(9*8)-(2-1);

A:=A+1;

最后A的值为72

三、输出语句

输出语句的作用是将程序运算的结果输出到屏幕或打印机等输出设备,这里通常是指输出到屏幕。

(一)输出语句的两种格式

1、write语句

格式:Write(表达式1,表达式2,……);

如:write(1,2,3,4);

write(1.2,3.4,5);

write('MynameisLiping');

2、writeln语句

格式:Writeln(表达式1,表达式2,……)或writeln

(二)输出语句的功能

计算机执行到某一输出语句时,先计算出输出语句中的每个表达式的值,并将每一个表达式的值一个接一个地输出到屏幕上。

Write语句与writeln语句格式上都相似,但它们在功能上有所不同,两个语句的区别在于,write语句将其后括号中的表达式一个接一个输出后,没有换行;而writeln语句则在输出各个表达式的值后换行,例如以下两个程序段的输出分别为:

write(1,2,3,4);

write(5,6);

输出为:

123456

writeln(1,2,3,4);write(5,6);

输出为:

1234

56

四、应用例析

例1:某仓库5月1日有粮食100吨,5月2日又调进20吨,5月3日卖出库存的3分之二,5月4日又调进库存的3倍粮食,问该仓库从5月1日到5月4日期间每天的粮食分别是多少吨?(输出每天的库存量)

分析:在这个问题中,主要要描述从5月1日到5月4日期间仓库的粮食库存量,且易知它是不断变化的。因此我们可以用一个变量A来描述仓库的粮食库存量

程序可写如下:

Programex1;

Var

A:integer;

Begin

A:=100;

Writeln('5/1:',A);

A:=A+20;

Writeln('5/2:',A);

A:=Adiv3;

writeln('5/3:',A);

A:=A*4;

writeln('5/4:',A);

Readln;

第三课带格式的输出语句及输入语句

一、写语句(WRITE、WRITELN)的输出格式

在pascal语言中输出数据时是可以按照一定格式的,对整数隐含的输出形式为按十进制数形式;对实数的输出,隐含的形式是科学记数法形式(如果不想用科学记数法输出而用

小数形式输出,要自己另行定义)。

事实上,输出语句中的每个输出项中的表达式之后可以加上格式说明,若输出项后没有加格式说明,则数据按系统隐含的格式输出,还可加上一定格式符号按特定格式输出。

1、隐含的输出格式

pascal语言为整型量、实型量、布尔型量和字符串(用一对单引号括起来的字符序列)规定了每种数据所占的宽度(即一个数据占几列),一个数据所占的宽度称为“场宽”或“字段宽”;系统给出的隐含场宽称为标准场宽,每一种pascal版本给定的标准场宽不尽相同,下表给出标准pascal、Turbopascal、FreePascal所规定的标准场宽标准场宽

数据类型

integer

real

布尔型

字符串标准pascal102210串长TurboPascal实际长度174或5串长FreePascal实际长度254或5串长

在TurboPascal系统中,对于整型字符串的输出都是按数据本身长度输出,对于

布尔型数据(只有True和False两种值),TRUE为4列,FALSE为5列,一律采用大写输出。而real型数据的输出时,则按17列输出,其中第一列为符号位,正号不显示,后四位为"E±nn",中间的12列为尾数部分。如:(□代表一个空格)

语句

TurboPascal

结果

FreePascal

结果WRITELN(2.367)□2.36700000E+0001□2.[**************]0E+0001WRITELN(67)6767WRITELN(TRUE)TRUETRUEWRITELN('ACDE')ACDEACDE

有时,在程序中往往根据实际情况,需要自己定义场宽。

2、指定场宽(自己定义场宽):在写语句中输出项含有格式符号时,就是为了指

定场宽

⑴指定单场宽

格式:write(表达式:N)或writeln(表达式:N),其中N为自然数,指定单场宽后,所有数据不再按标准场宽输出,而按指定场宽输出;若数据实际长度小于指定场宽时,则一律“向右靠齐,左留空格”。

如write(1234:8);write('abcdef':12)

输出结果:

□□□□1234□□□□□□abcdef

对于标准实型数据指定单场宽时,如果场宽大于标准场宽时,右靠齐按标准场宽格式输出17位,左留空格。若场宽小于标准场宽时,第一位仍为符号位,最后四位仍为“E±nn”,中间部分为尾数显示部分;如果指定的宽度小于8位,则数据按8位格式“*.*E±nn”输出

⑵指定双场宽

如果输出项是实数时,如果希望输出的实数不用科学记数法输出,而用小数形式输出,可以用指定双场宽方法输出,双场宽输出格式为:write(实型表达式:m:n),其中m和n都是自然数,m用以指定整个数据所占的宽度,n指定输出实数的小数位数,如:

write(sqrt(75):9:4);

输出:□□□8.6602

如果双场宽不能满足输出数据的最低要求,系统自动突破指定的场宽限制,按实际长度输出,如:write(sqrt(75):5:4);要使小数点后有4位数字,而总场宽为5,是不可能的(因为还有一个小数点,小数点前面还有一个数字),它最低限度要有6列,即输出为:

8.6602(舍弃超过场宽的数据坚持四舍五入原则)

例1:写出下列程序在turbopascal下的输出结果

programex;

consts='abcdefg';

var

i:integer;

r:real;

c:char;b:boolean;

begin

i:=1234;

r:=1234.5678;

c:='#';

b:=true;

writeln(i,i:6,i:3);

writeln(r,r:12:5,r:8:5,r:8:3);

writeln(c,c:5);

writeln(s,s:10,s:5);

writeln(b,b:5,b:3);

end.

运行结果如下:

1234□□12341234

□1.2345678000E+03□□1234.567801234.567801234.568

#□□□□#

abcdefg□□□abcdefgabcdefg

TRUE□TRUETRUE

3、应用例析

例2:已知A=253,B=43,输出A*B的运算式子,即输出如下

□□□□□□□253*43=10879

□□□□□□□□□253

□□□□□□□*□□43

□□□□--------

□□□□□□□□□759

□□□□□+□1012

□□□□--------

□□□□□□□10879

分析:对于该问题,我们只要控制好输出时右靠齐即可。即前四行的总宽度一样(例如为12),第五行总宽度比前面少1。第六、七行总宽度与前四行一样。

参考程序如下:

var

a,b:integer;

begin

a:=253;b:=43;

writeln(a:10,'*',b,'=',a*b);writeln(a:12);

write('*':8);writeln(b:4);writeln('--------':12);writeln(a*3:12);

write('+':6);writeln(a*4:5);writeln('--------':12);writeln(a*b:12);end.

二、输入语句(读语句READ、READLN)在程序中变量获得一个确定的值,固然可以用赋值语句,但是如果需要赋值的变量较多,或变量的值经常变化,则使用本节介绍的输入语句─读语句,将更为方便。读语句是在程序运行时由用户给变量提供数据的一种很灵活的输入动作,它有两种格式:

read();readln[()];

其中变量名表是用逗号隔开的若干个变量名组成的。

功能:从标准输入文件(即INPUT,一般对应着键盘)中读入数据,并依次赋给相应的变量

说明:①、read和readln是标准过程名,它们是标准标识符

②、执行到read或readln语句时,系统处于等待状态,等待用户从键盘上输入数据,

系统根据变量的数据类型的语法要求判断输入的字符是否合法。如执行read(a)语句,a是整型变量,则输入的字符为数字字符时是合法的,当输入结束时,则自动将刚接受的一串数字字符转换为整数赋给变量a

③、在输入数值型(整型或实型)数据时,数据间要用空格或回车分隔开各个数据,

输入足够个数的数据,否则仍要继续等待输入,但最后一定要有回车,表示该输入行结束,直到数据足够,该读语句执行结束,程序继续运行

例3:设a、b、c为整型变量,需将它们的值分别赋以10、20、30,写出对应下列语句的所有可能输入格式

Read(a,b,c);

解:根据③,即可列出所有可能输入格式(a)10□20□30←┘(b)10□20←┘

30←┘(c)10←┘

20□30←┘(d)10←┘

20←┘30←┘

其中"←┘"表示回车键,下同

④、read语句与readln语句的第一个区别是:read语句是一个接一个地读数据,在执行完本Read语句(读完本语句中变量所需的数据)后,下一个读语句接着从该数据输入行中继续读数据,也就是说,不换行。如:

Read(a,b);Read(c,d);Read(e);

如果输入数据行如下:1□2□3□4□5□6□←┘

则a,b,c,d,e的值分别为1,2,3,4,5,如果后面无读语句则数据6是多余的,这是允许的。Readln则不同,在读完本Readln语句中变量所需的数据后,该数据行中剩余的数据多余无用,或者说,在读完本Readln语句中变量所需数据后,一定要读到一个回车,否则多余的数据无用

例4:设要达到例1同样的目的,但语句改为readln(a,b);readln(c);

则例3中的4种输入格式只有(b)(d)是有效的

⑤、readln语句与read语句的第二个区别是:read后一定要有参数表,而readln可以不带参数表,即可以没有任何输入项,只是等待读入一个换行符(回车),经常用于暂停程序的运行,直到输入一个回车

例5:设有下列语句read(a,b,c);readln(d,e);readln;

第四课简单的分支结构程序设计

在现实生活中,我们每天都要进行根据实际情况进行选择。例如,原打算明天去公园,但如果明天天气不好,将留在家里看电视,所以人也会根据条件进行行为的选择;计算机也会根据不同情况作出各种逻辑判断,进行一定的选择。在这课与下一课中,我们将会发现,我们是通过选择(分支)结构语句来实现程序的逻辑判断功能。

一、PASCAL中的布尔(逻辑)类型

在前面,我们学习了整型(integer)与实型(real),其中integer型数据取值范围为

-3838

-32768到32767之间所有整数。而real型数据取值范围为其绝对值在10到10之间的所有实数,它们都是数值型的(即值都为数);布尔型(Boolean)是一种数据的类型,这种类型只有两种值,即“真”与“假”

1、布尔常量:在Pascal语言中“真”用ture表示,“假”用False表示,所以布尔类型只有TRUE与FALSE两个常量;

2、布尔变量(BOOLEAN):如果我们将某些变量说明成布尔型,那么这些变量就是布尔变量,它们只能用于存放布尔值(ture或false),例如,VARA,B:BOOLEAN;

3、布尔类型是顺序类型:由于这种类型只有两个常量,Pascal语言中规定ture的序号为1,false的序号为0。若某种类型的常量是有限的,那么这种类型的常量通常都有一个序号,我们称这种类型为顺序类型;如前面我们学过的整型(integer),以及后面要学到的字符型(char)都是顺序类型;

4、布尔类型的输入与输出a)、输出

VARA,B:BOOLEAN;BEGIN

A:=TRUE;B:=FALSE;WRITELN(A,B);END.

结果:TRUEFALSE

b)布尔类型变量不能直接用读语句输入:布尔类型变量不能通过读语句给它们提

供值;事实上,我们可以通过间接方式对布尔变量进行值的输入,最常用的就是通过赋值语句

例如,以下程序是错误的vara,b,c:Boolean;begin

readln(a,b,c);{错误语句}writeln(a,b,c);end.又如:

vara:Boolean;begin

a:=3>7;{正确语句}writeln(a);end.

二、关系表达式与布尔表达式

1、什么是关系表达式:用小括号、>、=、将两个算术表达式连接起来的式子就称为关系表达式(比较式),如:3+7>8,x+y

2、关系表达式的值

很显然,上面几个关系表达式中第一个是真的,第三个是假的,而第二个表达式可能是真的,也可能是假的;所以我们很容易发现,这些表达式的值是"对"的或"不对"的(或者说,是"真"的或"假"的),即关系表达式的值为布尔值。表示该比较式两端式子的大小关系是否成立;如3+2>6是假的,故它的值为FALSE;同样,45>=32是对的,故该表达式的值为true说明:①对于>=、=5都是真的,即值为TRUE

②关系表达式可用于表示一个命题。如:“m为偶数”可表示为:mmod2=0。“n

为正数”可表示为:n>0

3、布尔运算及布尔表达式(也称逻辑运算及逻辑表达式):为了表示更复杂的命题,Pascal还引入三种逻辑运算符:not、and、or,它们分别相当于数学上的“非”、“且”和“或”的意义

这三个运算符的运算对象为布尔量,其中not为单目运算,只有一个运算对象,and与or为双目运算,有两个运算对象,它们的运算真值表如下:

afalsefalsetruetrue

bfalsetruefalsetrue

Notatruetruefalsefalse

aandbfalsefalsefalsetrue

aorbfalseturetruetrue

axorbfalsetruetruefalse

于是,一个或多个关系表达式用布尔运算符连接起来的式子就称为布尔表达式;布

尔表达式的值也为布尔值;根据上表我们可以总结各运算符的运算规则:

NOT:非运算,取反(原来为真,非后为假;原来为假,非后为真)

AND:与运算,同为真则为真,其余均为假(参加运算的两个对象同为真结果才为真,否则为假)

OR:或运算,只要有一个为真,结果就为真

XOR:同或运算,相同则为真,不同则为假(参加运算的两个对象相同就为真,不同则为假)

请算出后面表达式的值:'a'6)AND('B'>'A')(3*4>6)OR('B'6)AND('B'>'A')都是正确的表达式;

②用括号改变各种运算符的先后顺序是非常重要的,如:NOT'a'6AND('B'>'A')都是不正确的表达式,因为布尔运算比关系运算的优先级高,导制上面的表达式有语法错误,为什么错请想一想

③布尔运算符的运算级别为:NOT>AND>OR如:FALSEORNOTTRUEANDTRUE的值为FALSE,它等价于:FALSEOR((NOTTRUE)ANDTRUE)

如果一个表达式里出现两个或两个以上的运算符,则必须规定它们的运算次序,pascal规定:

①表达式中相同优先级的运算符,按从左到右顺序计算;②表达式中不同优先级的运算符,按从高到低顺序计算;③括号优先级最高,从内到外逐层降低;

对于一个复杂的表达式可能同时包含算术运算、关系运算和逻辑运算以及函数运算,运算的优先顺序为:括号>函数>NOT>*、/、div、mod、and>+、-、or、xor>关系运算(>、=、=、)

对于复杂的命题,我们可以用布尔表达式来表示。例如,命题:“m,n都是偶数或都是奇数”可表示为(mmod2=0)and(nmod2=0)or(mmod2=1)and(nmod2=1)

三、简单的IF语句1、格式

Ⅰ、IF<布尔表达式>THEN语句;

Ⅱ、IF<布尔表达式>THEN语句1ELSE语句2;注意:Ⅱ型IF语句中语句1后无“;”号

2、功能

Ⅰ、执行IF语句时,先计算<布尔表达式>的值,若为TRUE则执行语句,否则不执行任何操作;

Ⅱ、执行IF语句时,先计算<布尔表达式>的值,若为TRUE则执行语句1,否则执行语句2;

3、示例

1)例4.2:输入一个整数a,判断是否为偶数(是输出Yes,否则输出No)Programex4_2;Vara:integer;Begin

Write('a=');readln(a);

If(amod2=0)thenwriteln('Yes')Elsewriteln('No');Readln;

End.

2)华榕超市里卖电池,每个电池8角钱,若数量超过10个,则可打75折

Programex4_3;

VarNum:integer;Price,Total:real;Begin

Write('Num=');readln(Num);Price=0.8;

IfNum>10thenPrice:=Price*0.75;Total:=Num*Price;

Writeln('Total=',Total:0:2);Readln;End.

3)编写一与电脑猜"红"或"黑"的游戏分析:用1代表红,0代表黑。先由计算机先出答案,然后再由人猜,猜对输出"YOUWIN"否则输出"YOULOST";为了模拟猜"红"或"黑"的随意性,程序中需要用到随机函数random(n)

函数是什么呢,例如大家都知道|-2|=2,|58|=58,那么|x|=?

如果我们用y表示|x|,那么,这里y=|x|就是一个函数,也就是说函数是一个关于一个或多个自变量(未知量,如上例中的x)的运算结果

在pascal语言中,系统提供了许多内部函数,其中包括|x|函数,当然它用abs(x)表

2

示;我们如果要求X-Y的绝对值,可以调用内部函数abs(x*x-y)即可求得;Random(n)也是一个内部函数,调用它能得到0~n-1之间的整数(但它不确定的,或说是随机的);同时由于函数是一个运算结果,所以函数的调用只能出现在表达式中

Programex4_3;Usescrt;

VarComputer,People:integer;Begin

Randomize;

Computer:=random(2);

Write('Youguess(0-Red1-Black):');readln(People);IfPeople=Computerthenwriteln('YOUWIN')Elsewriteln('YOULOST');Readln;End.练习四:

1.某车站行李托运收费标准是:10公斤或10公斤以下,收费2.5元,超过10公斤的行李,按每超过1公斤增加1.5元进行收费。试编一程序,输入行李的重量,算出托运费。

2.利用本课的知识,将第三课练习的第2题作进一步完善,即:程序要能判断输入的三个边能不能构成三角形(有数小于等于零、两边之和不能大于第三边都不能构成三角形),若不能则提示输入的数据有误且不做任何计算;若能构成三角形就计算并输出其面积。

第五课If嵌套与Case语句

一、IF语句的嵌套

在if语句中,如果then子句或else子句仍是一个if语句,则称为if语句的嵌套;

例1:

计算下列函数

分析:根据输入的x值,先分成x>0与x≤0两种情况,然后对于情况x≤0,再区分x是小于0,还是等于0;

源程序如下:programex;var

x:real;y:integer;begin

wrtie('Inputx:');readln(x);

ifx>0theny:=1{x>0时,y的值为1}else{x≤0时}

ifx=0theny:=0elsey:=-1;writeln('x=',x:6:2,'y=',y);end.

显然,以上的程序中,在then子句中嵌套了一个Ⅱ型if语句,当然程序也可以写成如下形式:

programex;var

x:real;y:integer;begin

wrtie('Inputx:');readln(x);ifx>=0then

ifx>0theny:=1elsey:=0elsey=-1;

writeln('x=',x:6:2,'y=',y);end.

但是对于本题,下面的程序是不对的。y:=0;

ifx>=0then

ifx>0theny:=1elsey:=-1;

明显,从此人的程序书写格式可以看出,他想让else与第一个if配对,而事实上,这是错的。因为pascal规定:else与它上面的距它最近的then配对,因此以上程序段的逻辑意义就与题义不符。

要使上程序段中esle与第一个then配对,应将程序段修改为:y:=0;或者y:=0;ifx>=0thenifx>=0thenifx>0theny:=1begin

elsey:=-1;

end

elseY:=-1;

二、case语句

从上面我们知道可以用嵌套的if语句实现多分支的选择结构,但如果分支越来越多时,用嵌套的if语句实现多分支就显得繁杂。当多分支选择的各个条件由同一个表达式的不同结果值决定时,可以用case语句实现;它的选择过程,很象一个多路开关,即由case语句的选择表达式的值,决定切换至哪一语句去工作。因此在分支结构程序设计中,它是一种强有力的手段,在实现多路径分支控制时,用case对某些问题的处理和设计,比用if语句写程序具有更简洁、清晰之感。(一)、case语句的一般形式:

caseof

:语句1;:语句2;:

:语句nend;

其中case、of、end是Pascal的保留字,表达式的值必须是顺序类型,它可以是整型、布尔型及以后学习的字符型、枚举型和子界型;情况标号表是一串用逗号隔开的与表达式类型一致的常量序列,语句可以是任何语句,包括复合语句和空语句。(二)、case语句的执行过程

先计算表达式(称为情况表达式)的值,如果它的值等于某一个常量(称为情况常量,也称情况标号),则执行该情况常量后面的语句,在执行完语句后,跳到case语句的末尾end处。(三)、说明

①情况表达式必须是顺序类型的;

②情况常量是情况表达式可能具有的值,因而应与情况表达式具有相同的类型;③情况常量出现的次序可以是任意的;

④同一情况常量不能在同一个case语句中出现两次或两次以上;⑤每个分语句前可以有一个或若干个用逗号隔开的情况常量;

⑥如果情况表达式的值不落在情况常量的范围内,则认为本case语句无效,执行case语句的下一个语句,turbopascal中增加了一个“否则”的情况,即增加一个else子句,但也是可省的;

⑦每个常量后面只能是一个语句或一个复合语句;例2根据x的值,求函数Y

的值

分析:利用case语句进行程序设计,关键在于巧妙地构造情况表达式。本例中三种情况可用一个表达式区分出来:Trunc(x/100),因为x在(0~100)之间时表达式值为0,x在[100,200)时表达式值为1;其余部分可用else子句表示;

注:trunc()是一个用于返回整数部分的函数,如trunc(23.75)的值为23、trunc(-23467/100)的值为-234

programex;varx,y:real;

b:integer;begin

write('Inputx:');readln(x);

b:=trunc(x/100);casebof0:y:=x+1;1:y:=x-1;elsey:=0;

end;{endofcase}

writeln('x=',x:8:2,'y=',y:8:2);end.

三、选择结构的程序设计

例3、输入一个年号,判断它是否是闰年

分析:判断闰年的算法是,如果此年号能被400除尽,或者它能被4整除而不能被100整除,则它是闰年;否则,它是平年

源程序如下:programex;

varyear:integer;begin

write('Inputyear:');readln(year);write(year:6);

if(yearmod400=0)thenwriteln('isaleapyear.')else

if(yearmod4=0)and(yearmod1000)thenwriteln('isaleapyear.')elsewriteln('isnotaleapyear.');end.

例4、判断1995年,每个月份的天数

分析:程序分为,输入月份,计算该月的天数,输出天数源程序如下:programdays;

varmonth,days:integer;begin

write('Inputmonth:');readln(month);casemonthof

1,3,5,7,8,10,12:days:=31;4,6,9,11:days:=30;2:days:=28;elsedays:=0;end;

ifdays0thenwriteln('Days=',days);end.

例5期未来临了,班长小Q决定将剩余班费X元钱,用于购买若干支钢笔奖励给一些学习好、表现好的同学。已知商店里有三种钢笔,它们的单价为6元、5元和4元。小Q想买尽量多的笔(鼓励尽量多的同学),同时他又不想有剩余钱。请您编一程序,帮小Q制订出一种买笔的方案。

分析:对于以上的实际问题,要买尽量多的笔,易知都买4元的笔肯定可以买最多支笔。因此最多可买的笔为xdiv4支。由于小q要把钱用完,故我们可以按以下方法将钱用完:

若买完xdiv4支4元钱的笔,还剩1元,则4元钱的笔少买1支,换成一支5元笔即可;若买完xdiv4支4元钱的笔,还剩2元,则4元钱的笔少买1支,换成一支6元笔即可;若买完xdiv4支4元钱的笔,还剩3元,则4元钱的笔少买2支,换成一支5元笔和一支6元笔即可。

从以上对买笔方案的调整,可以看出笔的数目都是xdiv4,因此该方案的确为最优方案。

源程序如下:programpen;

vara,b,c:integer;{a,b,c分别表示在买笔方案中,6元、5元和4元钱笔的数目}x,y:integer;{x,y分别表示剩余班费和买完最多的4元笔后剩的钱}begin

write('x=');readln(x);{输入x}c:=xdiv4;{4元笔最多买的数目}

y:=xmod4;{求买完c支4元笔后剩余的钱数y}caseyof

0:begina:=0;b:=0;end;

1:begina:=0;b:=1;c:=c-1;end;2:begina:=1;b:=0;c:=c-1;end;3:begina:=1;b:=1;c:=c-2;end;end;

writeln('a=',a,'b=',b,'c=',c);end.练习

1.输入三角形的三个边,判断它是何类型的三角形(等边三角形?等腰三角形?一般三角形?)。

2.输入三个数,按由大到小顺序打印出来。

3.计算1901年2099年之间的某月某日是星期几。

提示:我们知道,公历的平年是365天,闰年是366天,置闰的方法是能被4整除的年份在2月加一天,但能被100整除的不闰,能被400整除的又闰;因此,像1600、2000、2400年都是闰年,而1700、1800、1900、2100年都是平年,公元前1年,按公历也是闰年。因此,对于从公元前1年(或公元0年)12月31日到某一日子的年份Y之间的所有整年中的闰年数,就等于

[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]

[...]表示只取整数部分,第一项表示需要加上被4整除的年份数,第二项表示需要去掉被100整除的年份数,第三项表示需要再加上被400整除的年份数;之所以Y要减一是为了去掉输入的这一年。这样,我们就得到了第一个计算某一天是星期几的公式:

W=(Y-1)*365+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+D.(1)其中D是这个日子在这一年中的累积天数,算出来的W就是公元前1年(或公元0年)12月31日到你输入的这一天之间的间隔日数;把W用7除,余数是几,这一天就是星期几。比如我们来算2004年5月1日:

W=(2004-1)*365+[(2004-1)/4]-[(2004-1)/100]+[(2004-1)/400]+(31+29+31+30+1)=731702

731702/7=104528……6,余数为六,说明这一天是星期六,这和事实是符合的。

上面的公式(1)虽然很准确,但是计算出来的数字太大了,使用起来很不方便。仔细想想,其实这个间隔天数W的用数仅仅是为了得到它除以7之后的余数。这启发我们是不是可以简化这个W值,只要找一个和它余数相同的较小的数来代替,用数论上的术语来说,就是找一个和它同余的较小的正整数,照样可以计算出准确的星期数。

显然,W这么大的原因是因为公式中的第一项(Y-1)*365太大了。其实,(Y-1)*365=(Y-1)*(364+1)=(Y-1)*(7*52+1)=52*(Y-1)*7+(Y-1)

这个结果的第一项是一个7的倍数,除以7余数为0,因此(Y-1)*365除以7的余数其实就等于Y-1除以7的余数。这个关系可以表示为:(Y-1)*365≡Y-1(mod7)

其中,≡是数论中表示同余的符号,mod7的意思是指在用7作模数(也就是除数)的情况下≡号两边的数是同余的。因此,完全可以用(Y-1)代替(Y-1)*365,这样我们就得到了那个著名的、也是最常见到的计算星期几的公式:

W=(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+D.(2)4.输入两个正整数a、b,b最大不超过三位数,a不大于31;使a在左,b在右,拼接成一个新的数c。例如:a=2,b=16,则c=216;若a=18,b=476,则c=18476。

提示:求c的公式为:

c=a×K+b

其中:

第六课For循环语句在实际应用中,会经常遇到许多有规律性的重复运算,这就需要掌握本章所介绍的循环结构程序设计。在Pascal语言中,循环结构程序通常由三种的循环语句来实现,它们分别为FOR循环、当循环和直到循环;通常将一组重复执行的语句称为循环体,而控制重复执行或终止执行由重复终止条件决定;因此,重复语句是由循环体及重复终止条件两部分组成。一、for语句的一般格式

for:=todo;

for:=downtodo;

其中for、to、downto和do是Pascal保留字;表达式1与表达式2的值也称为初值和终值。

二、For语句执行过程

①先将初值赋给左边的变量(称为循环控制变量);

②判断循环控制变量的值是否已“超过”终值,如已超过,则跳到步骤⑥;

③如果未超过终值,则执行do后面的那个语句(称为循环体);

④循环变量递增(对to)或递减(对downto)1;

⑤返回步骤②;

⑥循环结束,执行for循环下面的一个语句。

三、说明

①循环控制变量必须是顺序类型。例如,可以是整型、字符型等,但不能为实型。②循环控制变量的值递增或递减的规律是:选用to则为递增;选用downto则递减。③所谓循环控制变量的值"超过"终值,对递增型循环,"超过"指大于,对递减型循环,"超过"指小于。

④循环体可以是一个基本语句,也可以是一个复合语句。

⑤循环控制变量的初值和终值一经确定,循环次数就确定了。但是在循环体内对循环变量的值进行修改,常常会使得循环提前结束或进入死环。建议不要在循环体中随意修改控制变量的值。

⑥for语句中的初值、终值都可以是顺序类型的常量、变量、表达式。

四、应用举例

例1.输出1-100之间的所有偶数。

vari:integer;

begin

fori:=1to100do

ifimod2=0thenwrite(i:5);

end.

例2.求N!=1*2*3*…*N,这里N不大于10

分析:程序要先输入N,然后从1累乘到N

程序如下:

var

n,i:integer;{i为循环变量}

S:longint;{s作为累乘器}

begin

write('Entern=');readln(n);{输入n}

s:=1;

fori:=2tondo{从2到n累乘到s中}

s:=s*i;

writeln(n,'!=',s);{输出n!的值}

end.

练习

1.求s=1+4+7+…+298的值。

2.输入正整数N,输出1至N之间的奇数之和(1和N也要考虑)。

3.编写一个评分程序,接受用户输入10个选手的得分(0-10分),然后去掉一个最高分和一个最低分,求出某选手的最后得分(平均分)。

4.输出如下8行8列的数字矩阵:

[**************]8

..

..

..

[**************]8

5.用一张一元票换1分、2分和5分的硬币,每种至少一枚,问有哪几种换法(各几枚)?

6.输入正整数N,显示如下N行的数字三角形:

1

12

123

1234

...

1234...N

7.编程输出“九九乘法表”,格式要求如下:

1*1=1

2*1=2

3*1=3

4*1=4

5*1=5

6*1=6

7*1=7

8*1=8

8*8=642*2=43*2=64*2=85*2=106*2=127*2=148*2=163*3=94*3=125*3=156*3=187*3=218*3=24

9*3=274*4=165*4=206*4=247*4=288*4=329*4=365*5=256*5=307*5=356*6=367*6=427*7=498*7=569*7=638*6=489*6=548*5=409*5=459*1=99*2=18

9*8=729*9=81

第七课WHILE循环与REPEAT

一、WHILE循环(当循环)

对于for循环有时也称为计数循环,当循环次数未知,只能根据某一条件来决定是否进行循环时,用while语句或repeat语句实现循环要更方便。

while语句的形式为:

whiledo;

其意义为:当布尔表达式的值为true时,执行do后面的语句。

while语句的执行过程为:

①判断布尔表达式的值,如果其值为真,执行步骤2,否则执行步骤4;

②执行循环体语句(do后面的语句);

③返回步骤1;

④结束循环,执行while的下一个语句。

说明:这里while和do为保留字,while语句的特点是先判断,后执行。当布尔表达式成立时,重复执行do后面的语句(循环体)

例1、求恰好使s=1+1/2+1/3+…+1/n的值大于10时n的值。

分析:"恰好使s的值大于10"意思是当表达式s的前n-1项的和小于或等于10,而加上了第n项后s的值大于10。从数学角度,我们很难计算这个n的值。故从第一项开始,当s的值小于或等于10时,就继续将下一项值累加起来。当s的值超过10时,最后一项的项数即为要求的n。

程序如下:

var

s:real;

n:integer;{n表示项数}

begin

s:=0.0;n:=0;

whiles

begin

n:=n+1;{项数加1}

s:=s+1/n;{将下一项值累加到s}

end;

writlen('n=',n);{输出结果}

end.

例2、求两个正整数m和n的最大公约数。

分析:求两个正整数的最大公约数采用的辗转相除法求解。以下是辗转的算法:

分别用m,n,r表示被除数、除数、余数。

①求m/n的余数r.

②若r=0,则n为最大公约数.若r≠0,执行第③步.

③将n的值放在m中,将r的值放在n中.

④返回重新执行第①步。

程序如下:

programex4_4;

varm,n,a,b,r:integer;

begin

write('Inputm,n:');

readln(m,n);

a:=m;b:=n;r:=amodb;

whiler0do

begin

a:=b;b:=r;

r:=amodb;

end;

writeln('Thegreatestcommondivideis:',b:8);

end.

二、直到循环(REPEAT-until语句)

用while语句可以实现"当型循环",用repeat-until语句可以实现"直到型循环"。repeat-until语句的含义是:"重复执行循环,直到指定的条件为真时为止"。

直到循环语句的一般形式:

Repeat

;

:

;

until;

其中Repeat、until是Pascal保留字,repeat与until之间的所有语句称为循环体。说明:

①repeat语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体。②repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句,until是另一个语句。

③repeat语句在布尔表达式的值为真时不再执行循环体,且循环体可以是若干个语句,不需用begin和end把它们包起来,repeat和until已经起了begin和end的作用。while循环和repeat循环是可以相互转化的。

对于例2中求两个正整数的最大公约数,程序可用repeat-until循环实现如下:var

m,n,a,b,r:integer;

begin

write('Inputm,n=');

readln(m,n);

a:=m;b:=n;

repeat

r:=amodb;

a:=b;b:=r;

untilr=0;

writeln('Thegreatestcommondivideis',a);

end.

以上我们已介绍了三种循环语句。一般说来,用for循环比较简明,只要能用for循环,就尽量作用for循环。只在无法使用for循环时才用while循环和repeat-until循环,而且while循环和repeat-until循环是可以互相替代的。for循环在大多数场合也能用whiel和repeat-until循环来代替。一般for循环用于有确定次数循环,而while和repeat-until循环用于未确定循环次数的循环。

当一个循环的循环体中又包含循环结构程序时,我们就称之为循环嵌套。

三、循环结构程序设计

例3求1!+2!+…+10!的值。

分析:这个问题是求10自然数的阶乘之和,可以用for循环来实现。程序结构如下:forn:=1to10do

begin

①N!的值àt

②累加N!的值t

end

显然,通过10次的循环可求出1!,2!…,10!,并同时累加起来,可求得S的值。而求T=N!,又可以用一个for循环来实现:

t=1;

forj:=1tondo

t:=t*j;

因此,整个程序为:

programex4_5;

vart,s:real;

i,j,n:integer;

begin

S:=0;

forn:=1to10do

begin

t:=1;

forj:=1tondo

t:=t*j;

S:=S+t;

end;

writeln('s=',s:0:0);

end.

以上的程序是一个二重的for循环嵌套。这是比较好想的方法,但实际上对于求n!,我们可以根据求出的(n-1)!乘上n即可得到,而无需重新从1再累乘到n。

程序可改为:

programex4_5;

vart,s:real;

i,j,n:integer;

begin

S:=0;t:=1;

forn:=1to10do

begin

t:=t*n;

S:=S+t;

end;

writeln('s=',s:0:0);

end.

显然第二个程序的效率要比第一个高得多。第一程序要进行1+2+…+10=55次循环,而第二程序进行10次循环。如题目中求的是1!+2!+…+1000!,则两个程序的效率区别更明显。

例4一个炊事员上街采购,用500元钱买了90只鸡,其中母鸡一只15元,公鸡一只10元,小鸡一只5元,正好把钱买完。问母鸡、公鸡、小鸡各买多少只?

分析:设母鸡I只,公鸡J只,则小鸡为90-I-J只,则15*I+10*J+(90-I-J)*5=500,显然一个方程求两个未知数是不能直接求解。必须组合出所有可能的i,j值,看是否满足条

件。这里I的值可以是0到33,J的值可以0到50。

源程序如下:

programrex4_6;

vari,j,k:integer;

begin

fori:=1to5do

forj:=1to8do

begin

k:=90-i-j;

if15*i+10*j+5*k=500thenwriteln(i:5,j:5,k:5);

end;

end.

例5、求100-200之间的所有素数。

分析:我们可对100-200之间的每一整数进行判断,判断它是否为素数,是则输出。而对于任意整数i,根据素数定义,我们从2开始,到,找i的第一个约数。若找到第一个约数,则i必然不是素数。否则i为素数。

源程序如下:

var

i:integer;

x:integer;

begin

fori:=100to200do

begin

x:=2;

while(x0)do

begin

x:=x+1;

end;

ifx>trunc(sqrt(i))thenwrite(i:8);

end;

end.

练习

1、用WHILE和REPEAT语句分别实现下列图形的输出:

AAA

AAAAA

AAAAAAA

AAAAAAAAA

2、用REPEAT语句编程找出1到输入的三位正整数N之间的水仙数(如:153=13+53+33,153就是水仙数)。

3、编程输出具有ABCD=(AB+CD)2特征的四位数,如:3025=(30+25)2

4、输入一个正整数n,把它分解成质因子相乘的形式

例如:36=1*2*2*3*339=1*3*13

5、编程输出如下字母金字塔:

AB

ABC

ABCD

.........

AB..YZ

6

、输出如下图形

7、编写一程序,验证角谷猜想,所谓的角谷猜想是:“对于任意大于1的自然数n,若n为奇数,则将n变为3*n+1;若n为偶数则将n变为n的一半,经过若干次这样的变换,一定会使n变为1”,如:

6→6/2=3→3*3+1=10→10/2=5→5*3+1=16→16/2=8→8/2=4→4/2=2→2/2=1

8.有一堆100多个的零件,若三个三个数,剩二个;若五个五个数,剩三个;若七个七个数,剩五个。请你编一个程序计算出这堆零件至少是多少个?

第一课初识Pascal语言

信息学奥林匹克竞赛是一项益智性的竞赛活动,核心是考查选手的智力和使用计算机解题的能力。选手首先应针对竞赛中题目的要求构建数学模型,进而构造出计算机可以接受的算法,之后要写出高级语言程序,上机调试通过。程序设计是信息学奥林匹克竞赛的基本功,在青少年朋友参与竞赛活动的第一步必须掌握一门高级语言及其程序设计方法。

一、Pascal语言概述

PASCAL语言也是一种算法语言,它是瑞士苏黎世联邦工业大学的N.沃思(NiklausWirth)教授于1968年设计完成的,1971年正式发表。1975年,对PASCAL语言进行了修改,作为“标准PASCAL语言”。

PASCAL语言是在ALGOL60的基础上发展而成的。它是一种结构化的程序设计语言,可以用来编写应用程序。它又是一种系统程序设计语言,可以用来编写顺序型的系统软件(如编译程序)。它的功能强、编译程序简单,是70年代影响最大一种算法语言。

二、Pascal语言的特点

从使用者的角度来看,PASCAL语言有以下几个主要的特点:

⒈它是结构化的语言。PASCAL语言提供了直接实现三种基本结构(顺序、分支、循环)的语句以及定义“过程”和“函数”(子程序)的功能。可以方便地书写出结构化程序。在编写程序时可以完全不使用GOTO语句和标号。这就易于保证程序的正确性和易读性。PASCAL语言强调的是可靠性、易于验证性、概念的清晰性和实现的简化。在结构化这一点上,比其它(如BASIC,FORTRAN77)更好一些。

⒉有丰富的数据类型。PASCAL提供了整数、实型、字符型、布尔型、枚举型、子界型以及由以上类型数据构成的数组类型、集合类型、记录类型和文件类型。此外,还提供了其它许多语言中所没有的指针类型。沃思有一个著名的公式:"算法+数据结构=程序"。指出了在程序设计中研究数据的重要性。丰富的数据结构和上述的结构化性质,使得PASCAL可以被方便地用来描述复杂的算法,得到质量较高的程序。

⒊能适用于数值运算和非数值运算领域。有些语言(如FORTRAN66,ALGOL60)只适用于数值计算,有些语言(如COBOL)则适用于商业数据处理和管理领域。PASCAL的功能较强,能广泛应用于各种领域。PASCAL语言还可以用于辅助设计,实现计算机绘图功能。⒋PASCAL程序的书写格式比较自由。不象FORTRAN和COBOL那样对程序的书写格式有严格的规定。PASCAL允许一行写多个语句,一个语句可以分写在多行上,也不区分大小写,这样就可以使PASCAL程序写得象诗歌格式一样优美,便于阅读。

由于以上特点,许多学校选PASCAL作为程序设计课程中的一种主要的语言。它能给学生严格而良好的程序设计的基本训练。培养学生结构化程序设计的风格。但它也有一些不足之处,如它的文件处理功能较差等。

三、Pascal语言程序的基本结构

任何程序设计语言都有着一组自己的记号和规则。PASCAL语言同样必须采用其本身所规定的记号和规则来编写程序。尽管不同版本的PASCAL语言所采用的记号的数量、形式不尽相同,但其基本成分一般都符合标准PASCAL的规定,只是某些扩展功能各不相同罢了。下面我们首先来了解Pascal语言的程序基本结构。

为了明显起见先举一个最简单的PASCAL程序例子:【例1】

从这个简单的程序可以看到:

⒈一个PASCAL程序分为两个部分:程序首部和程序体(或称分程序)

⒉程序首部是程序的开头部分,它包括:

⑴程序标志。用“program”来标识“这是一个PASCAL程序”。PASCAL规定任何一个PASCAL程序的首部都必须以此字开头。在turbopascal语言中,首部也可省略。

⑵程序名称。由程序设计者自己定义(但受一些规则限制),如例中的exam1。

注:在写完程序首部之后,应有一个分号。

⒊程序体是程序的主体,在有的书本里也称“分程序”。程序体包括说明部分(也可省略)和执行部分两个部分。

⑴说明部分用来描述程序中用到的变量、常量、类型、过程与函数等。本程序中第二行是"变量说明",用来定义变量的名称、类型。

PASCAL规定,凡程序中用到所有变量、符号常量、数组、标号、过程与函数、记录、文件等数据都必须在说明部分进行定义(或称“说明”)。也就是说,不允许使用未说明先使用。

⑵执行部分的作用是通知计算机执行指定的操作。如果一个程序中不写执行部分,在程序运行时计算机什么工作也不做。因此,执行部分是一个PASCAL程序的核心部分。

执行部分以“begin”开始,以“end”结束,其间有若干个语句,语句之间以分号隔开。

注:执行部分之后有一个句点,表示整个程序结束。

⒋PASCAL程序的书写方法比较灵活。当然,书写不应以节省篇幅为目的,而应以程序结构清晰、易读为目的。在编写程序时尽量模仿本书中例题程序格式。

⒌在程序中,一对大括号间的文字称为注释。注释的内容由人们根据需要书写,可以用英语或汉语表示。注释可以放在任何空格可以出现的位置。执行程序时计算机对注释不予理睬。

四、TurboPascal语言系统的使用(FreePascal与之类似)

目前,常用的Pascal语言系统有TurboPascal7.0、BorlandPascal7.0、

FreePascal1.0.10,下面我们就来学习TurboPascal7.0系统的使用。

1.系统的启动(上面的这几个版本都可在DOS、WINDOWS下使用)

方式一:只适合在WINDOWS下,在桌面上建立快捷方式,然后双击快捷方式即可

方式二:进入相应的系统目录下,执行主程序(TurboPascal的主程序为TURBO.EXE;FreePascal的主程序为FP.EXE),具体的操作步骤如下

进入DOS命令行(这是在WIDOWS下要做的,WIN98及以前的版本是在“运行”窗口中输入COMMAND命令;WINXP及以上版本是在“运行”窗口中输入CMD命令)

输入以下命令行即可启动相应的编译集成环境:

cd\tp\bin{进入主程序所在的文件夹,Freepascal是cd\pp\bin\go32v2}turbo{Freepascal是fp}

系统启动后,屏幕上出现如图1所示的集成环境。

2.TurboPascal系统集成环境简介

最顶上一行为主菜单。中间蓝色框内为编辑窗口,在它个编辑窗口内可以进行程序的编辑。最底下一行为提示行,显示出系统中常用命令的快捷键,如:将当前编辑窗口中文件存盘的命令快捷键为F2,获得系统帮助的快捷键为

F1,等等。

3.新建程序窗口

按F10进入主菜单,选择FILE菜单,执行其中New命令。就可建立一个新的程序窗口(默认文件名为Noname00.pas或Noname01.pas等)。

4.程序的输入、编辑与运行

在当前程序窗口中,一行一行的输入程序。事实上,程序窗口是一个全屏幕编辑器。所以对程序的编辑与其它编辑器的编辑方法类似,这里不再重复。

当程序输入完毕之后,一般要先按Alt+F9(或执行compile菜单中compile命令)对程序进行编译。如果程序有语法错误,则会在程序窗口的第一行处显示第一个红色错误信息。若无语法错误,则窗口正中央会出现一个对话框,提示编译成功。接下来,我们可以运行程

序了。

程序的运行可以通过按ALT+R打开RUN菜单中的RUN命令,或直接按快捷键CTRL+F9。则可以在用户窗口中输出运行结果。通常在程序运行结束后系统回到Pascal系统的集成环境,因此要查看运行结果,要按ALT+F5将屏幕切换到用户屏幕。

5.程序的保存与打开

当我们想把程序窗口中的程序存入磁盘时,可以通过按F2键(或执行File菜单中的save命令)来保存程序。第一次保存文件时屏幕上会出现一个对话框要求输入文件名(默认扩展名为.pas)。

当我们要将磁盘上的程序文件中的PASCAL程序装入窗口时,可按F3(或执行File菜单中的Open命令)来装入程序,此时系统也会弹出一个对话框要求输入要打开的文件名,或直接在文件对话框列表中选择所要的文件,然后回到打开文件。

6.退出TurboPascal:直接按组合键ALT+X或选择“File”菜单中的“Exit”

五、第一个程序

为让大家了解程序设计的基本过程(编辑→编译/解释→连接→运行),请大家输入下面的程序并运行,学会用自己的描述它的功能是什么?

programsample;

var

i,n,number:integer;

begin

write('Number=');

readln(number);

fori:=1tonumberdo

begin

ifimod2=1then

begin

forn:=1to(number-i)div2dowrite('');

forn:=1toidowrite('*');

writeln;

end;

end;

readln

end.

请输入上面的程序,将其存盘、关闭。然后再打开并运行序。(中途要在不退出Pascal的情况下进入命令行状态查看程序的运行结果,可以选择“File”菜单中的“Commandshell”,TurboPascal为“Dosshell”,返回请输入EXIT命令,不分大小写。

作业:模仿本课中出现的例程及学到的知识,完成下列编程任务

1.提示用户输入圆的半径,计算并输出圆的周长

2.提示用户输入两个数,计算并输出这两个数的和

第二课赋值语句、输出语句

上节课,我们学习了Pascal语言的程序基本结构,在一个程序中,所有的操作都由执行部分来完成,而执行部分又都是由一个个语句组成的。因此,下面开始我们要学习pascal语言的基本语句,并且在学习过程中逐步学会程序设计的基本方法。

这节课我们要学习两种语句,即赋值语句与输出语句。在语句学习之前我们要先了解一些pascal语言的基础知识。

一、常量、变量与算术表达式

(一)常量:在程序运行过程中,其值不能被改变的量称为常量。如123,145.88,'abc',true等。

1、整型常量:整型常量采用我们平常使用的十进制整数表示,包括正整数、负整数和零。如:138,0,-512等都是整型常量,而18.或18.0都不是整型常量。pascal中有一个标准标识符Maxint,它代表所使用的计算机系统允许的最大整型数,而最小的整型数即为-Maxint-1;TurboPascal还定义了长整数常量MaxLongInt,其值为2147483647。

注:计算机系统能表示的整型数的范围取决于其字长,如:现在大部分机器的字长字长为16,它们所能支持的整型数的范围为+215至-215-1,即-32768至+32767,这里涉及到有符号数和补码方面的知识;要想知道你所使用的计算机所能表示的整型数的范围,用这样的语句就可以知道了:WRITE(-maxint-1,'',maxint)

2、实型常量:包括正实数、负实数和实数零,其实就是常说的小数,pascal中表示实型常量的形式有两种。

⑴十进制表示法:这是人们日常使用的带小数点的表示方法,如0.0、-0.0、+5.61、-8.0、-6.050等都是实型常量,而0.、.37都不是合法的实数形式

⑵科学记数法:采用指数形式的表示方法,如1.25×105可表示成1.25E+05。在科学记数法中,字母"E"表示10这个"底数",而E之前为一个十进制表示的小数,称为尾数,E之后必须为一个整数,称为"指数"。如-1234.56E+26、+0.268E-5、1E5是合法形式,而.34E12、

2.E5、E5、E、1.2E+0.5都不是合法形式的实数。

无论实数是用十进制表示法还是科学表示法,它们在计算机内的表示形式是一样的,总是用浮点方式存储。

和整数相比,实数能表示的范围大得多,但值得注意的是实数的运算比整数的运算速度慢且无法像整数那样精确表示,只能近似表示。

3、字符常量:在Pascal语言中,字符常量是由单个字符组成,所有字符来自ASCII字符集,共有256个字符。在程序中,通常用一对单引号将单个字符括起来表示一个字符常量,如:'a','A','0'等;特殊地,对于单引号字符,则要表示成''''。对于ASCII字符集中,按每个字符在字符集中的位置,将每个字符编号为0-255,编号称为对应字符的序号,因此字符也存在大小,如:'A''a'

4、布尔常量:布尔型常量仅有两个值,真和假,分别用标准常量名true和false表示,它们的序号分别为1和0。

5、符号常量:它是由程序员自己定义的,一个常量即可以直接用字面形式表示(称为直接常量,如124,156.8),也可以用一个标识符来代表一个常量,称为"符号常量"。但符号常量必须在程序中的说明部分定义,也就是说先定义,后使用。

定义符号常量的一般格式:CONST=;如:

CONSTPI=3.1415926;

E=2.71828;

说明:常量说明部分以关键字const开头,后面的标识符为常量标识符,其中"="号后的常量为整数、实数、字符、字符串(字符串常量在后面章节中将作介绍);而且在常量说明部分可以将几个常量说明成符号常量,共用一个关键字"const",例如:

则在本程序中pi和zero作为符号常量,分别代表实数3.14159和整数0;也就是说,常量说明部分既定义了常量名及其值,又隐含定义了常量的类型。

关于符号常量,应注意下列几点:

⑴、符号常量一经定义,在程序的执行部分就只能使用该常量标识符,而不能修改其值⑵、使用符号常量比直接用数值更能体现"见名知义"的原则,也便于修改参数,故一个较好的程序中,应尽量使用符号常量,在执行部分基本上不出现直接常量。

(二)变量:变量代表了一个存储单元,其中的值是可变的,故称为变量。如游戏"魂斗罗"中玩者命的个数最初为3,当你死了一次命减少一,这里命的个数就是一个变量(或者说命的个数存储在一个存储单元中)。即在程序运行过程中,其值可以改变的量,称为变量。

变量有三个要素是:变量名、变量类型、变量值

一个程序中可能要使用到若干个变量,为了区别不同的变量,必须给每个变量(存贮单元)取一个名(称为变量名),该变量(存贮单元)存放的值称为变量的值,变量中能够存放值的类型为变量的类型。例如"魂斗罗"游戏中用于存放"命"的变量,在游戏程序中的名字可取为N,它的类型为整型,游戏初始时这个变量的值为3

1.变量名:用一个合法的标识符代表一个变量。如n,m,rot,total等都是合法变量名。在程序中用到的变量必须在说明部分加以说明,变量名应遵循自定义标识符的命名规则,并注意“见名知义”的原则,即用一些有意义的单词作为变量名

“自定义标识符”的命名规则为:自定义标识符必须以字母(包含下划线"_")开头,后面的字符可以是字母或数字,标识符长度不超过63个字符

2.变量的类型:常量是有类型的数据,变量在某一固定时刻用来存放一个常量,因此也应有相应的类型;如整型变量用来存放整数,实型变量用来存放实数;也就是说,变量的类型取决于将要存放的数据的类型,并且其类型一旦定义了,就不能再改变,也不能把其他类型的数据赋给它

3.变量说明:在程序中若要使用变量,变量的名称及类型在程序的变量说明部分加以定义,变量的值则在程序的执行部分中才能赋给,变量说明的一般格式:VAR[,]:;(中括号内部分表示可省,下同)

其中VAR是pascal保留字,表示开始一个变量说明段,每个变量标识符或由逗号隔开的多个变量标识,必须在它的冒号后面说明成同一类型。一个程序中,可以说明许多不同类型的变量,每种类型变量之间用分号隔开,共用一个VAR符号。例如:

var

age,day:integer;

amount,average:real;

其中:Integer(整型)、Real(实型)、Boolean(布尔型)、Char(字符型)是标准标识符,

它们是"类型标识符",代表了确定的类型,如age和day被定义为整型变量,amount和average被定义为实型变量。

一旦定义了变量,就确定了它的类型,也就是说,就确定了该变量的取值范围和对该变量所能进行的运算。

(三)算术表达式

⑴算术表达式的定义:pascal语言中的算术表达式是由符合pascal语法规定的运算对象(包括常量、变量、函数)、算术运算符、圆括号组成的有意义的式子。如:

A+3.14159*5/8.4-Abs(-1123)

⑵算术运算符,常用的有以下6个算术运算符:

①+(加)

②-(减)

③*(乘)

④/(实数除)得到结果为实型.如5.0/2.0=2.5,5/2=2.5,4/2=2.0而不等于2。⑤DIV(整除)DIV它要求除数和被除数均为整型,结果也为整型。如10DIV2=5,10DIV3=3,5DIV10=0.-15DIV4=-3,DIV运算只取商的整数部分,参与DIV运算的两个对象不能为实型

⑥mod(求余),也只能用于整数运算,结果为整数。例如:10mod4=2,-17mod4=-1,4mod(-3)=1,-4mod3=-1,即amodb=a-(adivb)*b

(3)运算优先顺序,如果一个表达式里出现两个或两个以上的运算符,则必须规定它们的运算次序,pascal规定

①表达式中相同优先级的运算符,按从左到右顺序计算

②表达式中不同优先级的运算符,按从高到低顺序计算

③括号优先级最高,从内到外逐层降低

在算术运算中运算符的优先顺序与数学上的四则运算一致,即“先乘除后加减”(注:MOD、DIV运算的优先级与*、/相同)

二、赋值语句

变量既然代表一个存储单元,其值是可变的,那么其中的值是怎么提供的,又是怎么改变的呢?可以通过赋值语句来进行

1、赋值语句的格式

变量名:=表达式;

其中“:=”称为赋值号,是赋值语句的标志

2、执行过程:计算机先计算赋值号右边表达式的值,然后将表达式的值赋给变量名代表的变量,如:

A:=(9*8)-(2-1);

A:=A+1;

最后A的值为72

三、输出语句

输出语句的作用是将程序运算的结果输出到屏幕或打印机等输出设备,这里通常是指输出到屏幕。

(一)输出语句的两种格式

1、write语句

格式:Write(表达式1,表达式2,……);

如:write(1,2,3,4);

write(1.2,3.4,5);

write('MynameisLiping');

2、writeln语句

格式:Writeln(表达式1,表达式2,……)或writeln

(二)输出语句的功能

计算机执行到某一输出语句时,先计算出输出语句中的每个表达式的值,并将每一个表达式的值一个接一个地输出到屏幕上。

Write语句与writeln语句格式上都相似,但它们在功能上有所不同,两个语句的区别在于,write语句将其后括号中的表达式一个接一个输出后,没有换行;而writeln语句则在输出各个表达式的值后换行,例如以下两个程序段的输出分别为:

write(1,2,3,4);

write(5,6);

输出为:

123456

writeln(1,2,3,4);write(5,6);

输出为:

1234

56

四、应用例析

例1:某仓库5月1日有粮食100吨,5月2日又调进20吨,5月3日卖出库存的3分之二,5月4日又调进库存的3倍粮食,问该仓库从5月1日到5月4日期间每天的粮食分别是多少吨?(输出每天的库存量)

分析:在这个问题中,主要要描述从5月1日到5月4日期间仓库的粮食库存量,且易知它是不断变化的。因此我们可以用一个变量A来描述仓库的粮食库存量

程序可写如下:

Programex1;

Var

A:integer;

Begin

A:=100;

Writeln('5/1:',A);

A:=A+20;

Writeln('5/2:',A);

A:=Adiv3;

writeln('5/3:',A);

A:=A*4;

writeln('5/4:',A);

Readln;

第三课带格式的输出语句及输入语句

一、写语句(WRITE、WRITELN)的输出格式

在pascal语言中输出数据时是可以按照一定格式的,对整数隐含的输出形式为按十进制数形式;对实数的输出,隐含的形式是科学记数法形式(如果不想用科学记数法输出而用

小数形式输出,要自己另行定义)。

事实上,输出语句中的每个输出项中的表达式之后可以加上格式说明,若输出项后没有加格式说明,则数据按系统隐含的格式输出,还可加上一定格式符号按特定格式输出。

1、隐含的输出格式

pascal语言为整型量、实型量、布尔型量和字符串(用一对单引号括起来的字符序列)规定了每种数据所占的宽度(即一个数据占几列),一个数据所占的宽度称为“场宽”或“字段宽”;系统给出的隐含场宽称为标准场宽,每一种pascal版本给定的标准场宽不尽相同,下表给出标准pascal、Turbopascal、FreePascal所规定的标准场宽标准场宽

数据类型

integer

real

布尔型

字符串标准pascal102210串长TurboPascal实际长度174或5串长FreePascal实际长度254或5串长

在TurboPascal系统中,对于整型字符串的输出都是按数据本身长度输出,对于

布尔型数据(只有True和False两种值),TRUE为4列,FALSE为5列,一律采用大写输出。而real型数据的输出时,则按17列输出,其中第一列为符号位,正号不显示,后四位为"E±nn",中间的12列为尾数部分。如:(□代表一个空格)

语句

TurboPascal

结果

FreePascal

结果WRITELN(2.367)□2.36700000E+0001□2.[**************]0E+0001WRITELN(67)6767WRITELN(TRUE)TRUETRUEWRITELN('ACDE')ACDEACDE

有时,在程序中往往根据实际情况,需要自己定义场宽。

2、指定场宽(自己定义场宽):在写语句中输出项含有格式符号时,就是为了指

定场宽

⑴指定单场宽

格式:write(表达式:N)或writeln(表达式:N),其中N为自然数,指定单场宽后,所有数据不再按标准场宽输出,而按指定场宽输出;若数据实际长度小于指定场宽时,则一律“向右靠齐,左留空格”。

如write(1234:8);write('abcdef':12)

输出结果:

□□□□1234□□□□□□abcdef

对于标准实型数据指定单场宽时,如果场宽大于标准场宽时,右靠齐按标准场宽格式输出17位,左留空格。若场宽小于标准场宽时,第一位仍为符号位,最后四位仍为“E±nn”,中间部分为尾数显示部分;如果指定的宽度小于8位,则数据按8位格式“*.*E±nn”输出

⑵指定双场宽

如果输出项是实数时,如果希望输出的实数不用科学记数法输出,而用小数形式输出,可以用指定双场宽方法输出,双场宽输出格式为:write(实型表达式:m:n),其中m和n都是自然数,m用以指定整个数据所占的宽度,n指定输出实数的小数位数,如:

write(sqrt(75):9:4);

输出:□□□8.6602

如果双场宽不能满足输出数据的最低要求,系统自动突破指定的场宽限制,按实际长度输出,如:write(sqrt(75):5:4);要使小数点后有4位数字,而总场宽为5,是不可能的(因为还有一个小数点,小数点前面还有一个数字),它最低限度要有6列,即输出为:

8.6602(舍弃超过场宽的数据坚持四舍五入原则)

例1:写出下列程序在turbopascal下的输出结果

programex;

consts='abcdefg';

var

i:integer;

r:real;

c:char;b:boolean;

begin

i:=1234;

r:=1234.5678;

c:='#';

b:=true;

writeln(i,i:6,i:3);

writeln(r,r:12:5,r:8:5,r:8:3);

writeln(c,c:5);

writeln(s,s:10,s:5);

writeln(b,b:5,b:3);

end.

运行结果如下:

1234□□12341234

□1.2345678000E+03□□1234.567801234.567801234.568

#□□□□#

abcdefg□□□abcdefgabcdefg

TRUE□TRUETRUE

3、应用例析

例2:已知A=253,B=43,输出A*B的运算式子,即输出如下

□□□□□□□253*43=10879

□□□□□□□□□253

□□□□□□□*□□43

□□□□--------

□□□□□□□□□759

□□□□□+□1012

□□□□--------

□□□□□□□10879

分析:对于该问题,我们只要控制好输出时右靠齐即可。即前四行的总宽度一样(例如为12),第五行总宽度比前面少1。第六、七行总宽度与前四行一样。

参考程序如下:

var

a,b:integer;

begin

a:=253;b:=43;

writeln(a:10,'*',b,'=',a*b);writeln(a:12);

write('*':8);writeln(b:4);writeln('--------':12);writeln(a*3:12);

write('+':6);writeln(a*4:5);writeln('--------':12);writeln(a*b:12);end.

二、输入语句(读语句READ、READLN)在程序中变量获得一个确定的值,固然可以用赋值语句,但是如果需要赋值的变量较多,或变量的值经常变化,则使用本节介绍的输入语句─读语句,将更为方便。读语句是在程序运行时由用户给变量提供数据的一种很灵活的输入动作,它有两种格式:

read();readln[()];

其中变量名表是用逗号隔开的若干个变量名组成的。

功能:从标准输入文件(即INPUT,一般对应着键盘)中读入数据,并依次赋给相应的变量

说明:①、read和readln是标准过程名,它们是标准标识符

②、执行到read或readln语句时,系统处于等待状态,等待用户从键盘上输入数据,

系统根据变量的数据类型的语法要求判断输入的字符是否合法。如执行read(a)语句,a是整型变量,则输入的字符为数字字符时是合法的,当输入结束时,则自动将刚接受的一串数字字符转换为整数赋给变量a

③、在输入数值型(整型或实型)数据时,数据间要用空格或回车分隔开各个数据,

输入足够个数的数据,否则仍要继续等待输入,但最后一定要有回车,表示该输入行结束,直到数据足够,该读语句执行结束,程序继续运行

例3:设a、b、c为整型变量,需将它们的值分别赋以10、20、30,写出对应下列语句的所有可能输入格式

Read(a,b,c);

解:根据③,即可列出所有可能输入格式(a)10□20□30←┘(b)10□20←┘

30←┘(c)10←┘

20□30←┘(d)10←┘

20←┘30←┘

其中"←┘"表示回车键,下同

④、read语句与readln语句的第一个区别是:read语句是一个接一个地读数据,在执行完本Read语句(读完本语句中变量所需的数据)后,下一个读语句接着从该数据输入行中继续读数据,也就是说,不换行。如:

Read(a,b);Read(c,d);Read(e);

如果输入数据行如下:1□2□3□4□5□6□←┘

则a,b,c,d,e的值分别为1,2,3,4,5,如果后面无读语句则数据6是多余的,这是允许的。Readln则不同,在读完本Readln语句中变量所需的数据后,该数据行中剩余的数据多余无用,或者说,在读完本Readln语句中变量所需数据后,一定要读到一个回车,否则多余的数据无用

例4:设要达到例1同样的目的,但语句改为readln(a,b);readln(c);

则例3中的4种输入格式只有(b)(d)是有效的

⑤、readln语句与read语句的第二个区别是:read后一定要有参数表,而readln可以不带参数表,即可以没有任何输入项,只是等待读入一个换行符(回车),经常用于暂停程序的运行,直到输入一个回车

例5:设有下列语句read(a,b,c);readln(d,e);readln;

第四课简单的分支结构程序设计

在现实生活中,我们每天都要进行根据实际情况进行选择。例如,原打算明天去公园,但如果明天天气不好,将留在家里看电视,所以人也会根据条件进行行为的选择;计算机也会根据不同情况作出各种逻辑判断,进行一定的选择。在这课与下一课中,我们将会发现,我们是通过选择(分支)结构语句来实现程序的逻辑判断功能。

一、PASCAL中的布尔(逻辑)类型

在前面,我们学习了整型(integer)与实型(real),其中integer型数据取值范围为

-3838

-32768到32767之间所有整数。而real型数据取值范围为其绝对值在10到10之间的所有实数,它们都是数值型的(即值都为数);布尔型(Boolean)是一种数据的类型,这种类型只有两种值,即“真”与“假”

1、布尔常量:在Pascal语言中“真”用ture表示,“假”用False表示,所以布尔类型只有TRUE与FALSE两个常量;

2、布尔变量(BOOLEAN):如果我们将某些变量说明成布尔型,那么这些变量就是布尔变量,它们只能用于存放布尔值(ture或false),例如,VARA,B:BOOLEAN;

3、布尔类型是顺序类型:由于这种类型只有两个常量,Pascal语言中规定ture的序号为1,false的序号为0。若某种类型的常量是有限的,那么这种类型的常量通常都有一个序号,我们称这种类型为顺序类型;如前面我们学过的整型(integer),以及后面要学到的字符型(char)都是顺序类型;

4、布尔类型的输入与输出a)、输出

VARA,B:BOOLEAN;BEGIN

A:=TRUE;B:=FALSE;WRITELN(A,B);END.

结果:TRUEFALSE

b)布尔类型变量不能直接用读语句输入:布尔类型变量不能通过读语句给它们提

供值;事实上,我们可以通过间接方式对布尔变量进行值的输入,最常用的就是通过赋值语句

例如,以下程序是错误的vara,b,c:Boolean;begin

readln(a,b,c);{错误语句}writeln(a,b,c);end.又如:

vara:Boolean;begin

a:=3>7;{正确语句}writeln(a);end.

二、关系表达式与布尔表达式

1、什么是关系表达式:用小括号、>、=、将两个算术表达式连接起来的式子就称为关系表达式(比较式),如:3+7>8,x+y

2、关系表达式的值

很显然,上面几个关系表达式中第一个是真的,第三个是假的,而第二个表达式可能是真的,也可能是假的;所以我们很容易发现,这些表达式的值是"对"的或"不对"的(或者说,是"真"的或"假"的),即关系表达式的值为布尔值。表示该比较式两端式子的大小关系是否成立;如3+2>6是假的,故它的值为FALSE;同样,45>=32是对的,故该表达式的值为true说明:①对于>=、=5都是真的,即值为TRUE

②关系表达式可用于表示一个命题。如:“m为偶数”可表示为:mmod2=0。“n

为正数”可表示为:n>0

3、布尔运算及布尔表达式(也称逻辑运算及逻辑表达式):为了表示更复杂的命题,Pascal还引入三种逻辑运算符:not、and、or,它们分别相当于数学上的“非”、“且”和“或”的意义

这三个运算符的运算对象为布尔量,其中not为单目运算,只有一个运算对象,and与or为双目运算,有两个运算对象,它们的运算真值表如下:

afalsefalsetruetrue

bfalsetruefalsetrue

Notatruetruefalsefalse

aandbfalsefalsefalsetrue

aorbfalseturetruetrue

axorbfalsetruetruefalse

于是,一个或多个关系表达式用布尔运算符连接起来的式子就称为布尔表达式;布

尔表达式的值也为布尔值;根据上表我们可以总结各运算符的运算规则:

NOT:非运算,取反(原来为真,非后为假;原来为假,非后为真)

AND:与运算,同为真则为真,其余均为假(参加运算的两个对象同为真结果才为真,否则为假)

OR:或运算,只要有一个为真,结果就为真

XOR:同或运算,相同则为真,不同则为假(参加运算的两个对象相同就为真,不同则为假)

请算出后面表达式的值:'a'6)AND('B'>'A')(3*4>6)OR('B'6)AND('B'>'A')都是正确的表达式;

②用括号改变各种运算符的先后顺序是非常重要的,如:NOT'a'6AND('B'>'A')都是不正确的表达式,因为布尔运算比关系运算的优先级高,导制上面的表达式有语法错误,为什么错请想一想

③布尔运算符的运算级别为:NOT>AND>OR如:FALSEORNOTTRUEANDTRUE的值为FALSE,它等价于:FALSEOR((NOTTRUE)ANDTRUE)

如果一个表达式里出现两个或两个以上的运算符,则必须规定它们的运算次序,pascal规定:

①表达式中相同优先级的运算符,按从左到右顺序计算;②表达式中不同优先级的运算符,按从高到低顺序计算;③括号优先级最高,从内到外逐层降低;

对于一个复杂的表达式可能同时包含算术运算、关系运算和逻辑运算以及函数运算,运算的优先顺序为:括号>函数>NOT>*、/、div、mod、and>+、-、or、xor>关系运算(>、=、=、)

对于复杂的命题,我们可以用布尔表达式来表示。例如,命题:“m,n都是偶数或都是奇数”可表示为(mmod2=0)and(nmod2=0)or(mmod2=1)and(nmod2=1)

三、简单的IF语句1、格式

Ⅰ、IF<布尔表达式>THEN语句;

Ⅱ、IF<布尔表达式>THEN语句1ELSE语句2;注意:Ⅱ型IF语句中语句1后无“;”号

2、功能

Ⅰ、执行IF语句时,先计算<布尔表达式>的值,若为TRUE则执行语句,否则不执行任何操作;

Ⅱ、执行IF语句时,先计算<布尔表达式>的值,若为TRUE则执行语句1,否则执行语句2;

3、示例

1)例4.2:输入一个整数a,判断是否为偶数(是输出Yes,否则输出No)Programex4_2;Vara:integer;Begin

Write('a=');readln(a);

If(amod2=0)thenwriteln('Yes')Elsewriteln('No');Readln;

End.

2)华榕超市里卖电池,每个电池8角钱,若数量超过10个,则可打75折

Programex4_3;

VarNum:integer;Price,Total:real;Begin

Write('Num=');readln(Num);Price=0.8;

IfNum>10thenPrice:=Price*0.75;Total:=Num*Price;

Writeln('Total=',Total:0:2);Readln;End.

3)编写一与电脑猜"红"或"黑"的游戏分析:用1代表红,0代表黑。先由计算机先出答案,然后再由人猜,猜对输出"YOUWIN"否则输出"YOULOST";为了模拟猜"红"或"黑"的随意性,程序中需要用到随机函数random(n)

函数是什么呢,例如大家都知道|-2|=2,|58|=58,那么|x|=?

如果我们用y表示|x|,那么,这里y=|x|就是一个函数,也就是说函数是一个关于一个或多个自变量(未知量,如上例中的x)的运算结果

在pascal语言中,系统提供了许多内部函数,其中包括|x|函数,当然它用abs(x)表

2

示;我们如果要求X-Y的绝对值,可以调用内部函数abs(x*x-y)即可求得;Random(n)也是一个内部函数,调用它能得到0~n-1之间的整数(但它不确定的,或说是随机的);同时由于函数是一个运算结果,所以函数的调用只能出现在表达式中

Programex4_3;Usescrt;

VarComputer,People:integer;Begin

Randomize;

Computer:=random(2);

Write('Youguess(0-Red1-Black):');readln(People);IfPeople=Computerthenwriteln('YOUWIN')Elsewriteln('YOULOST');Readln;End.练习四:

1.某车站行李托运收费标准是:10公斤或10公斤以下,收费2.5元,超过10公斤的行李,按每超过1公斤增加1.5元进行收费。试编一程序,输入行李的重量,算出托运费。

2.利用本课的知识,将第三课练习的第2题作进一步完善,即:程序要能判断输入的三个边能不能构成三角形(有数小于等于零、两边之和不能大于第三边都不能构成三角形),若不能则提示输入的数据有误且不做任何计算;若能构成三角形就计算并输出其面积。

第五课If嵌套与Case语句

一、IF语句的嵌套

在if语句中,如果then子句或else子句仍是一个if语句,则称为if语句的嵌套;

例1:

计算下列函数

分析:根据输入的x值,先分成x>0与x≤0两种情况,然后对于情况x≤0,再区分x是小于0,还是等于0;

源程序如下:programex;var

x:real;y:integer;begin

wrtie('Inputx:');readln(x);

ifx>0theny:=1{x>0时,y的值为1}else{x≤0时}

ifx=0theny:=0elsey:=-1;writeln('x=',x:6:2,'y=',y);end.

显然,以上的程序中,在then子句中嵌套了一个Ⅱ型if语句,当然程序也可以写成如下形式:

programex;var

x:real;y:integer;begin

wrtie('Inputx:');readln(x);ifx>=0then

ifx>0theny:=1elsey:=0elsey=-1;

writeln('x=',x:6:2,'y=',y);end.

但是对于本题,下面的程序是不对的。y:=0;

ifx>=0then

ifx>0theny:=1elsey:=-1;

明显,从此人的程序书写格式可以看出,他想让else与第一个if配对,而事实上,这是错的。因为pascal规定:else与它上面的距它最近的then配对,因此以上程序段的逻辑意义就与题义不符。

要使上程序段中esle与第一个then配对,应将程序段修改为:y:=0;或者y:=0;ifx>=0thenifx>=0thenifx>0theny:=1begin

elsey:=-1;

end

elseY:=-1;

二、case语句

从上面我们知道可以用嵌套的if语句实现多分支的选择结构,但如果分支越来越多时,用嵌套的if语句实现多分支就显得繁杂。当多分支选择的各个条件由同一个表达式的不同结果值决定时,可以用case语句实现;它的选择过程,很象一个多路开关,即由case语句的选择表达式的值,决定切换至哪一语句去工作。因此在分支结构程序设计中,它是一种强有力的手段,在实现多路径分支控制时,用case对某些问题的处理和设计,比用if语句写程序具有更简洁、清晰之感。(一)、case语句的一般形式:

caseof

:语句1;:语句2;:

:语句nend;

其中case、of、end是Pascal的保留字,表达式的值必须是顺序类型,它可以是整型、布尔型及以后学习的字符型、枚举型和子界型;情况标号表是一串用逗号隔开的与表达式类型一致的常量序列,语句可以是任何语句,包括复合语句和空语句。(二)、case语句的执行过程

先计算表达式(称为情况表达式)的值,如果它的值等于某一个常量(称为情况常量,也称情况标号),则执行该情况常量后面的语句,在执行完语句后,跳到case语句的末尾end处。(三)、说明

①情况表达式必须是顺序类型的;

②情况常量是情况表达式可能具有的值,因而应与情况表达式具有相同的类型;③情况常量出现的次序可以是任意的;

④同一情况常量不能在同一个case语句中出现两次或两次以上;⑤每个分语句前可以有一个或若干个用逗号隔开的情况常量;

⑥如果情况表达式的值不落在情况常量的范围内,则认为本case语句无效,执行case语句的下一个语句,turbopascal中增加了一个“否则”的情况,即增加一个else子句,但也是可省的;

⑦每个常量后面只能是一个语句或一个复合语句;例2根据x的值,求函数Y

的值

分析:利用case语句进行程序设计,关键在于巧妙地构造情况表达式。本例中三种情况可用一个表达式区分出来:Trunc(x/100),因为x在(0~100)之间时表达式值为0,x在[100,200)时表达式值为1;其余部分可用else子句表示;

注:trunc()是一个用于返回整数部分的函数,如trunc(23.75)的值为23、trunc(-23467/100)的值为-234

programex;varx,y:real;

b:integer;begin

write('Inputx:');readln(x);

b:=trunc(x/100);casebof0:y:=x+1;1:y:=x-1;elsey:=0;

end;{endofcase}

writeln('x=',x:8:2,'y=',y:8:2);end.

三、选择结构的程序设计

例3、输入一个年号,判断它是否是闰年

分析:判断闰年的算法是,如果此年号能被400除尽,或者它能被4整除而不能被100整除,则它是闰年;否则,它是平年

源程序如下:programex;

varyear:integer;begin

write('Inputyear:');readln(year);write(year:6);

if(yearmod400=0)thenwriteln('isaleapyear.')else

if(yearmod4=0)and(yearmod1000)thenwriteln('isaleapyear.')elsewriteln('isnotaleapyear.');end.

例4、判断1995年,每个月份的天数

分析:程序分为,输入月份,计算该月的天数,输出天数源程序如下:programdays;

varmonth,days:integer;begin

write('Inputmonth:');readln(month);casemonthof

1,3,5,7,8,10,12:days:=31;4,6,9,11:days:=30;2:days:=28;elsedays:=0;end;

ifdays0thenwriteln('Days=',days);end.

例5期未来临了,班长小Q决定将剩余班费X元钱,用于购买若干支钢笔奖励给一些学习好、表现好的同学。已知商店里有三种钢笔,它们的单价为6元、5元和4元。小Q想买尽量多的笔(鼓励尽量多的同学),同时他又不想有剩余钱。请您编一程序,帮小Q制订出一种买笔的方案。

分析:对于以上的实际问题,要买尽量多的笔,易知都买4元的笔肯定可以买最多支笔。因此最多可买的笔为xdiv4支。由于小q要把钱用完,故我们可以按以下方法将钱用完:

若买完xdiv4支4元钱的笔,还剩1元,则4元钱的笔少买1支,换成一支5元笔即可;若买完xdiv4支4元钱的笔,还剩2元,则4元钱的笔少买1支,换成一支6元笔即可;若买完xdiv4支4元钱的笔,还剩3元,则4元钱的笔少买2支,换成一支5元笔和一支6元笔即可。

从以上对买笔方案的调整,可以看出笔的数目都是xdiv4,因此该方案的确为最优方案。

源程序如下:programpen;

vara,b,c:integer;{a,b,c分别表示在买笔方案中,6元、5元和4元钱笔的数目}x,y:integer;{x,y分别表示剩余班费和买完最多的4元笔后剩的钱}begin

write('x=');readln(x);{输入x}c:=xdiv4;{4元笔最多买的数目}

y:=xmod4;{求买完c支4元笔后剩余的钱数y}caseyof

0:begina:=0;b:=0;end;

1:begina:=0;b:=1;c:=c-1;end;2:begina:=1;b:=0;c:=c-1;end;3:begina:=1;b:=1;c:=c-2;end;end;

writeln('a=',a,'b=',b,'c=',c);end.练习

1.输入三角形的三个边,判断它是何类型的三角形(等边三角形?等腰三角形?一般三角形?)。

2.输入三个数,按由大到小顺序打印出来。

3.计算1901年2099年之间的某月某日是星期几。

提示:我们知道,公历的平年是365天,闰年是366天,置闰的方法是能被4整除的年份在2月加一天,但能被100整除的不闰,能被400整除的又闰;因此,像1600、2000、2400年都是闰年,而1700、1800、1900、2100年都是平年,公元前1年,按公历也是闰年。因此,对于从公元前1年(或公元0年)12月31日到某一日子的年份Y之间的所有整年中的闰年数,就等于

[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]

[...]表示只取整数部分,第一项表示需要加上被4整除的年份数,第二项表示需要去掉被100整除的年份数,第三项表示需要再加上被400整除的年份数;之所以Y要减一是为了去掉输入的这一年。这样,我们就得到了第一个计算某一天是星期几的公式:

W=(Y-1)*365+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+D.(1)其中D是这个日子在这一年中的累积天数,算出来的W就是公元前1年(或公元0年)12月31日到你输入的这一天之间的间隔日数;把W用7除,余数是几,这一天就是星期几。比如我们来算2004年5月1日:

W=(2004-1)*365+[(2004-1)/4]-[(2004-1)/100]+[(2004-1)/400]+(31+29+31+30+1)=731702

731702/7=104528……6,余数为六,说明这一天是星期六,这和事实是符合的。

上面的公式(1)虽然很准确,但是计算出来的数字太大了,使用起来很不方便。仔细想想,其实这个间隔天数W的用数仅仅是为了得到它除以7之后的余数。这启发我们是不是可以简化这个W值,只要找一个和它余数相同的较小的数来代替,用数论上的术语来说,就是找一个和它同余的较小的正整数,照样可以计算出准确的星期数。

显然,W这么大的原因是因为公式中的第一项(Y-1)*365太大了。其实,(Y-1)*365=(Y-1)*(364+1)=(Y-1)*(7*52+1)=52*(Y-1)*7+(Y-1)

这个结果的第一项是一个7的倍数,除以7余数为0,因此(Y-1)*365除以7的余数其实就等于Y-1除以7的余数。这个关系可以表示为:(Y-1)*365≡Y-1(mod7)

其中,≡是数论中表示同余的符号,mod7的意思是指在用7作模数(也就是除数)的情况下≡号两边的数是同余的。因此,完全可以用(Y-1)代替(Y-1)*365,这样我们就得到了那个著名的、也是最常见到的计算星期几的公式:

W=(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+D.(2)4.输入两个正整数a、b,b最大不超过三位数,a不大于31;使a在左,b在右,拼接成一个新的数c。例如:a=2,b=16,则c=216;若a=18,b=476,则c=18476。

提示:求c的公式为:

c=a×K+b

其中:

第六课For循环语句在实际应用中,会经常遇到许多有规律性的重复运算,这就需要掌握本章所介绍的循环结构程序设计。在Pascal语言中,循环结构程序通常由三种的循环语句来实现,它们分别为FOR循环、当循环和直到循环;通常将一组重复执行的语句称为循环体,而控制重复执行或终止执行由重复终止条件决定;因此,重复语句是由循环体及重复终止条件两部分组成。一、for语句的一般格式

for:=todo;

for:=downtodo;

其中for、to、downto和do是Pascal保留字;表达式1与表达式2的值也称为初值和终值。

二、For语句执行过程

①先将初值赋给左边的变量(称为循环控制变量);

②判断循环控制变量的值是否已“超过”终值,如已超过,则跳到步骤⑥;

③如果未超过终值,则执行do后面的那个语句(称为循环体);

④循环变量递增(对to)或递减(对downto)1;

⑤返回步骤②;

⑥循环结束,执行for循环下面的一个语句。

三、说明

①循环控制变量必须是顺序类型。例如,可以是整型、字符型等,但不能为实型。②循环控制变量的值递增或递减的规律是:选用to则为递增;选用downto则递减。③所谓循环控制变量的值"超过"终值,对递增型循环,"超过"指大于,对递减型循环,"超过"指小于。

④循环体可以是一个基本语句,也可以是一个复合语句。

⑤循环控制变量的初值和终值一经确定,循环次数就确定了。但是在循环体内对循环变量的值进行修改,常常会使得循环提前结束或进入死环。建议不要在循环体中随意修改控制变量的值。

⑥for语句中的初值、终值都可以是顺序类型的常量、变量、表达式。

四、应用举例

例1.输出1-100之间的所有偶数。

vari:integer;

begin

fori:=1to100do

ifimod2=0thenwrite(i:5);

end.

例2.求N!=1*2*3*…*N,这里N不大于10

分析:程序要先输入N,然后从1累乘到N

程序如下:

var

n,i:integer;{i为循环变量}

S:longint;{s作为累乘器}

begin

write('Entern=');readln(n);{输入n}

s:=1;

fori:=2tondo{从2到n累乘到s中}

s:=s*i;

writeln(n,'!=',s);{输出n!的值}

end.

练习

1.求s=1+4+7+…+298的值。

2.输入正整数N,输出1至N之间的奇数之和(1和N也要考虑)。

3.编写一个评分程序,接受用户输入10个选手的得分(0-10分),然后去掉一个最高分和一个最低分,求出某选手的最后得分(平均分)。

4.输出如下8行8列的数字矩阵:

[**************]8

..

..

..

[**************]8

5.用一张一元票换1分、2分和5分的硬币,每种至少一枚,问有哪几种换法(各几枚)?

6.输入正整数N,显示如下N行的数字三角形:

1

12

123

1234

...

1234...N

7.编程输出“九九乘法表”,格式要求如下:

1*1=1

2*1=2

3*1=3

4*1=4

5*1=5

6*1=6

7*1=7

8*1=8

8*8=642*2=43*2=64*2=85*2=106*2=127*2=148*2=163*3=94*3=125*3=156*3=187*3=218*3=24

9*3=274*4=165*4=206*4=247*4=288*4=329*4=365*5=256*5=307*5=356*6=367*6=427*7=498*7=569*7=638*6=489*6=548*5=409*5=459*1=99*2=18

9*8=729*9=81

第七课WHILE循环与REPEAT

一、WHILE循环(当循环)

对于for循环有时也称为计数循环,当循环次数未知,只能根据某一条件来决定是否进行循环时,用while语句或repeat语句实现循环要更方便。

while语句的形式为:

whiledo;

其意义为:当布尔表达式的值为true时,执行do后面的语句。

while语句的执行过程为:

①判断布尔表达式的值,如果其值为真,执行步骤2,否则执行步骤4;

②执行循环体语句(do后面的语句);

③返回步骤1;

④结束循环,执行while的下一个语句。

说明:这里while和do为保留字,while语句的特点是先判断,后执行。当布尔表达式成立时,重复执行do后面的语句(循环体)

例1、求恰好使s=1+1/2+1/3+…+1/n的值大于10时n的值。

分析:"恰好使s的值大于10"意思是当表达式s的前n-1项的和小于或等于10,而加上了第n项后s的值大于10。从数学角度,我们很难计算这个n的值。故从第一项开始,当s的值小于或等于10时,就继续将下一项值累加起来。当s的值超过10时,最后一项的项数即为要求的n。

程序如下:

var

s:real;

n:integer;{n表示项数}

begin

s:=0.0;n:=0;

whiles

begin

n:=n+1;{项数加1}

s:=s+1/n;{将下一项值累加到s}

end;

writlen('n=',n);{输出结果}

end.

例2、求两个正整数m和n的最大公约数。

分析:求两个正整数的最大公约数采用的辗转相除法求解。以下是辗转的算法:

分别用m,n,r表示被除数、除数、余数。

①求m/n的余数r.

②若r=0,则n为最大公约数.若r≠0,执行第③步.

③将n的值放在m中,将r的值放在n中.

④返回重新执行第①步。

程序如下:

programex4_4;

varm,n,a,b,r:integer;

begin

write('Inputm,n:');

readln(m,n);

a:=m;b:=n;r:=amodb;

whiler0do

begin

a:=b;b:=r;

r:=amodb;

end;

writeln('Thegreatestcommondivideis:',b:8);

end.

二、直到循环(REPEAT-until语句)

用while语句可以实现"当型循环",用repeat-until语句可以实现"直到型循环"。repeat-until语句的含义是:"重复执行循环,直到指定的条件为真时为止"。

直到循环语句的一般形式:

Repeat

;

:

;

until;

其中Repeat、until是Pascal保留字,repeat与until之间的所有语句称为循环体。说明:

①repeat语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体。②repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句,until是另一个语句。

③repeat语句在布尔表达式的值为真时不再执行循环体,且循环体可以是若干个语句,不需用begin和end把它们包起来,repeat和until已经起了begin和end的作用。while循环和repeat循环是可以相互转化的。

对于例2中求两个正整数的最大公约数,程序可用repeat-until循环实现如下:var

m,n,a,b,r:integer;

begin

write('Inputm,n=');

readln(m,n);

a:=m;b:=n;

repeat

r:=amodb;

a:=b;b:=r;

untilr=0;

writeln('Thegreatestcommondivideis',a);

end.

以上我们已介绍了三种循环语句。一般说来,用for循环比较简明,只要能用for循环,就尽量作用for循环。只在无法使用for循环时才用while循环和repeat-until循环,而且while循环和repeat-until循环是可以互相替代的。for循环在大多数场合也能用whiel和repeat-until循环来代替。一般for循环用于有确定次数循环,而while和repeat-until循环用于未确定循环次数的循环。

当一个循环的循环体中又包含循环结构程序时,我们就称之为循环嵌套。

三、循环结构程序设计

例3求1!+2!+…+10!的值。

分析:这个问题是求10自然数的阶乘之和,可以用for循环来实现。程序结构如下:forn:=1to10do

begin

①N!的值àt

②累加N!的值t

end

显然,通过10次的循环可求出1!,2!…,10!,并同时累加起来,可求得S的值。而求T=N!,又可以用一个for循环来实现:

t=1;

forj:=1tondo

t:=t*j;

因此,整个程序为:

programex4_5;

vart,s:real;

i,j,n:integer;

begin

S:=0;

forn:=1to10do

begin

t:=1;

forj:=1tondo

t:=t*j;

S:=S+t;

end;

writeln('s=',s:0:0);

end.

以上的程序是一个二重的for循环嵌套。这是比较好想的方法,但实际上对于求n!,我们可以根据求出的(n-1)!乘上n即可得到,而无需重新从1再累乘到n。

程序可改为:

programex4_5;

vart,s:real;

i,j,n:integer;

begin

S:=0;t:=1;

forn:=1to10do

begin

t:=t*n;

S:=S+t;

end;

writeln('s=',s:0:0);

end.

显然第二个程序的效率要比第一个高得多。第一程序要进行1+2+…+10=55次循环,而第二程序进行10次循环。如题目中求的是1!+2!+…+1000!,则两个程序的效率区别更明显。

例4一个炊事员上街采购,用500元钱买了90只鸡,其中母鸡一只15元,公鸡一只10元,小鸡一只5元,正好把钱买完。问母鸡、公鸡、小鸡各买多少只?

分析:设母鸡I只,公鸡J只,则小鸡为90-I-J只,则15*I+10*J+(90-I-J)*5=500,显然一个方程求两个未知数是不能直接求解。必须组合出所有可能的i,j值,看是否满足条

件。这里I的值可以是0到33,J的值可以0到50。

源程序如下:

programrex4_6;

vari,j,k:integer;

begin

fori:=1to5do

forj:=1to8do

begin

k:=90-i-j;

if15*i+10*j+5*k=500thenwriteln(i:5,j:5,k:5);

end;

end.

例5、求100-200之间的所有素数。

分析:我们可对100-200之间的每一整数进行判断,判断它是否为素数,是则输出。而对于任意整数i,根据素数定义,我们从2开始,到,找i的第一个约数。若找到第一个约数,则i必然不是素数。否则i为素数。

源程序如下:

var

i:integer;

x:integer;

begin

fori:=100to200do

begin

x:=2;

while(x0)do

begin

x:=x+1;

end;

ifx>trunc(sqrt(i))thenwrite(i:8);

end;

end.

练习

1、用WHILE和REPEAT语句分别实现下列图形的输出:

AAA

AAAAA

AAAAAAA

AAAAAAAAA

2、用REPEAT语句编程找出1到输入的三位正整数N之间的水仙数(如:153=13+53+33,153就是水仙数)。

3、编程输出具有ABCD=(AB+CD)2特征的四位数,如:3025=(30+25)2

4、输入一个正整数n,把它分解成质因子相乘的形式

例如:36=1*2*2*3*339=1*3*13

5、编程输出如下字母金字塔:

AB

ABC

ABCD

.........

AB..YZ

6

、输出如下图形

7、编写一程序,验证角谷猜想,所谓的角谷猜想是:“对于任意大于1的自然数n,若n为奇数,则将n变为3*n+1;若n为偶数则将n变为n的一半,经过若干次这样的变换,一定会使n变为1”,如:

6→6/2=3→3*3+1=10→10/2=5→5*3+1=16→16/2=8→8/2=4→4/2=2→2/2=1

8.有一堆100多个的零件,若三个三个数,剩二个;若五个五个数,剩三个;若七个七个数,剩五个。请你编一个程序计算出这堆零件至少是多少个?


相关文章

  • 高中数理化竞赛参考书推荐
  • 高中化学竞赛参考书特别推荐 常规/高考类: <高中化学重难点手册>(华中师范大学出版社,王后雄老师主编):历年高考试题汇编(任何一种,最好有详细解析的): <高中化学读本>(很老的化学教材): <高中化学研究性 ...查看


  • 化学竞赛感想
  • 张鑫雨同学自述"我的竞赛历程" 端木守拙 发表于 2010-8-24 14:16:00 我的竞赛历程 一.进入整合班: 初二第二学期伊始,年级从四个平行班中选出一个作为整合班,我有幸被选入整合班学习.同时,学校决定比平行 ...查看


  • 奥数的一些相关问题
  • [学习篇] 奥数学什么,奥数杯赛有哪些,对学习奥数的几点建议 1. 什么是奥数? "奥数"是奥林匹克数学竞赛的简称.1934年和1935年,前苏联开始在列宁格勒和莫斯科举办中学数学竞赛,并冠以数学奥林匹克的名称,1959 ...查看


  • 书籍分类有哪些
  • 书籍分类有哪些 书籍分类有哪些 2011-4-2 19:39 提问者:匿名 | 浏览次数:15435次 书籍分类有哪些 我来帮他解答 2011-4-2 19:41 满意回答 细分:(一) 经典著作 · 哲学类 社会科学 · 政治法律 军事科 ...查看


  • 六年级教研组工作总结
  • 时光荏苒,日月如梭,转眼又过去了一年.我们六年级教研组在上级领导的亲切关怀和教导处的直接领导下,全体教师立足岗位,团结协作,求真务实,教书育人,顺利而圆满地完成了教育教学任务. 为了在今后的工作中扬长避短,现将六年级的教研工作总结如下: 一 ...查看


  • 学习大字报
  • 主办:信息科学与工程学院.软件学院2009级年级会 顾问:易险峰 古丽拜天 李飞 主编:年级会学习部 全国大学生数学建模竞赛 这是教育部高等教育司和中国工业与应用数 学学会共同主办的面向全国大学生的群众性科技 活动,目的在于激励学生学习数学 ...查看


  • 成都体育学院体育基本理论.体育概论真题
  • 2003年成都体育学院攻读硕士学位研究生入学试题<体育概论>(注意:所有答案一律写在标准答题卷上) 名词解释(每题4分,共20分): 1体育(广义的) 2健康3体育制度 4体育手段 5身体锻炼 二.正误判断(须简要说明判断依据. ...查看


  • 高二生物第二课堂工作总结
  • 09-2010学年度第一学期高二生物第二课堂工作总结 三水中学 缪运良 本学期教学处安排我组织开展高二生物第二课堂活动,现在一学期快要过去,为扬长避短,现将过去的工作总结如下. 1.在开学处按照学校的工作目标和第二课堂的内容要求,结合学生的 ...查看


  • 物理奥赛培训
  • 全国中学生超常教育研究协作组第12届年会--论文 物理奥赛培训的实践与思考 黄爱国 (华南师范大学附属中学 510630) 摘要:本文从发扬团结协作的团队精神.形成理论和实验培训的教材体系.提高学生竞赛实验能力.培养自学能力和创新能力.提高 ...查看


热门内容