您现在的位置:小学生自学网>> 信息>> pascal语言>> 基础教程

pascal基础教程

作者: 来源: 发布时间:2009年05月12日 点击数:
 

第一部分 Pascal语言和程序设计基础
预备知识
基本程序结构和几个概念::
标识符  保留字    常量   变量    运算符   表达式    标准数据类型

Pacal语言程序结构

Program prog_name;
var 变量申明;
begin
  程序体;
end.

例如:
program pname;
const n=4;
type arr=array [1..4] of integer;
var i:integer; a:arr;
begin
for i:=1 to n do  read(a[i]);
readln;
for i:=n downto 1 do write(a[i]:4);
writeln;
end.
以上是一个PASCAL程序。从键盘读入4个数据,逆序输出。
一般来说,一个PASCAL程序包括以下几个部分:
程序头:program pname;  其中,program是保留字,表示程序从这个地方开始,pname是标识符,是程序的名字,可由程序员自定。保留字是PASCAL选定的,具有固定意义和用法的专用单词或缩写,这些单词不允许作其它使用。如上,“program”就有“程序从这里开始”这样一种特别的意义,而“const”就有“常量说明从这里开始”的意义。我们不能再用“program”、“const”来作为其它变量、常量等的名字。标识符是以字母开头的字母数字串,其长度最大为8个字符。用来表示常量、变量、类型、文件、过程、函数和程序的名字。如“pname”、“i”、“j”、“a1”就是合法的标识符;但“1a”、“#a”是非法的标识符。有一点要注意的是,在PASCAL中,字母除了作为字符值或字符串值之外,其大小写是无关的。如标识符“A1”和“a1”在PASCLA看来是同一标识符。在PASCAL中除了保留字和自定义的标识符外,还有一类有特殊含义的标识符,这类标识符称为标准标识符。它们是用来标记程序中经常引用的处理对象,如常量、函数。(PASCAL定义的保留字和标准标识符附后)
 标识符在命名的时候要注意:
1、名字要易记易读,有意义。如8皇后问题程序名可以是“queen”也可以是“huanghou”等;
2、不能用保留字、标准标识符作为自定义的标识符。

说明部分:
const n=4;
type ar=array [1..4] of integer;
var i:integer; a:ar;
其中,const部分是常量说明,说明一些在以下部分用到的,在整个程序执行过程不改变值的量。这些量PASCAL称为常量。在程序中用到这个值的地方均用常量名来代替。如上题中定义“n=4”指本程序处理4个数值,在下面的程序体中就用“n”来代替具体的值(如for i:=1 to n)。如果要改变处理数据个数,则只在常量说明部分修改“n=4”这一句就行了,而不用在程序中每一个用到的地方都加以修改。这样不但在编写程序的时候很方便,也增加了程序的可读性,修改时更方便。
常量说明在保留字“const”下开始。可以有多个语句。常量说明语句的格式是:“常量名=值;”。如“n=4;”。n是常量名,4是该常量的值,“;”是语句分隔符。
type部分是类型说明,说明一些在以下部分用到的数据类型。如数组、记录、指针等。
类型说明在保留字“type”下开始。可以有多个语句。类型说明语句的格式是:“类型名=类型说明;”。如“ar=array [1..4] of integer;”。ar是类型名,array [1..4] of integer是类型说明,“;”是语句分隔符。
var部分是变量说明。变量是指在程序执行过程中可以通过赋值语句或读语句来改变值的量。所有在程序中使用的变量都应该先在变量说明部分说明。PASCAL中引用的每个变量都有“名字”和“类型”属性。变量说明“说明”的主要工作是告诉PASCA下面程序中要用到这个名字的量,同时这个量的类型是什么。
变量说明在保留字“var”下开始。可以有多个语句。变量说明语句的格式是:“变量名:变量类型;”。其中,如果有多个变量同一类型,则变量名与变量名之间用逗号分隔,变量名与变量类型之间用冒号分隔。如“i:integer;”(i是变量名,integer是类型名)、“i、j:integer;”(i、j是变量名,integer是类型名)……
变量说明要注意:1、有效变量名称不能大于8个字符;2、变量名称必须以字母开头;3、在同一个有效范围内变量名称必须唯一。
各个说明部分均以该部分的保留字开始。如“const”开始常量说明;“type”开始类型说明;“var”开始变量说明。一个程序包含多少种类型的说明,看需要而定,不是每一个程序都必须同时包含这三种说明。如果程序不须要用到常量,则常量说明部分可以省略;如果不须要用到类型说明,则类型说明可省……
    PASCAL还有一条规则:先说明后引用。即所有在程序体中用到的“名字”必须都在说明部分说明过才能引用,否则就会出错,通不过编译,也执行不了。如上,类型“ar”先在类型说明中定义,然后在变量说明中引用;变量i在变量说明中定义,在程序中引用。
 程序体:
begin
for i:=1 to n do
read(a[i]);
readln;
for i:=n downto 1 do
write(a[i]:4);
writeln;
end.
程序体是以begin   end.括起来的语句系列。“end”后面是一个小圆点,标识着程序结束,整个程序只有一个是一个程序的主要部分。编程要完成的工作大部分都在这里完成。程序体中每一语句均以“;”作为结束符。在书写程序时,以“分层缩进”的风格来写,以便提高程序的可读性。所谓的“分层缩进”是指在逻辑上同一级的语句其起始点对齐,下一级的语句向右缩进。
运算符  表达式
PASCAL中的运算符有算术运算符和关系运算符。和我们在数学课中学的基本一样但在写法上有些不同,在写程序时要特别注意写法的不同:
    + 加号;- 减号;* 乘号( 数学中写为 × );/ 除号( 数学中写为 ÷);MOD  取余  如:8 MOD 2=0,7 MOD 2=1,2 MOD 3=2;DIV  取整  如:8 DIV 2=4,7 DIV 2=3,2 DIV 3=0。在PASCAL只有上面6种数学运算。其它的就只能利用这6种运算的组合通过语句来实现。如a^2(a的平方)可以化成a*a。
> 大于;< 小于;<> 不等于(数学中写为 ≠);<= 小于等于(数学中写为≤);>= 大于等于(数学中写为 ≥),
变量、常量通过运算符连接起来的式子我们称为表达式。一个单独的变量或常量也是表达式。如a、a+3、a*3+b都是表达式。写表达式时要注意PASCAL表达式跟我们已经熟悉的数学表达式在格式上的区别:

数学表达式 PASCAL表达式 注意
2a 2*a *号不能省略
a÷b a/b 除号的写法
a≠b a<>b 不等号的写法
a≤b a<=b 小于等于号的写法

标准数据类型:整型  实型  字符型   布尔型
    数据类型可以理解为一个取值范围和定义在这取值范围上的运算规则。想一想我们对于数的理解:小学学自然数,范围是从0开始,那时候不知道有小数,也不知道有负数,允许的运算是+、-、×、÷,而且对于减法规定被减数要大于减数。到了中学,数的范围扩大了,整数包括正数和负数,减法运算也不再有额外的规定的了。同理,在PASCAL中“数据类型”也是一个取值范围和在它上面定义的运算规则。PASCAL中定义好的标准数据类型一共有4个:整型、实型、字符型、布尔型,分别用保留字integer、real、char、boolean来标记它们。其取值范围和运算如下:
    整型(integer):范围  -32768——32767;运算  +   -  *  /  mod  div
    实型(real):范围  运算  +  -  *  /
