2.表达式
(1)算术表达式:算术表达式是由算术运算符连接常量、变量、函数的式子。算术表达式中各个运算符的次序为: ( )-->函数-->*,/,div,mod-->+,1
(2)布尔表达式:Turbo Pascal提供给布尔表达式以下基本操作:逻辑运算和关系运算。
3.1 赋值语句
赋值语句是最简单的语句,其一般形式为:
<变量>:=<表达式>
赋值语句的作用是计算表达式的值,并赋给变量。对于任何一个变量必须首先赋值,然后才能引用,否则,未赋初值的变量将以一个随机值参与运算。另外,赋值号两边的类型必须相同,但表达式值为整数时,它可自动化为实型后赋给该实型变量,即符合赋值相容。
例:关于赋值的例子
program example;
var a,b:integer;
begin
a:=3;b:=2;
writeln(a);
writeln(b);
a:=a+b;
writeln(a);
writeln(b);
b:=a-b;
writeln(a);
writeln(b);
a:=a-b;
writeln(a);
writeln(b);
readln
end.</P><P>
3.2 输入语句
通过计算机的外设把数据送到计算机内存的过程称为输入。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语句中可以不包含变量名表。即有以下等价情况:
readln(a,b);readln等价于readln(a,b)
输入语句输入的数据类型必须和变量一一对应。如果输入的是一串整数或实数,数据间用空格或回车分隔;若输入的是一串字符,则不用分隔。
例:输入语句示例
program shuru;
var
x:real;
c:char;
begin
write('please input the number: ($XXX.XX)');
readln(c,x);
writeln('The price is ',c,x)
end.
3.3 输出语句
输出是将内存中的数据送到外设的过程。Turbo Pascal的输出语句有两种形式:
write(<输出项表>)
writeln(<输出项表>)
其中<输出项表>是一串用逗号分隔的常量、变量、函数名、表达式或字符串。如果是变量、函数名、表达式,则将其计算结果输出;如果是常量或字符串,则直接输出其值。
writeln和writeln的区别在于:write语句是输出项输出后,不换行,光标停留在最后一项后,writeln语句按项输出后,自动换行,光标则停留在下一行的开始位置。
writeln语句允许不含有输出项,即仅writeln;表示换行。
Turbo Pascal语言把输出项的数据显示占用的宽度称为域宽,你可以根据输出格式的要求在输出语句中自动定义每个输出项的宽度。定义宽度时分为单域宽和双域宽。
(1)单域宽输出格式:
writeln(I:n)
在n个字符宽的输出域上按右对齐方式输出I的值,若n大于I的实际位数,则在I值前面补(n-I的实际位数)个空格。若I的实际位数大于n,则自动突破限制。n必须是整数。
(2)双域宽输出格式:
writeln(a:m:n)
双域宽主要用于实型数据的输出。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.
3.4 复合语句
复合语句是由若干语句组成的序列,语句之间用分号“;”隔开,并且以begin和end括起来,作为一条语句。复合语句的一般形式:
begin
语句1;
语句2;
……
语句n;
end
例:变量值的交换
program jiaohuan;
var
a,b,t:integer;
begin
a:=10;b:=20;
begin
t:=a;
a:=b;
b:=t;
end;
writeln('a=',a,'b=',b)
end.
第四章 选择结构程序设计
4.1 if语句
IF语句是由一个布尔表达式和两个供选择的操作序列组成。运行时根据布尔表达式求值结果,选取其中之一的操作序列执行。有两种形式的IF语句:
if <布尔表达式> then <语句>;
if <布尔表达式> then <语句1>
else <语句2>;
当布尔表达式的值为真,则执行then后面的语句,值为假时有两种情况:要么什么也不做,要么执行else后面的语句。注意else前面没有分号,因为分号是两个语句之间的分隔符,而else并非语句。如果在该处添了分号,则在编译的时候就会认为if 语句到此结束,而把else当作另一句的开头,输出出错信息。
例:求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 lianxie3;
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配对。
4.2 case语句
case语句是由一个表达式和众多可选择的操作序列组成。运行时,根据表达式的求值结果,在众多的分支中选取一个分支执行。其形式为:
case 表达式 of
常量1:语句1;
常量2:语句2;
……
常量n:语句n;
else 语句 n+1 {可选项}
end;
表达式只能是顺序类型(除了实型以外的简单类型),其值必须是唯一确定并且和表达式类型相同。case语句执行和表达式值相匹配的case常数所指向的那条语句,如果没有相匹配的值,则执行else部分(如果有的话)或者什么也不做。在else前面的语句末尾有分号,这是和if语句不同的。
例:根据学生的成绩给予相应的等低,对应关系如下:
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:='B';
8:ch:='B';
7,6:='C';
else ch:='D';
end;
writeln(s,'--',ch);
end.
第五章 循环结构程序设计
5.1 while语句
while语句用于“当满足某一条件时进行循环”的情况。while语句的语法格式:
while 布尔表达式 do 语句;
循环结束条件在进入循环体之前测试,若最初的测试值为false,则根本不进入循环体,也就是说while循环是是属于当型循环。为了能使while重复能终止,循环体中一定要有影响布尔表达式的操作,否则该循就是一个死循环。
例:计算从0到某个数之间所有奇数的和。
program jishu;
var odds,limit,sum:integer;
begin
readln(limit);
sum:=0;
odds:=1;
while odds<=limit do
begin
sum:=sum+odds;
odds:=odds+2
end;
writeln(sum:1)
end.
5.2 repeat语句
repeat 语句用于“重复执行循环体,一直到指定的条件为真时为止”。语法格式为:
repeat
语句1;
……
语句n;
until 布尔表达式;
repeat重复基本上有和while重复一样的描述循环计算的能力,但有一些不同:在repeat语句的结构中,布尔表达式求值在计算操作之后,而while语句中,布尔表达式求值在计算操作之前,也就是说repeat至少执行一次循环体。while语句的成分语句只能是一个语句。因此,当重复动作包含多个语句时,要用begin和end ,使它变成一个复合语句。而repeat语句的保留字repeat和until已经起语句括号作用,可以包含多个语句而无须begin和end。repeat语句中,当布尔表达式为true时结束循环,而while语句中,是当表达式为false时才结束循环。当描述由计算操作后的情况确定重复是否继续进行的计算时,通常用repeat语句描述。
5.3 for 语句
for 语句用来描述已知重复次数的循环结构。for 语句有两种形式:
(1) for 控制变量:=初值 to 终值 do 语句;
(2) for 控制变量:=初值 downto 终值 do 语句;
第一种形式的for 语句是递增循环。首先将初值赋给控制变量,接着判断控制变量的值是否小于或等于终值,若是,则执行循环体,在执行了循环体之后,自动将控制变量的值该为它的后继值,并重新判断是否小于或等于终值。当控制变量的值大于终值时,退出for循环,执行for语句之后的语句。第一种形式的for 语句是递减循环。首先将初值赋给控制变量,接着判断控制变量的值是否大于或等于终值,若是,则执行循环体,在执行了循环体之后,自动将控制变量的值该为它的前趋值,并重新判断是否大于或等于终值。当控制变量的值小于终值时,退出for循环,执行for语句之后的语句。for 语句中的初值、终值、控制变量的数据都必须是顺序类型。当初值和终值确定后,重复的次数就确定不变了,并且控制变量在重复语句内不能施加任何赋值操作。
例:计算1+2+3+……+99+100
program jia;
var n,sum:integer;
begin
sum:=0;
for i:=1 to 100 do
sum:=sum+i;
writeln(sum);
end.
5.4 goto语句
goto语句是一种无条件转向语句,它可以控制直接从程序的一条语句转向另一条语句。goto语句的语法形式为:
goto 标号;
其中标号必须是不超过4位整数的正整数或标识符组成,但标号必须在说明语句中先予以说明。
goto语句会使程序出现一种称为“乱面条”的结构,因此你最好还是不要去用。
第六章 枚举型和子界型
6.1 类型定义
类型定义的语法格式:
type
<标识符1>=<类型1>;
<标识符1>=<类型1>;
……
<标识符n>=<类型n>;
6.2 枚举类型
通过预定义列出所有值的标识符来定义一个有序集合,这些值的次序和枚举类型说明中的标识符的次序识一致的。枚举类型的形式:(标识符1,……,标识符n)
例如:type daystype=(sunday,monday,tuesday,wednesday,thursday,friday,saturday)
枚举元素只能是标识符,而不能是数值常量或字符常量。例如以下的定义是错误的:
type daystype=('sun','mon','tue','wed','thu','fri','sat')
枚举元素是标识符,不要把作为枚举元素的标识符视作变量名,它不能被赋值。同一个枚举元素不能出现在两个或两个以上的枚举类型定义中。例如以下的定义是错误的:
type daytype1=(monday,tuesday);
daytype2=(monday,wednesday);
可以将枚举类型的定义和变量的定义结合在一起。例如:var a:(monday,tuesday,sunday)
枚举类型属于顺序类型。根据定义类型时各枚举元素的排列顺序确定它们的序列,序列号从0开始。
例如:已经定义daystype
ord(sunday)=0,succ(sunday)=monday,pred(friday)=thursday
但是枚举类型中的第一个元素没有前趋,最后一个元素没有后继。Turbo Pascal不允许直接读写枚举值,所以枚举值的输出常用case语句间接的输出。枚举值的输入,则要一一判断读入字符是否是枚举类型的标识符。若是才能赋给枚举变量,否则就会出错。
例如:枚举值的输出
case day of
sunday:write('sunday');
monday:write('monday');
tuesday:write('tuesday');
wednesday:write('wednesday');
thursday:write('thursday');
friday:write('friday');
saturday:write('saturday');
end;
6.3 子界类型
子界类型是由整型、字符型、枚举型、布尔型的两个常量指定该类型的值域区间。子界类型的形式:
常量..常量
两个常量必须是同一种顺序类型。例如:a..b,要求a<=b
例如:
type a=1..3;
b='a'..'d';
一个子界类型继承它的常量类型的运算符和标准函数,常量类型相容的不同子界类型可以混合运算,可以赋值。可以将子界类型的定义和变量的定义结合在一起。例如:var a:1..9
例 按月、日、年顺序读入一日期,输出该日期是这一年中的第几天。
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.
例如:[A,B,C]=[A,B,C] 等于true
[A,B,C]<>[C,B,A] 等于FALSE
9.2 记录
记录是描述同一对象的一组类型可能不同的数据的集合。使用记录类型实现了数据逻辑关系和存放形式上的一致。定义记录类型的一般形式
记录类型名=record
域名1:类型1;
域名2:类型2;
……
域名m:类型m;
end;
例如:表示学生信息的记录定义
type
stype=record
name:string[20];
number:integer;
sex:(male,female);
class:1..20
address:string
end;
域为记录类型的元素。记录的每个域都有名称,不同域的数据类型可以各不相同,这一点是数组所不能做到的。引用记录变量的元素采用以下标记法:
(1)直接引用,其形式为
记录变量名.域名
例如:var str1,str2:stype;
则str1.name表示学生str1的姓名,str2.sex表示学生str2的性别。
(2)使用with开域语句,其形式为
with 记录变量名 do 语句
在with语句中,引用记录变量名不再冠以记录变量名,以简化对记录中域的引用写法。例如描述100个学生的数据信息,引入元素类型为stype的数组students。
var
students:array[1..100]of stype;
number_of_boy,number_of _girl,k:integer:
例如下面是一段统计一个班级中男生人数和女生人数的程序。
begin
number_of_boy:=0;number_of_girl:=0;
for k:=1 to 100 do
with student[k] do
if sex=male then number_of_boy:=number_of_boy+1
else number_of_girl:=number_of_girl+1
end;
with语句的嵌套结构的一般形式:
with <记录变量名1> do
with <记录变量名2> do
……
with <记录变量名n> do
<语句>;
使用with嵌套结构时,with的嵌套顺序必须和所打开的记录的嵌套顺序一致,以就是说外层with打开外层记录,内层with打开内层记录。上面的嵌套格式也可以简写为:
with <记录变量名1,记录变量名2,……,记录变量名n> do
<语句>;
若记录是由一部分固定不变和另一部分变化部分是随固定部分中的某个数据项的具体取值而定的数据项所组成的称为记录变体。带记录变体的记录类型定义有以下形式:
type
<类型标识符>=record
<域名1>:<类型1>;
<域名2>:<类型2>;
……
<域名n-1>:<类型n-1>;
case <标志域>:<类型n> of
<常量表1>:<域表1>;
<常量表2>:<域表2>;
……
<常量表m>:<域表m>;
end;
例:重新定义描述学生信息的记录类型stype,对于大专生,不需要增加其他信息,对于本科生,增加专业信息。
type
stype=record
name:string[20];
number:integer;
sex:(male,female);
class:1..20
address:string
case studtype:(s,u) of
s:( );
u:(major:string);
end;
第十章 指针
10.1 指针的动态变量
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之间有如下关系:
10.2 对动态变量的操作
在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^
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.