字符型(char):范围  可显示的ASCII字符
 布尔型(boolean):范围  true  false  运算   and  or  not
在PASCAL中可使用的基本符号有:
    (1)大写字母 A—Z ;小写字母a—z  ;数字0—9
    (2)其它字符 +  —  *  /  =  >   <   >=    <=   <>  :=
(   ) [  ] . , :‘  $ ^ (*  *) {  }
其中,有些符号是以双字符作为一个整体,拆开后就失去原有的意义。如“<>”是一个表示“不等于”的关系运算符,如拆开后就变成了两个关系运算符,分别表示“小于”、“大于”。
PASCAL使用的保留字有:
 AND、ARRAY、BEGIN、CASE、CONST、DIV、DO、DOWNTO、ELSE、END、FILE、FOR、FUNCTION、GOTO 、IF、IN、LABEL、MOD、NIL、NOT、OF、PACKED、PROCEDURE、PROGRAM、RECORD、REPEAT、SET、THEN、TO、TYPE、UNTIL、VAR、WHILE、WITH、FORWARD

常用的标准标识符有:
    标准常量:FALSE  TRUE  MAXINT  MAXLONGINT
    标准类型:INTEGER  BOOLEAN  REAL  CHAR  TEXT
    标准文件:INPUT  OUTPUT
    标准函数:ABS  ACTAN  CHR  COS  EOF  ELON    EXP  LN  ODD
              ORD    PRED  ROUND  SIN  SQR  SQRT  SUCC  TRUNC
    标准过程:ASSIGN  GET  NEW  DISPOSE  PACK    PUT  READ
              READLN    RESET  REWRITE  UNPACK  WRITE  WRITELN

函数格式:
function fun_name(参数表):数据类型;
var 变量声明;
begin
  函数体;
end;
例题:写出计算两个整数a,b的和函数add(a,b)。
过程格式:
procedure proc_name(参数表);
var 变量声明;
begin
  过程体;
end;
例题:写出在屏幕打印一行文字:”hello,Pascal language is very easy!”

函数和过程的调用:

例题:从键盘输入:a,b两个数,输出由这两个数为直角边的三角形的面积。【xoi00_01.pas】
program xoi00_01;
function area(const a,b:real):real;
var s:real;
begin
  s:=a*b/2.0;
  area:=s;
end;
procedure myproc;
var a,b:real;
    s:real;
begin
 write('Please input two number a,b:');
 readln(a,b);
 s:=area(a,b);
 writeln('the area of trian is: ',s:5:2);
end;
{============= main program ================}
begin
  myproc;
end.

练习
一、 判断以下标识符的合法性:
a3 3a a17 abcd ex9.5 α β λ
二、 将下列的数学表达式改写成PASCAL表达式:
b^2-4ac
三、 求下列表达式的值:
20 mod 19, 15 mod 9, 7 div 8 ,19 div 3,(4>5) and (7<8),(8>9) or ( 9<10),2 and ((3=3) or (3<7))

第一节  顺序结构

顺序结构是程序设计中最简单的结构,也是最基本的结构,它就是按照程序书写的顺序逐句执行程序中的指令。流程图如下:

例题:计算圆的周长的过程:
输入圆的半径;(操作一)
计算圆的周长;(操作二)
输出圆的周长;(操作三)

基本的程序语句:
赋值语句:
赋值语句是最简单的语句,其一般形式为:
<变量>:=<表达式>;
“:=”称为赋值号,赋值语句的作用是计算表达式的值,并赋给变量。对于任何一个变量必须首先赋值,然后才能引用,否则,未赋初值的变量将以一个随机值参与运算。另外,赋值号两边的类型必须相同,但表达式值为整数时,它可自动化为实型后赋给该实型变量,即符合赋值相容。
如:Pi:=3.14;  R:=2;  Age:=20;  S:=Pi*R*R
例:关于赋值的例子
prssogram example;
var a,b:integer;
begin
a:=3;
b:=2;
a:=a+b;
writeln(a);
writeln(b);
end.
输入语句
通过计算机的外设把数据送到计算机内存的过程称为输入。Turbo Pascal语言的输入语句有如下两种形式:
read(<变量名表>);
readln(<变量名表>);
<变量名表>是一个或几个由逗号隔开的变量标识符,他们必须在程序说明部分预先说明,他们可以是整型、实型或字符型,布尔型不可以直接读入。例如a,b,c为整型变量,read(a,b,c)之后,键盘输入:20 30 40 <CR>(<CR>表示回车),结果: a=20,b=30,c=40
readln语句和read语句不同之处在于输入数据到各变量之后,readln自动换行,从下一行开始再输入数据。一个read语句执行完后,数据行中多余的未读数据可以被下一个输入语句读入;而一个readln于执行完后,数据行中多余未读数据就没有用了。readln语句中可以不包含变量名表。即有以下等价情况:
read(a,b);readln等价于readln(a,b)
输入语句输入的数据类型必须和变量一一对应。如果输入的是一串整数或实数,数据间用空格或回车分隔;若输入的是一串字符,则不用分隔。
输出语句
输出是将内存中的数据送到外设的过程。Turbo Pascal的输出语句有两种形式:
write(<输出项表>);
writeln(<输出项表>);
其中<输出项表>是一串用逗号分隔的常量、变量、函数名、表达式或字符串。如果是变量、函数名、表达式,则将其计算结果输出;如果是常量或字符串,则直接输出其值。
write和writeln的区别在于:write语句是输出项输出后,不换行,光标停留在最后一项后,writeln语句按项输出后,自动换行,光标则停留在下一行的开始位置。
writeln语句允许不含有输出项,即仅writeln;表示换行。
Turbo Pascal语言把输出项的数据显示占用的宽度称为域宽,你可以根据输出格式的要求在输出语句中自动定义每个输出项的宽度。定义宽度时分为单域宽和双域宽。
单域宽输出格式:writeln(I:n);
在n个字符宽的输出域上按右对齐方式输出I的值,若n大于I的实际位数,则在I值前面补(n-I的实际位数)个空格。若I的实际位数大于n,则自动突破限制。n必须是整数。
双域宽输出格式:writeln(a:n:m);
双域宽主要用于实型数据的输出。n的用法同上。在n个字符宽的输出域上按右队齐方式用小数点形式输出a的数值,m是小数点后的位数。原来的数据按该该格式指定的小数位数四舍五入。若m=0 ,则不输出小数部分和小数点,原数据四舍五入取整。n,m必须是整数。
例:输出语句的例子
program shuchu;
const s='pascal';
var i:integer;r:real;c:char;b:boolean;
begin
i:=12345;
r:=123.45
c:='a';
b:=true;
writeln('i=');
writeln(i:6);
writeln('r=',r,r:6:1);
writeln('c=',c,c:10);
writeln('b=',b,b:10)
end.
复合语句
复合语句是由若干语句组成的序列,语句之间用分号“;”隔开,并且以begin和end括起来,作为一条语句。复合语句的一般形式:
begin
语句1;
语句2;
……
语句n;
end;
例:变量值的交换
program swap;
var a,b,t:integer;
begin
a:=10;b:=20;
begin
t:=a;
a:=b;
b:=t;
end;
writeln('a=',a,'b=',b)
end.
例题1:输入圆的半径,求出圆的周长和面积:
Progam CalCircle;
var R,C,S:Real;{变量声明}
begin
write(‘输入圆的半径:’);
readln(R);
C:=2*Pi*R;
write(‘周长=’,C);
readln;
S:=Pi*sqr(R);{sqr(R)=R*R}
write(‘面积=’,S);
readln;
end.
例题2:找出下面程序中的语法错误。
Program Example1;
{计算圆环面积的程序,R2表示外圆环的半径,R1表示内圆环的半径,R2>R1}
var R1,R2:Real;
begin
      S=(R2+R1)*(R2-R1)*Pi  
      {Pi=3.14为常数}
      writeln(s)
end;
纠正以后的程序
Program Example1;
{计算圆环面积的程序,R2表示外圆环的半径,R1表示内圆环的半径,R2>R1}
var R1,R2:real;
        S:real;{每一个变量都必须声明}
begin
      S=(R2+R1)*(R2-R1)*Pi;  {Pi=3.14为常数}
      writeln(s); {语句必须以“;”结束}
end.{主程序必须以“.”结尾}

练习
编写程序实现以下功能:
1、输入三角形三边的长,计算三角形的面积。
计算公式:
 
Pascal程序中计算平方根的函数为:sqrt(x);{x:real; x 0}
基本要求:有友好的输入输出界面,不需要考虑输入的a,b,c是否可以构成三角形,假设输入的数据符合要求。

第二节 IF分支结构

例题: 输入一个考试分数,如果大于等于60就说恭喜你考试及格,如果小于60就说真差劲,要努力哦!

program JudgeScore;
输入分数→score;
如果Score≥60那么
  输出“恭喜你考试及格”
否则
  输出“真差劲,要努力哦”

“如果...那么”形式的判断在Pascal中使用If语句来实现。IF语句是由一个布尔表达式和两个供选择的操作序列组成。运行时根据布尔表达式求值结果,选取其中之一的操作序列执行。有两种形式的IF语句:
if <布尔表达式> then <语句>;
if <布尔表达式> then <语句1>
else   <语句2>;
当布尔表达式的值为真,则执行then后面的语句,值为假时有两种情况:要么什么也不做,要么执行else后面的语句。注意else前面没有分号,因为分号是两个语句之间的分隔符,而else并非语句。如果在该处添了分号,则在编译的时候就会认为if 语句到此结束,而把else当作另一句的开头,输出出错信息
前面例题的Pascal程序代码:
Program  JudgeScore;
var score:real;{声明分数变量score}
begin
readln(score);  {输入分数}
if  score>=60 then 
begin   {score代表分数的变量}
writeln(‘恭喜你,考试及格!’);
end  else begin
writeln(‘真差劲,要努力哦!’);
end; {end if score>=60}
end.

例:求y=f(x),当x>0时,y=1,当x=0时,y=0,当x<0时,y=-1
program lianxi;
var x,y:real;
begin
if x>0 then y:=1;
if x=0 then y:=0;
if x<0 then y:=-1;
writeln('y=',y);
end.
在Turbo Pascal语言if语句中被构造的语句只能是一条语句,当条件选择某个分支的计算要用多个语句描述时,就必须把该分支用begin和 end括来,写成复合语句。在用if语句连续嵌套时,如果你插入适量的复合语句,有利于程序的阅读和理解。
例:当x>0时候,计算x*x,并且输出x和x*x。
program lianxi;
var x,x1:real;
begin
readln('x=',x);
 if x>= then
  begin
   x1:=x*x;
   writeln('x*x=',x1);
   writeln('x=',x);
  end;
 end.
当if 语句嵌套时,Turbo Pascal约定else总是和最近的一个if配对。前面介绍了If语句的使用情况,下面来概括if判断语句的使用方法。
分支结构的基本情况:

if 条件成立 then
begin
处理;
end;
下一语句;

if 条件成立 then
begin
 操作B;
end else {if 条件不成立 then }
begin
 操作A;
end;
下一语句;

练习
写出下列关系表达式和逻辑表达式的Pascal语句:
1、 区分合格和不合格:x >= 60
2、 60分到70分之间: ( x >= 60 ) and ( x <=70 )
3、判别闰年的条件(年份能被4整除,并且不能被100整除;或者能被400整除的整数年份):((y mod 4 = 0) and (y mod 100 <> 0 )) or (y mod 400 = 0)

编写程序实现下列功能:
1、从键盘读入一个数,判断它的正负。是正数,则输出"+",是负数,则输出"-"
2、输入a,b,c三个不同的数,将它们按由小到大的顺序输出
3、铁路托运行李规定:行李重不超过50公斤的,托运费按每公斤0.15元计费;如超50公斤,超过部分每公斤加收0.10元。编一程序完成自动计费工作。
4、打印某年某月有多少天。(提示:A、闰年的计算方法:年数能被4整除,并且不能被100整除;或者能被400整除的整数年份。B、利用MOD运算可以判断一个数能否被另一个数整除)
5、从键盘输入3个数a,b,c输出其中最大的数。

第三节 Case分支结构

case语句是由一个表达式和众多可选择的操作序列组成。运行时,根据表达式的求值结果,在众多的分支中选取一个分支执行。其形式为:
case 表达式 of
常量1:语句1;
常量2:语句2;
……
常量n:语句n;
else 语句 n+1;  {可选项}
end;
表达式只能是顺序类型(除了实型以外的简单类型),其值必须是唯一确定并且和表达式类型相同。case语句执行和表达式值相匹配的case常数所指向的那条语句,如果没有相匹配的值,则执行else部分(如果有的话)或者什么也不做。在else前面的语句末尾有分号,这是和if语句不同的。
Case表达式的应用:
例题:输入一个考试分数(整数),根据分数情况报告相应的信息
 
要求:假设输入的分数为[0,100]之间的整数。
Program JudgeScore2;
var x:real;
begin
  read(x);{输入一个分数}
case x of
0..59:{ }
writeln(‘不及格’;
60..89:{ }
writeln(‘及格’);
90..100;{ }
writeln(‘优秀’);
else
writeln(‘错误的分数’);
end;{case x of}
end.
例:根据学生的成绩给予相应的等级,对应关系如下:
  90——100 A
  80——89  B
  60——79  C
  60以下    D
 program chengji;
  var s:real;ch:char;
 begin
  write('input the score: ');
  readln(s);
  if(s>=0)and(s<=100)then
   case s div 10 of
    10,9:ch:='A';
    8:ch:='B';
    7,6:='C';
    else ch:='D';
   end;
  writeln(s,'--',ch);
 end.

练习
1、我们把字母作如下的分类:大写字母:’A’..’Z’;小写字母:’a’..’z’;数字:’0’..’9’;其他字母,编写一个程序,根据上述分类的方法,输入一个字母,报告该字母所属的类型。
2、某超市为了促销,规定:购物不足50元的按原价付款,超过50不足100的按九折付款,超过100元的,超过部分按八折付款。编一程序完成超市的自动计费的工作。

第四节 for循环结构

程序设计时我们经常要做一些重复的任务通过反复的执行某一个动作来完成任务,编写这一类程序我们使用循环结构来实现。如计算1+2+3+….+100。Pascal中循环结构通过使用For、While、Repeat三种语句来实现。
For语句是形式最简单的循环语句。
例题1:输入正整数N,计算
分析: =1+2+3+…+N,因此我们必需重复的执行S:=S+i,其中S代表和,
S=1     {i=1}
S=1+2    {i=2}
S=1+2+3   {i=3}
S=1+2+3+4   {i=4}
….
S=1+2+3+4+…+N {i=N}
i从1变化到N,计算前I项的和:1+2+3+…+I,写成Pascal代码如下:
For i:=1 to N DO S:=S+i;{i从1变化到N重复执行S:=S+i}
完整的程序如下:
Program Example1_4
Var
  N,I,S:integer;
Begin
  Write(‘输入正整数N:’);Readln(N);
  S:=0;
  For I:=0 to n do S:=S+I;
  Writeln(‘1+2+3+…+’,n,’=’,s);
End.
 
FOR 循环有两种形式:
升序形式:for <控制变量>:=<初值> to <终值> do <语句>
降序形式:for <控制变量>:=<初值> downto <终值> do <语句>
for语句功能描述:
虽然for循环形式简单,但是执行的机制却很复杂。其基本过程如下:
1. 计算初值并记忆
2. 判断初值是否超出终值、如果超过则执行步骤7,否则执行步骤3
3. 把初值赋给控制变量
4. 执行do后面的语句(循环体)
5. 判断控制变量的值 是否达道终值,如果是则执行步骤6,否则执行步骤7
6. 控制变量取下一个值(升序取后继,降序取前驱)
7. (循环结束)执行下一语句.

例题:编写程序输出序号从32到126的ASCII字符与对应代码之间的对应关系。每行输出5个字符,输出结果如下如所示。(Example4_2)
program example4_2;
var  i, j: byte;
begin
  for i := 32 to 126 do
    begin
      if (j mod 5 = 0) then writeln;
      write(i: 5, chr(i): 2);
      j := j + 1;
end;
end.

程序说明:
标准函数chr(i)可以得到代码为i的字符。j mod 5 求 j模5的余数。语句if (j mod 5 = 0) then writeln;用于控制换行,每行写5个字符的对应关系。语句write(i: 5, chr(i): 2);用于格式化输出结果。

编程完成下列计算
1、
2、
3、 把数码1,2,3,4,…,9分成3组,每组构成一个3位数,使这3个3位数恰好成1:2:3,该怎样分?求出所有的解答来。(如:192,384,576就是一组解答)
4、 求出所有的三位数  ,它除以11所得余数等于它的三个数字的平方和。

第五节 while、repeat循环结构

While语句是另外一种实现循环的语句,一般形式如下:
While <条件> do <语句>
While循环的执行过程如下:
1. 判断条件是否成立,条件成立时执行步骤2,否则执行步骤4
2. 执行do后面的语句(循环体)
3. 返回步骤1
4. 结束循环,执行下一语句
注意:一定要有使条件取假(False)的时候,否则会出现死循环。
例题:从键盘输入一批学生考试数据,统计这些数据中大于80的数的个数。
分析:因为学生的人数没有确定,因此不方便用for循环来完成此项工作,但是用while循环比较容易实现。(example4_3)
while score>=0 do
   输入一个学生成绩→score;计算总分;
Pascal代码:
  while score >= 0 do
    begin
      readln(score);
      total := total + score;
    end;
完整的程序代码:
program example4_3;
var
  score: integer;
  total: integer;
  c: char;
begin
  writeln('输入学生分数:');
  readln(score);
  total:=0;
  while score >= 0 do
    begin
      readln(score);
      total := total + score;
    end;
    writeln('总分为:',total);
    read(c);
end.

Repeat语句与while语句基本类类似,只是while先判断条件,reapeat语句先执行循环体然后再判断。
Repeat
  <语句>;{循环体部分}
Until <条件>;{循环结束条件}
执行过程如下:
1. 执行循环体
2. 判断条件,如果布满足重复1,否则 执行步骤3
3. 结束循环,执行下一语句

例题:改写Example4_3程序使用Repeat循环语句实现。(Example4_4)
program example4_4;
var
  score: integer;
  total: integer;
  c: char;
begin
  writeln('输入学生分数:');
  total := 0;
  repeat
    readln(score);
    total := total + score;
  until score < 0;
  writeln('总分为:', total);
  read(c);
end.

练习
1、 计算下列式子的值:
(1) 1+3+5+…+99
(2) 1+2+4+8+…+128+256+512+1024
(3) 1+(1+2)+(1+2+3)+…+(1+2+3+4+…+N)
2、 有一分数序列: 求出这个数列的前20项的和。
3、 求水仙花数。所谓水仙花数,是指一个三位数 ,如果满足 ,则abc是水仙花数。
4、 输入一个整数,计算它各位上数字的和。(注意:是任意位的整数)
5、 输入一整数A,判断它是否质数。(提示:若从2到A的平方根的范围内,没有一个数能整除A,则A是质数。)
6、 求两个数的最小公倍数和最大公约数。(提示:公约数一定小于等于两数中的小数,且能整除两数中的大数。公倍数一定大于等于两数中的大数,且是大数的倍数,又能给两数中的小数整除。)
7、 编写一个译码程序,把一个英语句子译成数字代码。译码规则是以数字1代替字母A,数字2代替字母B,……,26代替字母Z,如遇空格则打印一个星号‘*’,英文句子以‘.‘结束。
8、  “百钱买百鸡”是我国古代的著名数学题。题目这样描述:3文钱可以买1只公鸡,2文钱可以买一只母鸡,1文钱可以买3只小鸡。用100文钱买100只鸡,那么各有公鸡、母鸡、小鸡多少只?与之相似,有"鸡兔同笼"问题。
9、 输入一个正整数N,把它分解成质因子相乘的形式。如:36=1×2×2×3×3; 19=1×19(提示:设因子为I,从2开始到N,让N重复被I除,如果能整除,则用商取代N,I为一个因子;如果不能整除,再将I增大,继续以上操作,直到I等于N。)
10、 编程实现:求 之值,其中a是一个数字。例如: (当n=5时),n由键盘输入。
11、 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如:6的因子为1、2、3,而6=1+2+3,因此6是“完数”。编程序找出1000以内的所有完数。
12、 编一程序,输入a,b,c,d,e,f,然后解出方程组 的解。

第六节 数据类型

简单数据类型
Pascal语言基本数据类型由:integer(longint,shortint,byte),real,char,Boolean.等构成。
自定义数据类型:
我们可以 在基本数据类型的基础上定义新的数据类型,类型定义的保留字为“Type”,格式为:
TYPE
  <类型标识符>=<数据类型>
如:
Type
  MyLong=Longint;
枚举类型:
 “枚举”的意思就是把所需要的对象都一个一个的列举出来。比方说星期是一个只有7个元素的数据,因此我们可以定义一种数据类型TWeekDay代表星期,如果一个变量定义为TWeekDay类型,那么他的取值范围就是Sunday..Saturday,另外颜色TColor也一样。习惯上我们在 自定义类型名称前加上“T”,如TColor,TWeekDay,而且单词以大写字母开始。
Type
  TWeekDay=(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
  TColor=(Red,Yellow,Blue,Green.Purple,White,Black);
枚举变量的第一个代表0,第二个 代表1,以此类推,如上面定义的TweekDay类型,Sunday=0,Monday=1,…,Saturday=6。
例题:输入今天的日期数字:0=Sunday,1=Monday,…6=Saturday,输出明天的日期,用英文单词表示。【xoi00_02.pas】
program xoi00_02;
Type TWeekDay=(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
var today,tomorrow:TWeekDay;
   number,i:integer;
begin
  write('Enter today number:');readln(number);
  if (number<0) or (number>6) then
    writeln('Error number')
  else begin
    today:=Sunday;
    for i:=0 to number-1 do today:=succ(today);
    if today=Saturday then
       tomorrow:=Saturday
    else
       tomorrow:=succ(today);
       write('Tomorrow is:');
       case tomorrow of
         Sunday:writeln('Sunday');
         Monday:writeln('Monday');
         Thursday:writeln('Thusday');
         Wednesday:writeln('Wednesday');
         Thursday:writeln('Thursday');
         Friday:writeln('Friday');
         Saturday:writeln('Saturday');
    end;{if today=saturday then}
  end;{if (number<0) or (number >6)}
end.

子界类型:
子界类型是在其它的离散类型的值域中取出一部分构成独立的类型。
子界类型的一般定义形式如下:
TYPE
<子界类型标识符>=<下界常量>..<上界常量>;
如:  TYPE Tmonth=1..12;
TYPE Tscore=0..100;
例 按月、日、年顺序读入一日期,输出该日期是这一年中的第几天。
 program date;
  var year:0..2010;
    month,i:1..12;
    day:1..31;
    dayth:integer;
 begin
  read(month,day,year);
  dyath:=0;
  for i:=1 to month-1 do
   case i of
    1,3,5,7,8,10,12:dayth:=dayth+31;
    2:if ((year mod 4=0)and(year mod 100<>0)or(year mod 400 =0)
     then dayth:=dayth+29
     else dayth=:=dayth+28;
    4,6,9,11:dayth:=dayth+30;
   end;
  dayth:=dayth+day;
  writeln(dayth)
 end.

数组类型:
定义数组:
Type
数组类型标识符=Array[下标类型] OF 数组元素类型
数组元素类型本身也可以是复杂的自定义类型,如子界类型,数组类型,记录等。
例如:定义存放学生姓名的字符数组:
TYPE TName=Array[1..20] of Char;
定义一个存放班级学生(50人)名单的数组:
TYPE TStudents=Array[1..50] of TName
也可以这么定义:
TYPE TStudents=Array[1..50] of Array[1..20] of Char;
例1:输入5个考分数,计算它们的总分。【xoi00_03.pas】
program xoi00_03;
Type TScore=Array[1..5] of integer;
var score:TScore; i:integer;sum:integer;
begin
  for i:=1 to 5 do
  begin
    write('Enter Number #',i);
    readln(score[i]);
  end;
  sum:=0;
  for i:=1 to 5 do
  begin
    sum:=sum+score[i];
  end;
  writeln('Total Score is:',sum);
end.

例2:从键盘输入10个数,将这10个数逆序输入,并求这10个数的和,输出这个和。
program p1;
var
  a: array[1..10] of integer;
  i, s: integer;
begin
  for i := 1 to 10 do
    read(a[i]);
  for i := 10 downto 1 do
    write(a[i], ' ');
  writeln;
  s := 0;
  for i := 1 to 10 do
    s := s + a[i];
  writeln('s=', s);
end.
例3:用筛法求100以内的素数(质数)。
分析:素数是除了1和它本身以外没有其它约数的数。用筛法求素数的方法是:用质数筛去合数:从第一个素数2开始,把它的倍数去掉;这样2以后的第一个非0数就一定也是素数,把它的倍数也删了……重复这个删数过程,直到在所找到的素数后再也找不到一个非0数。把所有非0数输出。
program p2;
var
  a: array[1..100] of integer;
  i, j, k: integer;
begin
  for i := 1 to 100 do
    a[i] := i;
  a[1] := 0;
  i := 2;
  while i <= 100 do
    begin
      k := i;
      while k <= 100 do
        begin
          k := k + i;
          a[k] := 0;
        end;
      {----上面将所有a[i]的倍数清0}
      i := i + 1;
      while a[i] = 0 do
        i := i + 1;
      {----查找接下来的第一个非0数}
    end;
  for i := 1 to 100 do
    if a[i] <> 0 then write(a[i], ' ');
end.
 
字符串类型:
如果数组存放的是字符,则成为字符数组。例如前面提到的学生姓名:Tname可以存放20个字符。为了操作方便Turbo Pascal 提供了字符串类型和操作函数。字符串类型:String。例如前面的学生姓名可以定义为:Type TName=String[20];
字符串定义时,如不指定长度,则按该类型的最大长度(255个字符)分配空间,使用时最大可用长度为255个;如果在中括号中给出一个具体的值(1—255之间),则按这个值的大小分配空间。使用时,最大的可用长度即为该值。
字符串类型既可按数组方式输入、输出,也可直接输入、输出:readln(s);writeln(s);多个字符串输入时以回车作为数据间的分隔符;每个readln语句只能读入一个字符串。
操作函数:
连接函数:concat(s1,s1,…,sn),相当于:S1+S2+…+Sn
截取子字符串:copy(S,I,L),从字符串S左边第I个字符起连续截取L个字符。
长度函数:length(S),计算字符串S的长度。Length(S)=Ord(S[0])
子串点的函数:pos(P,S),返回P在S中第一次出现的位置。
删除子串过程:delete(S,I,L),在S中从的I个字符起删除L个字符。
插入子串函数:insert(S,D,L),在D中的第I个字符位置插入字符串S。

记录类型:
记录类型由固定数量的具有不同类型的成分组成,在实际的程序设计中,这种类型非常有用,比方说学生的信息包括:学号,姓名,语文数学英语成绩,平均分等组成,用一个简单的数据类型无法表达。我们可以这样定义:
Type
TScore=0..100;
TScores=Array[1..5] of TScore;
TStudent=Record
NO:String[5];
Name:String[16];
Score:TScores;
Avg:Real;
End;{End Type TStudent}
TStudents=Array[1..50] of TStudent;

在程序中可以使用Var student:Tstudents;定义一个学生变量,可以使用student[1].Name来访问学生的姓名。

集合类型:
集合是指相同类型的数据汇集在一起构成的数据结构,如学生集合,类似于数学中的集合,但是构成集合的数据类型必须是简单的离散类型,如:Byte,Shortint,Longint,char,Boolean,枚举,子界类型。
定义:
Type
<集合数据类型标识符>= Set of <基类型>;
例如:
Type UperLetters= Set of [‘A’..’Z’];
Type EvenDigits=Set of [0,2,4,6,8];
集合的运算:并:+;差:-;相等:=;不等:<>;包含:>=;包含于:<=;属于:in;
具体含义参考数学中的集合运算。

例4:传说中有一个残暴的国王,喜欢杀戮百姓。有一次,他抓到30个百姓并要一一杀掉。在这30个百姓中间有一个聪明人,他站出来对国王说:“请国王大发慈悲,赦免二人不死。”国王问:“赦免哪二人不死?”那个聪明人回答说:“我们30个人围成一圈,从1开始报数,凡数到5的人就拉出去杀掉。剩下的人继续从1开始报数,循环反复,直到剩下两个人为止,这两个人被赦免。”国王一听很有意思,采纳了聪明人的建议,赦免了两个人,而那个聪明人就是其中之一。请你设计一个程序,由计算机判断聪明人要站在什么位置,才能躲过这一场屠杀。
问题分析:
首先,设百姓的人数为M人,设数到N的人被杀掉。用数组A(M)存放M个人是否还在圈中的信息。其中,A(I)=1 表示第I个人还在圈中。A(I)=0 表示第I个人已被杀掉。开始时,数组A中所有的元素都是1,表示每个人都站在圈中。用K=K+A(I)来实现报数功能,因为只有还在圈中的人才能使K的值增加。用变量D来记录出圈的人数,当D=M时,表示所有的人都出圈了。最后出圈的两个人就是被赦免的人。
程序清单:【xoi00_05.pas】
program xoi00_05;
const m = 100;
const n = 10;
var a: array[1..m] of integer;
  i, d, k, p: integer;
begin
  writeln; writeln('====================');
  for i := 1 to m do a[i] := 1;
  d := 0; k := 0;
  while true do begin
    for i := 1 to m do begin
      k := k + a[i];
      if k <> n then continue;
      write(i: 4);
      p := p + 1;
      if p > 9 then begin p := 0; writeln; end;
      a[i] := 0;
      k := 0;
      d := d + 1;
      if d = m then exit;
    end;
  end; {while}
end.

例5:输入一个十进制数,将其转换成二进制数。
输入:[KEYBOARD] 输出:[SCREEN]
255
FF
[问题分析] 模拟手算.
program bin;
const max = 20;
var i, j: integer; str: array[1..max] of byte;
procedure print;
var k, r: integer;
begin
  k := max;
  repeat
    dec(k);
  until str[k] = 1;
  for r := k downto 1 do write(str[r]);
  writeln;
end;
begin
  write('Please input an integer between 1..32767:'); readln(i);
  j := 0;
  repeat
    inc(j);
    str[j] := i mod 2; i := i div 2;
  until i = 1;
  str[j + 1] := 1;
  print;
end.

练习
1、 数学黑洞6174:已知:一个任意的四位正整数。将数字重新组合成一个最大的数和最小的数相减,重复这个过程,最多七步,必得6174。即:7641-1467=6174。将永远出不来。求证:所有四位数数字(全相同的除外),均能得到6174。输出掉进黑洞的步数。
2、 随机产生20个三位数,将这20个数按从小到大的顺序排列,要求在排列中,用尽可能少的交换次数。
3、 输入10个学生的姓名,编一程序将它们按字母的顺序排列。
4、 有一组数,其排列形式如下:11,19,9,12,5,20,1,18,4,16,6,10,15,2,17,3,14,7,13,8,且尾部8和头部11首尾相连,构成环形的一组数,编程找出相邻的4个数,其相加之和最大,并给出它们的起始位置。
5、 有一组数其排列顺序如下:(设有N个)3,6,11,45,23,70,67,34,26,89,90,15,56,50,20,10。编一程序交换这组数中任意指定的两段。
6、 有M个猴子围成一圈,每个有一个编号,编号从1到M。打算从中选出一个大王。经过协商,决定选大王的规则如下:从第一个开始,每隔N个,数到的猴子出圈,最后剩下来的就是大王。要求:从键盘输入M,N,编程计算哪一个编号的猴子成为大王。
7、 请你设计一个程序,让计算机找出40个自然数来,使得其中任意两个数之差均不相等。
问题分析:
首先,开辟一个数组S(I),准备存放这40个数,再开辟一个数组CHA(I),用来存放两个数的差。
寻找某一个满足条件的自然数的过程如下:
把1和2放进数组S中; 把1放进数组CHA中; 当寻找下一个自然数时,要把这个自然数与数组S中的每一个数相减,再判断所得的差是否在数组CHA中;如果所得的差不在数组CHA中,说明又找到一个满足条件的自然数。把这个自然数放进数组S中,同时把这个自然数与数组S中原有的每一个自然数的差记录在数组S中去。如果所得的差与数组CHA中的某一个数重复,说明这个自然数不符合条件,继续寻找下一个自然数。 重复步骤(3),直到找到40个自然数为止。

第七节 常用函数

Pascal中的数学函数

求绝对值函数abs(x)
定义:function Abs(X): (Same type as parameter);
说明:X可以是整型,也可以是实型;返回值和X的类型一致
例子:
var
r: Real;
i: Integer;
begin
r := Abs(-2.3); { 2.3 }
i := Abs(-157); { 157 }
end.
取整函数int(x)
定义:function Int(X: Real): Real;
注意:X是实型数,返回值也是实型的;返回的是X的整数部分,也就是说,X被截尾了(而不是四舍五入)
例子:
var R: Real;
begin
R := Int(123.567); { 123.0 }
R := Int(-123.456); { -123.0 }
end.
截尾函数trunc(x)
定义:function Trunc(X: Real): Longint;
注意:X是实型表达式. Trunc 返回Longint型的X的整数部分
例子:
begin
Writeln(1.4, ' becomes ', Trunc(1.4)); { 1 }
Writeln(1.5, ' becomes ', Trunc(1.5)); { 1 }
Writeln(-1.4, 'becomes ', Trunc(-1.4)); { -1 }
Writeln(-1.5, 'becomes ', Trunc(-1.5)); { -1 }end.

四舍五入函数round(x)
定义:function Round(X: Real): Longint;
注意:X是实型表达式. Round 返回Longint型的X的四舍五入值.如果返回值超出了Longint的表示范围,则出错.
例子:
begin
Writeln(1.4, ' rounds to ', Round(1.4)); { 1 }
Writeln(1.5, ' rounds to ', Round(1.5)); { 2 }
Writeln(-1.4, 'rounds to ', Round(-1.4));{ -1 }
Writeln(-1.5, 'rounds to ', Round(-1.5));{ -2 }
end.
取小数函数frac(x)
定义:function Frac(X: Real): Real;
注意:X 是实型表达式. 结果返回 X 的小数部分; 也就是说,Frac(X) = X - Int(_X).
例子:
var
R: Real;
begin
R := Frac(123.456); { 0.456 }
R := Frac(-123.456); { -0.456 }
end.


求平方根函数sqrt(x)和平方函数sqr(x)
定义:平方根:function Sqrt(X: Real): Real;
注意:X 是实型表达式. 返回实型的X的平方根.
平方:function Sqr(X): (Same type as parameter);
注意:X 是实型或整型表达式.返回值的类型和X的类型一致,大小是X的平方,即X*X.
例子:
begin
Writeln('5 squared is ', Sqr(5)); { 25 }
Writeln('The square root of 2 is ',Sqrt(2.0)); { 1.414 }
end.

字符串函数
求长度length
定义:function Length(S: String): Integer;
例子:
var
S: String;
begin
Readln (S);
Writeln('"', S, '"');
Writeln('length = ', Length(S));
end.
复制子串copy
定义: function Copy(S: String; Index: Integer; Count: Integer): String;
注意:S 是字符串类型的表达式。Index和Count是整型表达式。Copy 返回S中从Index开始,Count个字符长的一个子串。
例子:
var S: String;
begin
S := 'ABCDEF';
S := Copy(S, 2, 3); { 'BCD' }
end.
插入子串insert
定义:procedure Insert(Source: String; var S: String; Index: Integer);
注意:Source 是字符串类型的表达式。 S 是任意长度字符串类型变量。Index 是整型表达式。Insert 把 Source插在S中Index处。如果结果字符串的长度大于255,那么255之后的字符将被删除。

例子:
var
S: String;
begin
S := 'Honest Lincoln';
Insert('Abe ', S, 8); { 'Honest Abe Lincoln' }
end.
删除子串delete
定义:procedure Delete(var S: String; Index: Integer; Count:Integer);
注意:S 是字符串类型变量。 Index和Countare是整型表达式。Delete 删除S中从Index开始的Count个字符。如果Index大于S的长度,则不删除任何字符;如果Count大于S中从Index开始的实际字符数,则删除实际的字符数。

例子:
var
s: string;
begin
s := 'Honest Abe Lincoln';
Delete(s,8,4);
Writeln(s); { 'Honest Lincoln' }
Delete(s,9,10);
Writeln(s); { 'Honest L' }
end.
字符串转为数值val
定义: procedure Val(S; var V; var Code: Integer);
在这里:
S 是由一系列数字字符构成的字符串类型变量;。
V 是整型或实型变量;
Code 是Integer型变量
注意:Val将S转为它的数值形式。
例子:
var s:string;I, Code: Integer;
begin
s:='1234';
val(s,i,code);
writeln(i); { 1234 }
end.
数值转为字符串str
定义: procedure Str(X [: Width [: Decimals ]]; var S:string);
注意:将数值X转成字符串形式。
例子:
var
S: string[11];
begin
Str(I, S);
IntToStr := S;
end;
begin
Writeln(IntToStr(-5322));
Readln;
end.
求子串起始位置pos
定义:function Pos(Substr: String; S: String): Byte;
注意:Substr和S字符串类型表达式。Pos在S中搜索Substr并返回一个integer值。这个值是Substr的第一个字符在S中的位置。如果在S中没有找到Substr,则Pos返回0。
例子:
var S: String;
begin
S := ' 123.5';
{ Convert spaces to zeroes }
while Pos(' ', S) > 0 do
S[Pos(' ', S)] := '0';
end.
字符完全串连+
定义:操作符+把两个字符串联在一起。
例子:
var s1,s2,s:string;
begin
s1:='Turbo ';
s2:='pascal';
s:=s1+s2; { 'Turbo pascal' }
end.
字符串压缩空格串连-
定义:操作符-去掉第一个字符串最后的空格后,将两个字符串联在一起。
例子:
var s1,s2,s:string;
begin
s1:='Turbo ';
s2:='pascal';
s:=s1-s2; { 'Turbopascal' }
end.

第八节 指针

指针的动态变量
1.定义指针类型
  在Turbo Pascal中,指针变量中存放的某个存储单元的地址,即指针变量指向某个存储单元。一个指针变量仅能指向某一种类型的存储单元,这种数据类型是在指针类型的定义中确定的,称为指针类型的基类型。指针类型定义如下:
   类型名=^基类型名;
例如:type q=^integer;
   var a,b,c:q;
  说明q是一指向整型存储单元的指针类型,其中"^"为指针符。a,b,c均定义为指针变量,分别可以指向一个整型存储单元。
  上例也可定义为:
    var a,b,c:^integer;
  指针也可以指向有结构的存储单元。
例如:type person=record
         name:string[10];
        sex:(male,female);
        age:20..70
      end;
   var pt:^person;
  pt为指向记录类型person的指针变量。
2.动态变量
  应用一个指针指向的动态存储单元即动态变量的形式如下:
    指针变量名^
例如:p^、q^、r^
  指针变量p和它所指向的动态变量^p之间有如下关系:
P->P'
以下语句把整数5存放到p所指向的动态变量p^ 中去:
p^:=5;
以下语句把p所指向的p^中的值赋给整型变量i:
i:=p^;
如果指针变量p并未指向任何存储单元,则可用下列赋值语句:
p:=nil;
其中nil是Turbo Pascal保留字,表示“空”,相当于C里面的null
对动态变量的操作
  在Turob Pascal程序中,动态变量不能由var直接定义而是通过调用标准过程new建立的。过程形式为:
    new(指针变量名);
  如果有下列变量定义语句:
   var p:^integer;
  仅仅说明了p是一个指向整型变量单元的指针变量,但这个整型单元并不存在,在指针变量p中还没有具体的地址值。在程序中必须通过过程调用语句:new(p);才在内存中分配了一个整型变量单元,并把这个单元的地址放在变量p中,一个指针变量只能存放一个地址。在同一时间内一个指针只能指向一个变量单元。当程序再次执行new(p)时,又在内存中新建立了一个整型变量单元,并把新单元的地址存放在p中,从而丢失了旧的变量单元的地址。
  为了节省内存空间,对于一些已经不使用的现有动态变量,应该使用标准过程dispose予以释放。过程形式为:dispose(指针变量名);为new(指针变量名)的逆过程,其作用是释放由指针变量所指向的动态变量的存储单元。例如在用了new(p)后在调用dispose(p),则指针p所指向的动态变量被撤销,内存空间还给系统,这时 p的值为 nil。
例:输入两个数,要求先打印大数后打印小数的方式输出,用动态变量做。
 program dongtai;
  type intepter=^integer;
  var p1,p2:intepter;
  procedure swap(var,q1,q2:intepter);
   var p:integer;
  begin
   p:=q1;q1:=q2;q2:=p;
  end;
 begin
  new(p1);new(p2);
  writeln('input 2 data: ');readln(p1^,p2^);
  if p1^  then writeln('output 2 data: ',p1^:4,p2^:$);
 end.

第九节 文件操作

类型文件
  按数据的二进制代码形式存放时的文件称为类型文件。如果再按照组成类型文件的元素数据结构分,又可以分为有类型文件和无类型文件。其定义为:
   type 类型名=file of 基类型;{有类型文件}
     类型名=file;    {无类型文件}
  例如:var f:file of integer;
     说明f为名的变量对应文件将用于存放整数。
     var g:file;
     说明g为名的变量对应文件的数据无任何规定。
  Turbo Pascal有关类型文件的函数和过程
(1)assign过程
  形式:assign(f,str);
  功能:将文件名字符串str赋给文件变量f,程序对文件变量f的操作代替对文件str的操作。
(2)rewrite过程
  形式:rewrite(f);
  功能:建立并打开一个新的允许写磁盘文件,其文件名必须先由assign过程赋给变量f。这时,指向文件元素的指针指向第一个元素,rewrite过程所建立的文件为空文件。
(3)reset过程
  形式:reset(f);
  功能:打开一个已经存在的磁盘文件,其文件名必须先由assign过程赋给变量f,该文件只能读,指向文件元素的指针指向第一个元素。
(4)read过程
  形式:read(f,var表);
  功能:从磁盘文件f中,将数据依次读到var表表示的各个变量中。
(5)write过程
  形式:write(f,var表);
  功能:将var表所表示的各个变量的值依次写到磁盘文件f上。
(6)close过程
  形式:close(f);
  功能:关闭和f关联的磁盘文件,在写操作时自动产生一个文件结束标志。
(7)seek过程
  形式:seek(f,n);
  功能:把文件指针移到f指明文件的第n个元素。
(8)eof函数
  形式:eof(f);
  功能:若文件指向文件尾,则返回true,否则返回false。
  对有类型文件的写操作步骤为:
   assign(f,str);
   rewrite(f);
   write(f,var表);
   close(f);
  对有类型文件的读操作步骤为:
   assign(f,str);
   reset(f);
   read(f,var表);
   close(f);
例:在磁盘上建立一个1~50的平方数的数据文件zhoufei.dat。要求以一个数,这个数的平方数的格式写入。
  program zhoufei;
   var f:file of integer;
   i:integer;
  begin
   assign(f,'zhoufei.dat');
   rewrite(f);
   for i:=1 to 50 do write(f,i,sqr(i));
   close(f)
  end.
文本文件
  文本文件的内容有ASCII字符集中的字符组成,因此文本文件也称ASCII码文件,它可以用DOS中的type命令列出内容。文本文件具体是由一系列行组成,每一行可以包括0个或多个字符型成分,并以也行结束符结尾,文本文件类型TXT和类型文件file of char区别在于后者不包含行结束符。
  文本文件和类型文件在读写上的差别在于前者只能按次序顺序读写,而后者可以不按照次序读写。适用文本文件的函数和过程除了用于类型文件操作的过程和函数外主要还有:
(1)readln过程
形式:readln(f,var表);或readln(f);
功能:从磁盘文件f中,将数据依次读到var表表示的各变量中(其中readln(f)只读数据),并将文件指针移到行结束符后,就是下一行开头。
(2)writeln过程
  形式:writeln(f,var表)或writeln(f);
  功能:将var表所表示的各个变量的值依次写到磁盘文件f上去(writeln(f)不写值),然后再写一个行结束符。
(3)append过程
  形式:append(f);
  功能:打开一个已经存在的磁盘文件,其文件名必须和assign过程中的变量名f相对应,该文件只能写,此时文件指针指向文件尾。
(4)eoln函数
  形式:eoln(f);
  功能:若文件指针指向行结束符或文件结束符,则返回true,否则返回false。
  对文本文件的写操作步骤:
   assign(f,str);
   rewrite(f);  或append(f);
   write(f,var表);或writeln(f);
   close(f);
  对文本文件的读操作步骤:
   assign(f,str);
   reset(f);  
   readln(f,var表);或readln(f);
   close(f);
例:随机产生30个随机整数存放于文本文件zhoufei.txt 中
  program zhoufei;
   const n=30;
   var ra:text;
     i:integer;
  begin
   randomize;
   assign(ra,'zhoufei.txt');
   rewrite(ra);
   for i:=1 to n do writeln(ra,random(100));
close(ra)
end.
 
练习
1、从键盘输入一行字符,把输入的字符存入磁盘文件中。
2、编一个程序,从磁盘读入一个文本文件(英文字符),统计文件中的字符数目和单词数目(假设单词以空格、逗号、分号、句号分隔,文章中不含有其它分隔字符)。

【综合实验】:文件、统计管理
    编写一个建立学生基本情况的直接存取文件,并能根据学生编号检索其基本情况的程序。【xoi0015.pas,演示程序:DEM00_06.rar】
    学生基本情况存储在记录student内,他有编号、姓名、性别、年龄和五门课成绩五个域。采用直接存取方式利用seek过程存贮记录数,由于学生编号从10001-29999,因此,记录数为编号数减10000。为了确定检索已结束,最后的编号为65535。如果根据编号已检索到该生,这输出其基本情况,如果检索不到,程序中自动将编号加1,重复检索,直到编号65535,仍未检索到则表示没有该生的记录,可以继续检索其它学生的基本情况。
(1)算法:
  a.定义一个记录文件
     TYPE
         student=RECORD
          number:word;
          name:lstring(10);{lstring,IBM Pascal提供的高级数组类型:L串。
                             name为可变字符串,其可变字符长度为10}
          sex:lstring(6);
          age:integer;
         grades:array[1..5] of real
         end;
         VAR
             i:integer;
         total,avg:real;
         n,m:word;
         answer,c:char;
         buf:student;
         sfile:file of student;
         t:boolean;
 b.建立一个记录文件并输入记录 
    assign(sfile,'student.bat');
    sfile.mode:=DIRECT;
    rewrite(sfile);
    answer:=' ';
    while (answer<>'.') do
       begin
           write('Enter student number(10001-29999) ');
           write('name,sex(f-m),age..');
           with buf do
              begin
               readln(number);readln(name);
               readln(sex);readln(age);
               writeln('sc1,sc2,sc3,sc4,sc5 ');
               for i:=1 to 5 do
                   readln(grades[i]);
               seek(sfile.number-10000)
            end;
          write(sfile,buf);
          writeln('type''''.'''' to end');
          readln(answer)
       end;
     seek(sfile,buf.number+1-10000);
     buf.number:=65535;
     write(sfile,buf);
     close(sfile);
 c.根据输入的学生编号检索学生的基本情况
     sfile.mode:=direct;
     reset(sfile);
     t:=false;
     write('Enter students number(10001-29999)..');
     readln(n);m:=n;
     writeln(' grades report');
     write('number':6,'name':10);
     write('age':4,'sex':4,' ');
     write('total':5,'1':5,'7':5);
     write('3':5,'4':5,'5':5 ');
     writeln('avg':5);
     while not t do
         begin
           seek(sfile,m-10000);
           get(sfile);buf:=sfile^;
           with buf do
             begin
               if number=65535 then
                 begin
                   writeln('not found this student ');
                   t:=true
                 end
               else if number=n then
                 begin
                   t:=true;
                   total:=0;
                   for i:=1 to 5 do
                      total:=total+grades[i];
                   avg:=total/5;
                   write(number:6,name:10,age:4,' ');
                   write(sex:4,' ',total:5:1,' ');
                   for i:=1 to 5 do
                     write(' ',grades[i]:4:1);
                   writeln(' ',avg:4:1,' ')
                 end
               else
                 begin
                   t:=true;
                   writeln('not found');
                   m:=m+1
                 end
             end
         end;

上一篇:没有了!

下一篇:带格式的输出语句及输入语句