readln(a,b);
until (a>0)and(b>0)and(a
writeln('List of all perfect numbers:');
{从a到b逐个判断,是完全数则打印出来
for i:=a to b do
if perfect(i) then writeln(i);
end.
自定义函数只是主程序的说明部分,若主程序中没有调用函数,则系统不会执行函数子程序。当主程序调用一次函数时,则将实在参数的值传给函数的形式参数,控制转向函数子程序去执行,子程序执行完毕后自动返回调用处。
二、过程
在pascal中,自定义过程与自定义函数一样,都需要先定义后调用。函数一般用于求值,而过程一般实现某些操作。
(一)过程的说明
过程说明的一般格式为:
procedure <过程名> (<形式参数表>); {过程首部}
说明: ①过程首部以关键字procedure开头。
②过程名是用户自定义的标识符,只用来标识一个过程,不能代表任何数据,因此不能说明"过程的类型"。
③形参表缺省(当然要同时省去一对括号)时,称为无参过程。
④形参表的一般格式形式如下:
[var] 变量名表:类型;…;[var] 变量名表:类型。
其中带var的称为变量形参,不带var的称为值形参。在函数中,形参一般都是值形参,很少用变量形参(但可以使用)。例如,下列形参表中:
(x,y:real;n:integer;var w:real;var
k:integer;b:real)
x、y、n、b为值形参,而w、k为变量形参。
调用过程时,通过值形参给过程提供原始数据,通过变量形参将值带回调用程序。因此,可以说,值形参是过程的输入参数,变量形参是过程的输出参数。有关变参,这在后面内容具体叙述。
⑤过程体与程序、函数体类似。与函数体不同的是:函数体的执行部分至少有一个语句给函数名赋值,而过程体的执行部分不能给过程名赋值,因为过程名不能代表任何数据。
⑥过程体的说明部分可以定义只在本过程有效的标号、常量、类型、变量、子程序等。
(二)过程的调用
过程调用是通过一条独立的过程调用语句来实现的,它与函数调用完全不同。过程调用与调与标准过程(如write,read等)的方式相同。调用的一般格式为:
<过程名>
或
<过程名>(实在参数表)
说明: ①实参的个数、类型必须与形参一一对应。
②对应于值形参的实参可以是表达式,对应于变量形参的实参只能是变量。
③过程调用的步骤为:计算实参的值;将值或变量的"地址"传送给对应的形参;执行过程体;返回调用处。
过程与函数有下列主要区别:
①过程的首部与函数的首部不同;
②函数通常是为了求一个函数值,而过程可以得到若干个运算结果,也可用来完成一系列的数据处理,或用来完成与计算无关的各种操作;
③调用方式不同。函数的调用出现在表达式中,而过程调用是一个独立的语句。
(三)过程的应用举例
例2 输出以下一个图形:
*
**
***
****
*****
******
分析:我们前面学习可用的二重循环打印出上图形, 现我们设置一个过程打印出N个连续的"*"号。
源程序如下:
program ex7_2;
var i:integer;
procedure draw_a_line(n:integer); {该过程打印出连续n 个星号,并换行}
var j:integer;
begin
for j:=1 to n do
write('*');
writeln;
end;
begin
for i:=1 to 6 do
draw_a_line(i);{调用过程,第I行打印i个连续星号}
end.
三、过程、函数的数据传递
在程序调用子程序时,调用程序将数据传递给被调用的过程或函数,而当子程序运行结束后,结果又可以通过函数名、变参。当然也可以用全局变量等形式实现数据的传递。这一节我们,就来研究参数传递与局部变量、全局变量等问题。
(一)数值参数和变量参数
前面已经讲过,pascal子程序中形式参数有数值形参(简称值参)和变量形参(变参)两种。事实上,还有函数形参和过程形参两种,只是应用并不太多,我们不作深入地研究。
1、值形参
值参的一般格式如§7.1.1所示。应该强调的是:
①形参表中只能使用类型标识符,而不能使用类型。
②值形参和对应的实参必须一一对应,包括个数和类型。
③实参和值形参之间数据传递是单向的,只能由实参传送给形参,相当赋值运算。
④一个特殊情况是,当值形参是实型变量名时,对应的实参可以是整型表达式。
⑤值形参作为子程序的局部量,当控制返回程序后,值形参的存储单元释放。
2、变量形参
变量形参的一般格式如§7.2.1所示,必须在形参前加关键字var。
应该注意的是:
①与变量形参对应的实参只能是变量名,而不能是表达式。
②与变量形参对应的实参可以根据需要决定是否事先有值。
③变量形参与对应的实参的类型必须完全相同。
④对变量形参,运行时不另外开辟存储单元,而是与对应的实参使用相同的存储单元。也就是说,调用子程序时,是将实参的地址传送给对应的变量形参。
⑤当控制返回到调用程序后,变量形参的存储单元不释放,但变量形参本身无定义,即不得再使用。
⑥选用形式参时,到底是使用值形参还是变量形参,应慎重考虑。值形参需要另开辟存储空间,而变量形参会带来一些副作用。一般在函数中使用值形参,而在过程中才使用变量形参,但也有例外。
例3 写出下列两个程序的运行结果。
program ex1; program
ex2;
var a,b:integer; var
a,b:integer;
procedure swap(x,y:integer); procedure swap(Var x,y:integer) ;
var t:integer; var
t:integer;
begin begin
t:=x;x:=y;y:=t; t:=x;x:=y;y:=t;
end; end;
begin begin
a:=1;b:=2; a:=1;b:=2;
writeln(a:3,b:3); writeln(a:3,b:3);
swap(a,b); swap(a,b);
writeln(a:3,b:3); writeln(a:3,b:3);
end. end.
分析:这两个程序唯一的区别是ex1中将x,y作为值形参,而 ex2中将x,y作为变量形参,因此在ex2中对x,y的修改实际上是对调用该过程时与它们对应的变量a,b的修改,故最后,a,b的值为2,1。而ex1中调用swap过程时,只是将a,b的值传递给x,y,之后在过程中的操作与a,b无关。
答:ex1的运行结果为: ex2的运行结果为:
1 2 1 2
1 2 2 1
(二)全程变量、局部变量及它们的作用域
在主程序的说明部分和子程序的说明部分均可以说明变量,但它们的作用范围是特定的。
1、局部量及其作用域
在介绍过程和函数的说明时,我们曾指出,凡是在子程序内部作用的变量,应该在本子程序内加以说明。这种在子程序内部说明的变量称为局部变量。形式参数也只是在该子程序中有效,因此也属于局部变量。
一个变量的作用域是指在程序中能对此变量进行存取的程序范围。因此,局部变量的作用域就是其所在的子程序。实际上,局部变量只是当其所在的子程序被调用时才具有确定的存储单元,当控制从子程序返回到调用程序后,局部变量的存储单元就被释放,从而变得无定义。
事实上,在子程序内定义的标号、符号常量、类型、子程序也与局部变量具有相同的作用域。
2、全程量及其作用域
全程量是指在主程序的说明部分中说明的量。全程量的作用域分两种情况:
①当全程量和局部量不同名时,其作用域是整个程序范围(自定义起直到主程序结束)。
②当全程量和局部量同名时,全程量的作用域不包含局部量的作用域。
例4 写出下列程序的运行结果:
program ex7_4;
var x,y:integer;
procedure a;
var x:integer;
begin
x:=2;
writeln('#',x,'#');
writeln('#',y,'#');
end;{of a}
begin{main program}
x:=1;y:=2;
writeln('*',x,'*',y);
a;
writeln('***',x,'***',y);
end.
分析:程序中x,y是全局变量,但在过程a中也有变量x,故全程变量x的作用域为除过程a外的任何地方。而y的作用域包含了子程序a,即整个程序。
答:运行结果如下:
*1*2
#2#
#2#
***1***2
评注:变量作用域内对变量的操作都是对同一存储单元中的量进行的。
四、过程和函数的嵌套
Pascal语言中,使用过程和函数,能使程序设计简短,便于阅读,节省存贮单元和编译时间。程序往往设计成分层结构,由一个主程序和若干个过程及函数组成。在过程或函数中,还可以说明另一些过程或函数,即过程或函数可以分层嵌套。在同一层中亦可说明几个并列的过程或函数。例如:
上例过程的分层嵌套关系如下:0层主程序sample内并列两个1层过程P1a和P1b。过程P1a又嵌套两个2层过程p2a和p2b,2层的第二过程p2b又嵌套过程p3,p3就是第3层。其中p1b,p2a和p3不再嵌套别的过程,称为基本过程。这种分层结构的程序设计,特别要注意局部变量的使用范围和过程调用的要求。
在主程序sample中定义的变量,可以在所有的过程中使用,主程序可调用p1a和p1b两个过程。过程p1a中定义的变量,只能在p2a,p2b 和p3中使用。它能调用p2a,p2b两个过程,而不能调用p3和p1b。
在过程p1b中定义的变量,只能在p1b中使用,它只能调用过程p1a。过程p2a不能调用任何过程。过程p2b可以调用并列过程p2a和p3,而过程p3可以调用p2a过程。
过程调用是有条件的,过程定义在先,调用在后。同一层过程,后说明的过程可以调用先说明的过程。如果要调用在它后面定义的过程(或函数),可使用<向前引用>FORWARD这个扩充标识符。 要注意的是<向前引用>过程(或函数)首部中形式参数表写一次即可, 不必重复。如:
procedure extend(var a,b:integer);
forward;
表示过程extend<向前引用>。因此,过程extend 的说明部分只须如下书写:
procedure extend;
<说明部分>
begin
:
end;
五、子程序(模块化)结构的程序设计
例5 对6到60的偶数验证哥德巴赫猜想:不小于6的偶数可分解成两个素数之和。
分析:用布尔型函数prime(x)判断x是否是素数,若是, 函数值为真,否则,函数值为假。算法如下所示。
1. t:=6
2. while t≤60 do
3. t11;
4. repeat
5. t11+2; /* 找下一个素数a */
6. until prime(t1)and
prime(t-t1); /*直到a,b都是素数*/
7.
writeln(i,'=',t1,'+',t-t1);
8. tt+2;
9. endwhile
源程序如下:
program ex9_7;
var t,t1:integer;
function prime(x:integer):boolean;
var i:integer;
begin
if x=1
then prime:=false
else if x=2
then prime:=true
else begin
prime:=true;
i:=2;
while (i<=round(sqrt(x)))and(x mod
i<>0) do
i:=i+1;
if i<=round(sqrt(x)) then
prime:=false;
end;
end;{of prime}
begin
t:=6;
while t<=60 do
begin
t1:=1;
repeat
t1:=t1+2;
until prime(t1) and prime(t-t1);
writeln(t,'=',t1,'+',t-t1);
t:=t+2;
end;
end.
例6 编写一个给一个分数约分的程序。
源程序如下:
program ex7_6; ┌──变量参数
var a,b:integer; ↓
procedure common(var x,y:integer);
var i,j,k:integer;
begin
{求x,y的最大公约数}
i:=x;j:=y;
repeat
k:=i mod j;
i:=j;j:=k;
until k=0;
{对x,y进行约分}
x:=x div i;y:=y div i;
end;
begin
write('Input a,b=');readln(a,b);
common(a,b);
writeln(a,b:5);
end.
如输入:
Input a,b=12 8
则输出:
3 2
练习
1. 输入5个正整数求它们的最大公约数。(提示:可用一个数组将5个数存放起来,然后求第一个数和第二个数的公约数,再求第三个数与前两个数公约数的公约数,这样求得前三个整数最大公约数……如此类推可求出5个整数的最大公约数)
2. 给一维数组输入任意6个整数,假设为:
7 4 8 9 1 5
请建立一个具有以下内容的方阵:
7 4 8 9 1 5
4 8 9 1 5 7
8 9 1 5 7 4
9 1 5 7 4 8
1 5 7 4 8 9
5 7 4 8 9 1
(请用子程序编写)。
3. 求两个正整数的最小公倍数。
4. 输入一个任意位的正整数,将其反向输出。
5. 有五位同学,其各科成绩如下:
学号 数学 语文 英语 总分 名次
1 108 97 90
2 98 88 100
3 100 43 89
4 84 63 50
5 97 87 100
(1)编写一个过程enter,输入每个学生成绩并计算各人的总分。
(2)编写过程minci,用以排出每个人的名次。
(3)按学号顺序输出。
第十三章 动态数据类型
前面介绍的各种简单类型的数据和构造类型的数据属于静态数据。在程序中,这些类型
的变量一经说明,就在内存中占有固定的存储单元,直到该程序结束。
程序设计中,使用静态数据结构可以解决不少实际问题,但也有不便之处。如建立一个
大小未定的姓名表,随时要在姓名表中插入或删除一个或几个数据。而用新的数据类型──
指针类型。通过指针变量,可以在程序的执行过程中动态地建立变量,它的个数不再受限制,
可方便地高效地增加或删除若干数据。
一、指针的定义及操作
(一)指针类型和指针变量
在pascal中,指针变量(也称动态变量)存放某个存储单元的地址;也就是说, 指针变量
指示某个存储单元。
指针类型的格式为:^基类型
说明: ①一个指针只能指示某一种类型数据的存储单元,这种数据类型就是指针的基类
型。基类型可以是除指针、文件外的所有类型。例如,下列说明:
type pointer=^Integer;
var p1,p2:pointer;
定义了两个指针变量p1和p2,这两个指针可以指示一个整型存储单元(即p1、p2 中存放的是某存储单元的地址,而该存储单元恰好能存放一个整型数据)。
②和其它类型变量一样,也可以在var区直接定义指针型变量。
例如:var a:^real; b:^boolean;
又如:type person=record
name:string[20];
sex:(male,female);
age:1..100
end;
var pts:^person;
③pascal规定所有类型都必须先定义后使用,但只有在定义指针类型时可以例外,如下
列定义是合法的:
type pointer=^rec;
rec=record
a:integer;
b:char
end;
(二)开辟和释放动态存储单元
1、开辟动态存储单元
在pascal中,指针变量的值一般是通过系统分配的,开辟一个动态存储单元必须调用标
准过程new。
new过程的调用的一般格式:
New(指针变量)
功能:开辟一个存储单元,此单元能存放的数据的类型正好是指针的基类型,并把此存
储单元的地址赋给指针变量。
说明:①这实际上是给指针变量赋初值的基本方法。例如,设有说明:var p:^Integer;
这只定义了P是一个指示整型存储单元的指针变量,但这个单元尚未开辟,或者说P中尚未有值(某存储单元的首地址)。当程序中执行了语句new(p)才给p赋值,即在内存中开辟(分配)一个整型变量存储单元,并把此单元的地址放在变量p中。示意如下图:
(a)编译时给 (b)执行New(p)后 (c)(b)的简略表示
p分配空间 生成新单元
?表示值不定 新单元的地址为XXXX
内存单元示意图
②一个指针变量只能存放一个地址。如再一次执行New(p)语句,将在内存中开辟另外一个新的整型变量存储单元,并把此新单元的地址放在p中,从而丢失了原存储单元的地址。
③当不再使用p当前所指的存储单元时,可以通过标准过程Dispose释放该存储单元。
⒉释放动态存储单元
dispose语句的一般格式:dispose(指针变量)
功能:释放指针所指向的存储单元,使指针变量的值无定义。
(三)动态存储单元的引用
在给一个指针变量赋以某存储单元的地址后,就可以使用这个存储单元。
引用动态存储单元一般格式:<指针变量>^
说明:①在用New过程给指针变量开辟了一个它所指向的存储单元后,要使用此存储单元的唯一方法是利用该指针。
②对动态存储单元所能进行的操作是该类型(指针的基类型)所允许的全部操作。
例1 设有下列说明:
var p:^integer; i:integer;
画出执行下列操作后的内存示意图:
New(p); P^:=4;i:=p^;
解: 如下图所示。
(a)编译时 (b)执行New语句 (c)执行P^:=4 (d)执行i:=P^
分配存储
单元
内存单元示意图
(四)对指针变量的操作
前已述及,对指针所指向的变量(如P^)可以进行指针的基类型所允许的 全部操作。
对指针变量本身,除可用New、Dispose过程外,尚允许下列操作:
⒈具有同一基类型的指针变量之间相互赋值
例2 设有下列说明与程序段:
var p1,p2,p3:^integer;
begin
New(P1) ; New(P2); New(P3);
P1:=P2; P2:=P3;
end;
2、可以给指针变量赋nil值
nil是PASCAL的关键字,它表示指针的值为"空"。例如,执行:
p1:=ni1后,p1的值是有定义的,但p1不指向任何存储单元。
3、可以对指针变量进行相等或不相等的比较运算
在实际应用中,通常可以在指针变量之间,或指针变量与nil之间进行相等(=)或不相等(<>=的比较,比较的结果为布尔量。
例3 输入两个整数,按从小到大打印出来。
分析:不用指针类型可以很方便地编程,但为了示例指针的用法,我们利用指针类型。定义一个过程swap用以交换两个指针的值。
源程序如下:
Type pointer=^integer;
var p1,p2:pointer;
procedure swap(var q1,q2:pointer);
var q:pointer;
begin
q:=q1;
q1:=q2;
q2:=q;
end;
begin
new(p1);new(p2);
write('Input 2 data:');readln(pq^,p2^);
if p1^>p2^ then swap(p1,p2);
writeln('Output 2 data:',p1^:4,p2^:4);
end.
二、链表结构
设有一批整数(12,56,45,86,77,……,),如何存放呢? 当然我们可以选择以前学过的数组类型。但是,在使用数组前必须确定数组元素的个数。如果把数组定义得大了,就会有大量空闲存储单元,定义得小了,又会在运行中发生下标越界的错误,这是静态存储分配的局限性。
利用本章介绍的指针类型可以构造一个简单而实用的动态存储分配结构――链表结构。
下图是一个简单链表结构示意图:
其中:①每个框表示链表的一个元素,称为结点。
②框的顶部表示了该存储单元的地址(当然,这里的地址是假想的)。
③每个结点包含两个域:一个域存放整数,称为数据域,另一个域存放下一个结点(称为该结点的后继结点,相应地,该结点为后继结点的前趋结点)的地址。
④链表的第一个结点称为表头,最后一个结点表尾,称为指针域;
⑤指向表头的指针head称为头指针(当head为nil时,称为空链表),在这个指针变量中
存放了表头的地址。
⑥在表尾结点中,由指针域不指向任何结点,一般放入nil。
(一)链表的基本结构
由上图可以看出:
①链表中的每个结点至少应该包含两个域;一是数据域,一是指针域。因此,每个结点都是一个记录类型,指针的基类型也正是这个记录类型。因此,head可以这样定义:
type pointer=^ rec;
rec=record
data:integer;
next:pointer;
end;
var head:pointer;
②相邻结点的地址不一定是连续的。整个链表是通过指针来顺序访问的,一旦失去了一个指针值,后面的元素将全部丢失。
③与数组结构相比,使用链表结构时;可根据需要采用适当的操作步骤使链表加长或缩 短,而使存储分配具有一定的灵活性。这是链表结构的优点。
④与数组结构相比,数组元素的引用比较简单,直接用"数组名[下标]"即可,因为数组元素占用连续的存储单元,而引用链表元素的操作却比较复杂。
(二)单向链表的基本操作
上图所示的链表称为单向链表。下面我们通过一些例题来说明对单向链表的基本操作,并假设类型说明如前所述。
例6 编写一个过程,将读入的一串整数存入链表,
并统计整数的个数。
分析:过程的输入为一串整数,这在执行部分用读语句完成。过程的输出有两个:一是链表的头指针,一是整数的个数,这两个输出可以用变量形参来实现。
由于不知道整数的个数,我们用一个特殊的9999作为结束标记。
过程如下:
procedure creat(var h:pointer;var n:integer);
var p,q:pointer;x:integer;
begin
n:=0;h:=nil; read(x);
while x<>9999 do
begin
New(p);
n:=n+1;p^.data:=x;
if n=1 then h:=p
else q^.next:=p;
q:=p;read(x)
end;
if h<>nil then q^.next:=nil;
Dispose(p);
end;
例7 编一过程打印链表head中的所有整数,5个一行。
分析:设置一个工作指针P,从头结点顺次移到尾结点,每移一次打印一个数据。
过程如下:
procedure print(head:pointer);
var p:pointer; n:integer;
begin
n:=0;p:=head;
while p<>nil do
begin
write(p^.data:8);n:=n+1;
if n mod 5=0 then writeln;
p:=p^.next;
end;
writeln;
end;
(三)链表结点的插入与删除
链表由于使用指针来连接,因而提供了更多了灵活性,可以插入删除任何一个成分。
设有如下定义:
type pointer=^rec;
rec=record
data:integer;
next:pointer
end;
var head:pointer;
⒈结点的插入
如下图所示,要在P结点和Q结点之间插入一个结点m,其操作如下:
只要作如下操作即可:
New(m);
read(m^.data);
m^.next:=q;
p^.next:=m;
例8 设链表head中的数据是按从小到大顺序存放的,在链表中插入一个数,使链表仍有序。
分析:显然,应分两步:查找、插入。设po指向要插入的结点,若仅知道po应插在p之前(作为p的前趋结点)是无法插入的,应同时知道p的前趋结点地址q。
当然,如果插在链表原头结点这前或原链表为空表或插在原尾结点之后,则插入时又必须作特殊处理。
过程如下:
procedure inserting(var head:pointer;x:integer);
var po,p,q:pointer;
begin
new(po);po^.data:=x;
p:=head;
if head=nil{原表为空表}
then begin
head:=po;po^.next:=nil;
end
else begin
while (p^.datanil)do
begin
q:=p;p:=p^.next
end;
if p^.data>=x{不是插在原尾结点之后}
then begin
if head=p then head:=po
else q^.next:=po;
po^.next:=p
end
else begin
po^.next:=po;
po^.next:=nil
end;
end;
end;
⒉结点的删除
如下图所示,要在删除结点P的操作如下:
要删除结点P,则只要将其前趋结点的指针域指向P 的后继结点即可。
q^.next:=p^.next;
dispose(p);
例9 将链表head中值为X的第一个结点删除
分析: 有三种情况存在:头结点的值为X; 除头结点外的某个结点值为X;无值为X的结点。为将前两种情况统一起来,
我们在头结点之前添加一个值不为X的哨兵结点。
算法分两步:查找、删除。
过程如下:
procedure deleteing(var head:pointer;x:integer);
var p,q:pointer;
begin
New(p);p^.data:=x-1;p^.next:=head;
head:=p;{以上为添加哨兵结点}
while(x<>p^.data)and(p^.next<>nil)do
begin
q:=p;
p:=p^.next
end;
if x=p^.data{存在值为X的结点}
then q^.next:=p^.next
else writeln('NOt found!');
head:=head^.next{删除哨兵}
end;
(四)环形链表结构
在单向链表中,表尾结点的指针为空。如果让表尾结点的指针域指向表头结点,则称为单向环形链表,简称单链环。如图所示。
单链环示意图
(五)双向链表结构
单链表中,每个结点只有一个指向其后继结点的指针域。如果每个结点不仅有一个指向其后继结点的指针域,还有一个指向其前趋的指针域,则这种链表称为双向链表。如图所示。
双向链表示意图
可用如下定义一个数据域为整型的双向链表:
type pointer=^node;
node=record
prev:pointer;
data:integer;
next:pointer;
end;
对双向链表的插入、删除特别方便。与单向链环相似,我们还可定义双向链环。
三、综合例析
例10 读入一串以"#"为结束标志的字符,统计每个字符出现的次数。
分析:设置一个链表存放,每读入一个字符,就从链表的头结点向后扫描链表,如果在链表中此字符已存在,则其频率加1,
否则将该字符的结点作为链表的新头结点,相应频率为1。
源程序如下:
program ex11_10;
type ref=^letters;
letters=record
key:char;
count:integer;
next:ref;
end;
var k:char;
sentinel,head:ref;
procedure search(x:char);
var w:ref;
begin
w:=head;
sentinel^.key:=x;
while w^.key<>x do w:=w^.next;
if w<>sentinel
then w^.count:=w^.count+1
else begin
w:=head;new(head);
with head^ do
begin
key:=x;count:=1;next:=w;
end
end;
end;{of search}
procedure printlist(w:ref);
begin
while w<>sentinel do
begin
writeln(w^.key:2,w^.count:10);
w:=w^.next;
end;
end;{of printlist}
begin{main program}
new(sentine);
with sentinel^ do
begin
key:='#';count:=0;next:=nil;
end;
head:=sentinel;
read(k);
while k<>'#' do
begin
search(k);read(k);
end;
printlist(head);
end.
例11 用链表重写筛法求2~100之间所有素数程序。
源程序如下:
program ex11_12;
uses crt;
type link=^code;
code=record
key:integer;
next:link;
end;
var head:link;
procedure printlist(h:link);{打印链表h}
var p:link;
begin
p:=h;
while p<>nil do
begin
write(p^.key,'-->');
p:=p^.next;
end;
end;
procedure buildlink;{建立链表}
var p,q:link;
i:integer;
begin
new(head);
head^.key:=2;
p:=head;
for i:=3 to 100 do
begin
new(q);
q^.key:=i;
q^.next:=nil;
p^.next:=q;
p:=q;
end;
end;
procedure prime;{筛法将找到的素数的倍数从链表中删除}
var h,p,q:link;
begin
h:=head;
while h<>nil do
begin
p:=h;q:=p^.next;
while q<>nil do
if (q^.key mod h^.key=0) then
begin
p^.next:=q^.next;
dispose(q);
q:=p^.next;
end
else begin
p:=q;
q:=q^.next;
end;
h:=h^.next;
end;
end;
begin{main program}
clrscr;
buildlink;
printlist(head);
writeln;
prime;
printlist(head);
end.
练习
1、围绕着山顶有10个洞,一只兔子和一只狐狸各住一个洞,狐狸总想吃掉兔子。一天兔子对狐狸说,你想吃我有一个条件,你先把洞编号1到10。你从第10号洞出发,先到第1号洞找我,第二次隔一个洞找我,第三次隔两个洞找我,以后依次类推,次数不限。若能找到我,你就可以饱餐一顿,在没找到我之前不能停止。狐狸一想只有10个洞,寻找的次数又不限,哪有找不到的道理,就答应了条件。结果就是没找着。
利用单链环编程,假定狐狸找了1000次,兔子躲在哪个洞里才安全。
2、某医院病房的订位管理中, 将病人的记录按姓名的字母顺序排成一个链表。试编写程序,从键盘上输入下列字母,就可对病员记录进行管理:
(1)i───新病人入院(插入一个病员记录)。
(2)d───病人出院(删除一个病员记录,并显示该记录)。
(3)s───查询某病员记录(显示该记录或"未找到")。
(4)q───在屏幕上列出所有的病员记录并结束程序。
3、编写一个简单的大学生新生入校登记表处理程序。
第十四课
文
件
在DOS操作中,我们所谈及的文件称之为外部文件。外部文件是存储在外部设备上, 如:外存储器上,可由计算机操作系统进行管理,如用dir、type等命令直接对文件进行操作。
Pascal所谈及的文件,称之为内部文件。内部文件的特点是文件的实体(实际文件)也是存储在外存储器上,成为外部文件的一分子,但在使用时必须在程序内部以一定的语句与实际文件联系起来,建立一一对应的关系,用内部文件的逻辑名对实际文件进行操作。内部文件的逻辑名必须符合PASCAL语言标识符的取名规则。
Pascal中的文件主要用于存放大量的数据。如:成绩管理,原始数据很多,使用文件先将其存入磁盘,通过程序读出文件中的数据再进行处理,比不使用文件要来得方便、有效。
Pascal中的一个文件定义为同一类型的元素组成的线性序列。文件中的各个元素按一定顺序排列,可以从头至尾访问每一个元素,从定义上看,文件与数组相似,但它们之间有着明显不同的特征,主要表现在:
(1)文件的每一个元素顺序存贮于外部文件设备上(如磁盘上)。因此文件可以在程序进行前由Pascal程序或用文字编辑软件,如edit、ws、Turbo Pascal的edit命令等产生,或在运行过程中由程序产生,且运行完后,依然存贮在外部设备上。
(2)在系统内部,通过文件指针来管理对文件的访问。文件指针是一个保存程序在文件中位置踪迹的计算器,在一固定时刻,程序仅能对文件中的一个元素进行读或写的操作,在向文件写入一个元素或从文件读取一个元素后,相应的文件指针就前进到下一元素位置。而数组是按下标访问。
(3)在文件类型定义中无需规定文件的长度即元素的个数,就是说元素的数据可动态改变,一个文件可以非常之大,包含许许多多元素,也可以没有任何元素,即为一个空文件。而数组的元素个数则是确定的。
使用文件大致有以下几个步骤;
(1)说明文件类型,定义文件标识符;
(2)建立内部文件与外部文件的联系;
(3)打开文件;
(4)对文件进行操作;
(5)关闭文件。
Turbo Pascal将文件分为三类:文本文件(顺序)、有类型文件(顺序或随机)和无类型文件(顺序或随机)。下面将介绍这些文件及其操作。
一、文本文件
文本文件又称为正文文件或行文文件,可供人们直接阅读,是人机通信的基本数据形式之一。文本文件可用文字编辑程序(如DOS的edit或Turbo Pascal的编辑命令edit)直接建立、阅读和修改, 也可以由PASCAL程序在运行过程中建立。
1、文本文件的定义:
文本文件的类型为TEXT,它是由ASCII字符组成的,是Pascal提供的标准文件之一。标准文件 TEXT已由Pascal说明如下:
TYPE TEXT=FILE OF CHAR;
因此,TEXT同标准类型INTEGER、READ等一样可以直接用于变量说明之中,无需再由用户说明。 例如:
VAR F1,F2:TEXT;
这里定义了两个文本文件变量F1和F2。
2、文本文件的建立
文本文件的建立有两种方法:
(1)直接用Turbo Pascal的Edit建立原始数据文件。
例1 将下表中的数据存入名为A.dat的文件中。
3 4
29 30 50 60
80 90 70 75
60 50 70 45
操作步骤:
①进入Turbo Pascal的编辑状态;
②输入数据;
③存盘,文件名取A.dat。
此时,已将数据存入文本文件A.dat中。文本文件也可用DOS中的Edit等软件建立。
(2)用程序的方式建立中间数据或结果数据文件。
用程序的方式建立文件操作步骤为:
①定义文本文件变量;
②把一外部文件名赋于文本文件变量,使该文本文件与一相应外部文件相关联;
命令格式:ASSIGN(f,name)
f为定义的文本文件变量
name为实际文件文件名
如:ASSIGN(F1,`FILEIN.DAT`)
或:ASSIGN(F1,`PAS\FILEIN.RES`)
这样在程序中对文本文件变量F1的操作,也就是对外部实际文件`FILEIN.DAT`或`FILEIN.RES`的操作。上例中文件`FILEIN.DAT`是存贮在当前目录中,而文件`FILEIN.RES`则是存贮在PAS子目录中。
③打开文本文件,准备写;
命令格式1:REWRITE(f)
功能:创建并打开新文件准备写,若已有同名文件则删除再创建
命令格式2:APPEND(f)
功能:打开已存在的文件并追加
④对文件进行写操作;
命令格式:WRITE(f,<项目名>)
或:WRITELN(f,<项目名>)
功能:将项目内容写入文件f中
⑤文件操作完毕后,关闭文件。
命令格式:CLOSE(f)
例2 从键盘上读入表12.1的数据,用程序写入名为B.dat的文件中。
3、读取文本文件
文本文件内容读出操作步骤:
①定义文本文件变量;
②用ASSIGN(f,name)命令,将内部文件f与实际文件name联系起来;
③打开文本文件,准备读;
命令格式:READ(f,<变量名表>) READLN(f,<变量名表>)
功能:读文件f中指针指向的数据于变量中
文本文件提供了另外两个命令,在文本的操作中很有用处,它们是:
EOLN(f):回送行结束符
EOF(f):回送文件结束符
⑤文件操作完毕,用CLOSE(f)命令关闭文件。
例3 读出例12.1建立的文本文件,并输出。
由于文本文件是以ASCII码的方式存储,故查看文本文件的内容是极为方便,在DOS状态可使用 DOS中TYPE等命令进行查看,在Turbo Pascal中可以象取程序一样取出文件进行查看。
4、文本文件的特点
(1)行结构
文本文件由若干行组成,行与行之间用行结束标记隔开,文件末尾有一个文件结束标记。由于各行长度可能不同,所以无法计算出给定行在文本文件中的确定位置,从而只能顺序地处理文本文件,而且不能对一文本文件同时进行输入和输出。
(2)自动转换功能
文本文件的每一个元素均为字符型,但在将文件元素读入到一个变量(整型,实型或字符串型)中时,Pascal会自动将其转换为与变量相同的数据类型。与此相反在将一个变量写入文本文件时,也会自动转移为字符型。
例4 某学习小组有10人,参加某次测验,考核6门功课, 统计每人的总分及各门的平均分,将原始数据及结果数据放入文本文件中。
分析
(1)利用Turbo Pascal的EDIT建立原始数据文件TESTIN.DAT存贮在磁盘中,其内容如下:
10 6
1 78 89 67 90 98 67
2 90 93 86 84 86 93
3 93 85 78 89 78 98
4 67 89 76 67 98 74
5 83 75 92 78 89 74
6 76 57 89 84 73 71
7 81 93 74 76 78 86
8 68 83 91 83 78 89
9 63 71 83 94 78 95
10 78 99 90 80 86 70
(2)程序读入原始数据文件,求每人的总分及各门的平均分;
(3)建立结果数据文件,文件名为TEXTIN.RES.
程序:
例5 读入一个行长不定的文本文件。排版,建立一个行长固定为60个字符的文件, 排版要求:(1)当行末不是一个完整单词时,行最后一个字符位用'-'代替, 表示与下一行行头组成完整的单词;(2)第一行行头为两个空格,其余各行行头均不含有空格。
分析
(1)建立原始数据文件。
(2)程序边读入原始数据文件内容,边排版。
(3)每排完一行行长为60字符,并符合题中排版条件,写入目标文件中。
设原始数据TEXTCOPY.DAT文件内容如下:
Pavel was arrested.
That dat Mother did not light the stove.
Evening came and a cold wind was blowing.
There was a knock at the window.
Then another.
Mother was used to such knocks,but this time she gave
a little start of joy.
Throwing a shawl over her shoulders,she opened the
door.
程序:
对TEXTCOPY.DAT文本文件运行程序得到排版结果文件TEXTCOPY.RES内容如下:
Pavel was arrested.That dat Mother did not light
the stov-
evening came and a cold wind was blowing.There was a
knock
at the window.Then another.Mother was used to such
knocks,b-
ut this time she gave a little start of joy.Throwing
a shawl
over her shoulders,she opened the door.
二、有类型文件
文本文件的元素均为字型符。若要在文件中存贮混合型数据,必须使用有类型文件。
1、有类型文件的定义
有类型文件中的元素可以是混合型的,并以二进制格式存贮,因此有类型文件(除了字符类型文件,因为它实质上是文本文件)不象文本文件那样可以用编辑软件等进行阅读和处理。
有类型文件的类型说明的格式为:
类型标识符=File of 基类型;
其中基类型可以是除了文件类型外的任何类型。例如:
FILE1=FILE OF INTEGER;
FILE2=FILE OF ARRAY[1--10] OF STRING;
FILE3=FILE OF SET OF CHAR;
FILE4=FILE OF REAL;
FILE5=FILE OF RECORD;
NAME:STRING;
COURSE:ARRAY[1--10] OF READ;
SUN:READ;
END;
等等,其中FILE2,FILE3,FILE5中的数组、集合、记录等类型可以先说明再来定义文件变量。
例如:
VAR
F1:FILE;
F2,F3:FILE3;
F4:FILE5;
与前面所有类型说明和变量定义一样,文件类型说明和变量定义也可以合并在一起,例如:
VAR
F1:FILE OF INTEGER;
F2,F3:FILE OF SET OF CHAR;
F4:FILE OF RECORD
NAME:STRING;
COURSE:ARRAY[1--10] OF REAL;
SUM:READ;
END;
Turbo Pascal对有类型文件的访问既可以顺序方式也可以用随机方式。
为了能随机访问有类型文件,Turbo Pascal提供如下几个命令:
命令格式1:seek(f,n)
功能:移动当前指针到指定f文件的第n个分量,f为非文本文件,n为长整型
命令格式2:filepos(f)
功能:回送当前文件指针,当前文件指针在文件头时,返回,函数值为长整型
命令格式3:filesize(f)
功能:回送文件长度,如文件空,则返回零,函数值为长整型
2、有类型文件的建立
有类型文件的建立只能通过程序的方式进行,其操作步骤与文本文件程序方式建立的步骤相仿,不同之处:(1)有类型文件的定义与文本文件的定义不同;(2)有类型文件可以利用SEEK命令指定指针随机写入。
3、有类型文件的访问
有类型文件访问的操作步骤与文本文件的程序访问操作步骤相仿,区别之处:(1)有类型文件的定义与文本文件的定义不同;(2)有类型文件可以利用SEEK命令访问文件记录中的任一记录与记录中的任一元素。
例6 建立几个学生的姓名序、座号、六门课程成绩总分的有类型文件。
分析:为简单起见,这里假设已有一文本文件FILEDATA.TXT,其内容如下:
10
li hong
1 89 67 56 98 76 45
wang ming
2 99 87 98 96 95 84
zhang yi hong
3 78 69 68 69 91 81
chang hong
4 81 93 82 93 75 76
lin xing
5 78 65 90 79 89 90
luo ze
6 96 85 76 68 69 91
lin jin jin
7 86 81 72 74 95 96
wang zheng
8 92 84 78 89 75 97
mao ling
9 84 86 92 86 69 89
cheng yi
10 86 94 81 94 86 87
第一个数10表示有10个学生,紧接着是第一个学生的姓名、座号、6科成绩,然后是第二个学生,等等。
从文本文件中读出数据,求出各人的总分,建立有类型文件,设文件名为filedata.fil,文件的类型为记录studreco,见下例程序。
程序:
例7 产生数1-16的平方、立方、四次方表存入有类型文件中, 并用顺序的方式访问一遍,用随机方式访问文件中的11和15两数及相应的平方、立方、四次方值。
分析:建立有类型文件文件名为BIAO.FIL,文件的类型为实数型。
(1)产生数1-16及其平方、立方、四次方值,写入BIAO.FIL,并顺序读出输出;
(2)用SEEK指针分别指向11和15数所在文件的位置,其位置数分别为10×4和14×4(注意文件的第一个位置是0),读出其值及相应的平方、立方、四次方值输出。
程序:
程序运行结果如下:
另外,Turbo Pascal还提供了第三种形式文件即无类型文件,无类型文件是低层I/O通道,如果不考虑有类型文件、 文本文件等存在磁盘上字节序列的逻辑解释,则数据的物理存储只不过是一些字节序列。这样它就与内存的物理单元一一对应。无类型文件用128个连续的字节做为一个记录(或分量)进行输入输出操作,数据直接在磁盘文件和变量之间传输,省去了文件缓解区,因此比其它文件少占内存,主要用来直接访问固定长元素的任意磁盘文件。
无类型文件的具体操作在这里就不一一介绍,请参看有关的书籍。
三、综合例析
例8 建立城市飞机往返邻接表。文本文件CITY.DAT内容如下:
第一行两个数字N和V;
N代表可以被访问的城市数,N是正数<100;
V代表下面要列出的直飞航线数,V是正数<100;
接下来N行是一个个城市名,可乘飞机访问这些城市;
接下来V行是每行有两个城市,两城市中间用空格隔开,表示这两个城市具有直通航线。
如:CITY1 CITY2表示乘飞机从CITY1到CITY2或从CITY2到CITY1。
生成文件CITY.RES,由0、1组成的N×N邻接表。
邻接表定义为:
分析
(1)用从文本文件city.dat中读入N个城市名存入一些数组CT中;
(2)读入V行互通航班城市名,每读一行,查找两城市在CT中的位置L、K,建立邻接关系,lj[l,k]=1和lj[k,j]=1;
(3)将生成的邻接表写入文本文件CITY.RES中。
设CITY.DAT内容如下:
10 20
fuzhou
beijin
shanghai
wuhan
hongkong
tiangjin
shenyan
nanchan
chansa
guangzhou
fuzhou beijin
fuzhou shanghai
fuzhou guangzhou
beijin shanghai
guangzhou beijin
wuhan fuzhou
shanghai guangzhou
hongkong beijin
fuzhou hongkong
nanchan beijin
nanchan tiangjin
tiangjin beijin
chansa shanghai
guangzhou wuhan
chansa beijin
wuhan beijin
shenyan beijin
shenyan tiangjin
shenyan shanghai
shenyan guangzhou
程序:
得到CITY.RES文件内容如下:
10
1 fuzhou
2 beijin
3 shanghai
4 wuhan
5 hongkong
6 tiangjin
7 shenyan
8 nanchan
9 chansa
10 guangzhou
0 1 1 1 1 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1
1 1 0 0 0 0 1 0 1 1
1 1 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 1 0 0
0 1 1 0 0 1 0 0 0 1
0 1 0 0 0 1 0 0 0 0
0 1 1 0 0 0 0 0 0 0
1 1 1 1 0 0 1 0 0 0
例9 对例12.3的FILEDATE.FIL文件内容按总分的高低顺序排序。
分析:
文件的排序就是将文本文件的各分量按一定要求排列使文件有序,文件排序有内排序和外排序二种,内排序是指将文件各分量存入一个数组,再对数组排列,最后将该数组存入原来的文件。外排列不同于内排列,它不是将文件分量存入数组,而是对文件直接排序,内排序比外排序速度要快,但当文件很大时,无法调入内存,此时用外排序法较合适。
本程序使用过程SEEK,实现外排序。
程序:
习 题
1、编一程序,计算文本文件中行结束标志的数目。
2、计算文本文件的行长度的平均值、最大值和最小值。
3、一文本文件FILE.DAT存放N个学生某学科成绩,将成绩转换成直方图存入FILE.RES文件中。
如FILE.DAT内容为:
5
78 90 87 73 84
得到直方图文件FILE.RES内容为:
5
********
*********
*********
*******
********
4、银行账目文件含有每一开户的账目细节:开户号、姓名、地址、收支平衡额。写一程序,读入每一开户的账目,生成银行账目文件。
5、通讯录文件每个记录内容为:姓名、住址、单位、邮编、电话,编一程序按姓名顺序建立通讯录文件,要求先建立文件,再对文件按姓名顺序进行外排序。
附录一 Pascal中的字符串函数和数学函数
字符串函数
求长度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.
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.
附录三 关于fillchar的使用和讨论
大家听说过fillchar这个标准过程吧。 很好用的。
var a:array [1..10] of arrtype;
执行fillchar(a,sizeof(a),0);
当arrtype为
1.real(其他差不多) 使得a中的元素全部成为0.0
2.integer(byte,word,longint,shortint都相同) 全部为0
3.boolean 全部为false
4.char 全部为#0
执行fillchar(a,size(a),1);
写几个特殊的
1.integer
全部为157(不知道为什么)
2.real 很大的一个数,同上。
3.boolean 全部为true
4.byte,shortint 全部为1,所以integer不行可以暂时用这两个嘛。 要不然就减去156
附录五 程序的调试(一) ——步骤法
任何一个天才都不敢说,他编的程序是100%正确的。几乎每一个稍微复杂一点的程序都必须经过反复的调试,修改,最终才完成。所以说,程序的调试是编程中的一项重要技术。我们现在就来掌握一下基本的程序调试。
我们以下的示范,是以时下比较流行的Borland Pascal 7.0为例子,其他的编程环境可能略有不同,但大致上是一致的。
我们先编一个比较简单的程序,看看程序是如何调试的。
program tiaoshi;
var i:integer;
begin
for i:=1 to 300 do
begin
if i mod 2 = 0 then
if i mod 3 = 0 then
if i mod 5 = 0 then
writeln(i);
end;
end.
该程序是输出300以内同时能被2,3,5整除的整数。 现在我们开始调试。 调试有多种方法,先介绍一种,权且叫步骤法,步骤法就是模拟计算机的运算,把程序每一步执行的情况都反映出来。通常,我们有F8即STEP这个功能来实现,如图:
不断地按F8,计算机就会一步步地执行程序,直到执行到最后的“end.”为止。
可能你还没有发现F8的威力,我们不妨把上面的程序略微修改一下,再配合另外的一种调试的利器watch,你就会发现步骤法的用处。
program tiaoshi;
var i:integer;
a,b,c:boolean;
begin
for i:=1 to 300 do
begin
a:=false;
b:=false;
c:=false;
if i mod 2 = 0 then a:=true;
if i mod 3 = 0 then b:=true;
if i mod 5 = 0 then c:=true;
if a and b and c then writeln(i);
end;
end.
如图,我们单击菜单栏中debug选项,里面有一项叫watch的选项,我们单击它。
就会出现一个watch窗口:
watch窗口可以让我们观察变量的变化情况,具体操作是在watches窗口内按Insert键:
这时,屏幕上弹出一个菜单,我们输入所需要观察的变量名,我们分别输入i,a,b,c这4个变量名,于是watches窗口内就有如下的4个变量的状态:
这时,我们再次使用步骤法,我们会发现,这4个变量的状态随着程序的执行而不断变化,比如:
这样我们就可以方便地知道执行每一步之后,程序的各个变量的变化情况,从中我们可以知道我们的程序是否出错,在哪里出错,方便我们及时地修改。
下一次,我们介绍另外的一种方法,断点法
程序的调试(二) ——断点法
在前面我们已经学习了基本的程序调试方法——步骤法。步骤法有一个缺点,就是在遇到循环次数比较多或者语句比较多的时候,用起来比较费时,今天我们来学习一种新的也是常用的调试方法——断点法。
所谓断点法,就是在程序执行到某一行的时候,计算机自动停止运行,并保留这时各变量的状态,方便我们检查,校对。我们还是以前面求同时能被2,3,5整除的3000以内的自然数为例,具体操作如下:
我们把光标移动到程序的第14行,按下ctrl+F8,这时我们会发现,该行变成红色,这表明该行已经被设置成断点行,当我们每次运行到第14行的时候,计算机都会自动停下来供我们调试。
我们必须学以致用,赶快运用刚学的watch方法,看看这家伙到底有多厉害。
请记住,计算机是执行到断点行之前的一行,断点行并没有执行,所以这时b:=true这一句并没有执行。
断点行除了有以上用处之外,还有另外一个重要用处。它方便我们判断某个语句有没有执行或者是不是在正确的时刻执行,因为有时程序由于人为的疏忽,可能在循环或者递归时出现我们无法预料的混乱,这时候通过断点法,我们就能够判断程序是不是依照我们预期的顺序执行。
附录六
Pascal的多种退出语句用法
1、
break 是用来退出其所在的循环语句
即 : 不论在任何一个循环语句中 执行了 break 的话, 马上退出这个语句。
相当于 : goto 这一层循环语句 最末尾一句的下一句。
例如:var i : integer;
begin
for i := 1 to 10 do
begin
{1} writeln(i);
break;
writeln(i+1);
end;
readln
end.
执行结果 :
1
可见 第一次循环 时 , 执行了{1}句 后 , 执行 break ,然后马上退出了这个for语句。 {*****} 注意 : 以上两个语句 只 对 它们所在的 那层循环语句 起作用,也就是说 : 如果有多个 循环语句 相嵌套, 其中 某一层 执行了continue / break 语句, 它们并不能影响上面几层的循环语句。
2、exit 是退出当前程序块;
即 : 在任何子程序 中执行 exit ,
那么 将退出 这个子程序;如果是在 主程序中执行 exit , 那么将退出整个程序。相当于 : goto 这个程序块 的 末尾 的 end 例如 : 试除法判断素数时,一旦整除,就把函数值赋为false ,然后exit;{******}注意 : 类似上面的 , exit也是只对当前 这一个 子程序产生作用,如果多重嵌套子程序 , 那么其中某个子程序执行了exit以后,将返回到 调用它的那个语句 的下一个语句。
3、halt : 没什么好说的,退出整个程序,Game Over.
例如 : 搜索时, 一旦找到一个解,就打印,然后执行halt,退出整个程序。使用exit , halt 应该注意的地方:要注意所有可能会退出 子程序或主程序 的地方 均要妥善处理好善后工作,比如 文件是否关闭
,输出是否完整等。
最后说一句
, 使用这些语句 使得程序结构不止有一个出口,破坏了结构化程序设计的 标准控制结构 , 使程序难以调试 (但是往往便于编写),应尽量避免使用,因为它们完全可以用其它语句代替,所以,除非使用这些语句
能给 编写程序 带来 较大的方便,且可读性不受到影响,才值得一用。
不要想你能为世界做什么,想想你该为世界做什么!
posted @
2014-07-11 19:47
Chaobs
阅读(8631)
评论(0)
编辑
收藏
举报
会员力量,点亮园子希望
刷新页面返回顶部
公告
Copyright © 2024 Chaobs
Powered by .NET 8.0 on Kubernetes
Basic Pascal Tutorial/Introduction/zh CN - Free Pascal wiki
Basic Pascal Tutorial/Introduction/zh CN - Free Pascal wiki
Basic Pascal Tutorial/Introduction/zh CNFrom Free Pascal wiki(Redirected from Basic Pascal Introduction/zh CN)Jump to navigationJump to search
│
العربية (ar) │
български (bg) │
Deutsch (de) │
English (en) │
español (es) │
français (fr) │
italiano (it) │
日本語 (ja) │
한국어 (ko) │
русский (ru) │
svenska (sv) │
中文(中国大陆) (zh_CN) │
简介 (原作者: Tao Yue, 状态: 未更改)
欢迎学习Pascal语言!本教程是对Pascal程序设计语言的一个简单而完整性的介绍。它涵盖了标准Pascal语言包括指针在内的所有语法。
如果你想要快点开始正式学习,或者如果你正在查找关于Pascal语言的某个特定特点的信息,你可以直接到本教程的目录表中去选择任何章节。
我已经尽可能地把所有的事情讲清楚。如果你仍然有不明白的地方,请在你的Pascal编译器里试一试并稍微做一些修改。Pascal是一种语法严格的语言。这就意味着如果你犯了错误,编译器会停止继续编译,然后报告错误给你。除了文件操作,你几乎没办法彻底搞砸你的计算机系统。
如果你想更加深入或更多地了解基本数据结构之外的东西,你可以购买在下面这个页面中列出的关于Pascal程序设计的书籍和杂志:Pascal和Lazarus的相关书籍和杂志
为了能够用Pascal(或者任何高级语言)编程,你需要一个编译器。本教程中你可以使用任何标准的Pascal编译器。如果你要下载一个编译器,或者如果你完全是第一次接触编程并且不知道编译器是干嘛的,点击这里了解更多信息。
上一页
目录
下一页
Retrieved from "http://wiki.freepascal.org/index.php?title=Basic_Pascal_Tutorial/Introduction/zh_CN&oldid=153642"
Categories: zhBasic Pascal Introduction/zh CNNavigation menuPage actionsPageDiscussionView sourceHistoryPage actionsPageDiscussionMoreToolsIn other languagesPersonal toolsCreate accountLog inNavigationMain PageDocumentationFAQDownloadsGlossaryIndexRecent changesRandom pageHelpToolsWhat links hereRelated changesSpecial pagesPrintable versionPermanent linkPage informationSearch This page was last edited on 20 August 2022, at 15:15.Content is available under unless otherwise noted.Privacy policyAbout Free Pascal wikiDisclaimers
Pascal - 快速指南_学习Pascal|WIKI教程
Pascal - 快速指南_学习Pascal|WIKI教程
WIKI教程
首页
WIKI工具
学习敏捷数据科学
学习Apex
学习Arduino
学习汇编
学习Awk
C标准库
学习Clojure
学习COBOL
学习计算机编程
学习C ++
C ++标准库
学习C
学习C#
学习dart_programming
学习D.
目录
目录
Pascal - 教程
Pascal - 概述
Pascal - 环境设置( Environment Setup)
Pascal - 程序结构
Pascal - Basic 语法
Pascal - 数据类型
Pascal - 变量类型
Pascal - 常量
Pascal - 运算符
Pascal - 决策( Decision Making)
Pascal - 循环
Pascal - 决策( Decision Making)
Pascal - 程序( Procedures)
Pascal - 变量作用域
Pascal - 程序( Procedures)
Pascal - 布尔( Booleans)
Pascal - 数组( Arrays)
Pascal - 指针(Pointers)
Pascal - 记录( Records)
Pascal - Variants
Pascal - Sets
Pascal - 文件处理( File Handling)
Pascal - Memory
Pascal - Units
Pascal - 日期和时间( Date & Time)
Pascal - 对象(Objects)
Pascal - 课程( Classes)
Pascal - 快速指南
Pascal - 有用的资源
Pascal - 讨论
关闭
WIKI教程
学习Pascal
Pascal - 快速指南
Pascal - 快速指南
Pascal - Overview Pascal是一种通用的高级语言,最初由Niklaus Wirth在20世纪70年代初开发。 它的开发是为了将编程教学作为一门系统学科,并开发可靠和有效的课程。 Pascal是基于Algol的语言,包含许多Algol构造。 Algol 60是Pascal的子集。 Pascal提供了多种数据类型和编程结构。 易于理解和维护Pascal程序。 Pascal因其各种原因在教学和学术领域越来越受欢迎: Easy to learn. 结构化语言。 它产生透明,高效和可靠的程序。 它可以在各种计算机平台上编译。 Pascal语言的特点 Pascal具有以下功能 - Pascal是一种强类型语言。 它提供广泛的错误检查。 它提供了几种数据类型,如数组,记录,文件和集合。 它提供了各种编程结构。 它通过功能和程序支持结构化编程。 它支持面向对象的编程。 关于Pascal的事实 Pascal语言以法国数学家Blaise Pascal和计算机开发先驱命名。 Niklaus Wirth在1970年完成了原始Pascal编程语言的开发。 Pascal基于Algol编程语言的块结构样式。 Pascal是一种适合将编程教学作为系统学科的语言,其实现既可靠又高效。 ISO 7185 Pascal标准最初发布于1983年。 Pascal是用于Apple Lisa开发的主要高级语言,也是Mac早期的高级语言。 1986年,Apple Computer发布了第一个Object Pascal实现,并且在1993年,Pascal标准委员会发布了面向对象的Pascal扩展。 为什么要使用Pascal? Pascal允许程序员定义复杂的结构化数据类型并构建动态和递归数据结构,例如列表,树和图。 Pascal提供诸如记录,枚举,子范围,动态分配的变量以及关联指针和集合等功能。 Pascal允许嵌套过程定义到任何深度级别。 这真正为学习编程提供了一个很好的编程环境,作为基于基本概念的系统学科。 Pascal最令人惊叹的实现是 - SkypeTotal CommanderTeX Macromedia Captivate Apple Lisa Various PC Games 嵌入式系统 Pascal - Environment Set Up 有几种Pascal编译器和解释器可供一般使用。 其中有 - Turbo Pascal - 提供IDE和编译器,用于在CP/M,CP/M-86,DOS,Windows和Macintosh上运行Pascal程序。 Delphi - 提供运行Object Pascal的编译器,并为32位和64位Windows操作系统以及32位Mac OS X和iOS生成本机代码。 Embarcadero计划为Linux和Android操作系统构建支持。 Free Pascal - 它是一个用于运行Pascal和Object Pascal程序的免费编译器。 Free Pascal编译器是一个32位和64位Turbo Pascal和Delphi兼容的Pascal编译器,适用于Linux,Windows,OS/2,FreeBSD,Mac OS X,DOS和其他几个平台。 Turbo51 - 它是8051系列微控制器的免费Pascal编译器,具有Turbo Pascal 7语法。 Oxygene - 它是.NET和Mono平台的Object Pascal编译器。 GNU Pascal (GPC) - 它是一个Pascal编译器,由GNU Compiler Collection的前端组成。 我们将在这些教程中使用Free Pascal。 您可以从以下链接下载适用于您的操作系统的Free Pascal : 下载免费Pascal 在Linux上安装Free Pascal Free Pascal的Linux发行版有三种形式 - tar.gz版本,也可作为单独的文件提供。 一个.rpm (Red Hat Package Manager)版本。 一个.deb (Debian)版本。 .rpm版本的安装代码:: rpm -i fpc-X.Y.Z-N.ARCH.rpm
其中XYZ是.rpm文件的版本号,ARCH是受支持的体系结构之一(i386,x86_64等)。 Debian版本的安装代码(如Ubuntu) - dpkg -i fpc-XXX.deb
其中XXX是.deb文件的版本号。 有关详细信息,请阅读: 免费Pascal安装指南 在Mac上安装Free Pascal 如果您使用Mac OS X,使用Free Pascal的最简单方法是从Apple的网站下载Xcode开发环境,并按照简单的安装说明进行操作。 一旦你有Xcode设置,你就可以使用Free Pascal编译器。 在Windows上安装Free Pascal 对于Windows,您将下载Windows安装程序setup.exe。 这是一个通常的安装程序。 您需要采取以下步骤进行安装 - 选择一个目录。 选择要安装的软件包的部分。 (可选)将.pp或.pas扩展名与Free Pascal IDE相关联。 有关详细信息,请阅读: 免费Pascal安装指南 文本编辑器 (Text Editor) 这将用于键入您的程序。 少数编辑器的示例包括Windows Notepad,OS Edit命令,Brief,Epsilon,EMACS和vim或vi。 文本编辑器的名称和版本可能因不同的操作系统而异。 例如,Notepad将在Windows上使用,vim或vi可用于Windows以及Linux或UNIX。 使用编辑器创建的文件称为源文件,包含程序源代码。 Pascal程序的源文件通常以扩展名.pas命名。 在开始编程之前,请确保您有一个文本编辑器,并且您有足够的经验来编写计算机程序,将其保存在文件中,编译并最终执行。 Pascal - Program Structures 在我们研究Pascal编程语言的基本构建块之前,让我们看一下最小的Pascal程序结构,以便我们在接下来的章节中将其作为参考。 Pascal程序结构 Pascal程序基本上由以下部分组成 - 程序名称 使用命令 输入声明 Constant declarations 变量声明 函数声明 程序声明 主程序块 每个区块内的陈述和表达 Comments 每个pascal程序通常都有一个标题声明,一个声明和一个严格按顺序执行的部分。 以下格式显示了Pascal程序的基本语法 - program {name of the program}
uses {comma delimited names of libraries you use}
const {global constant declaration block}
var {global variable declaration block}
function {function declarations, if any}
{ local variables }
begin
...
end;
procedure { procedure declarations, if any}
{ local variables }
begin
...
end;
begin { main program block starts}
...
end. { the end of main program block }
Pascal Hello World示例 以下是一个简单的pascal代码,可以打印出“Hello,World!”字样。 - program HelloWorld;
uses crt;
(* Here the main program block starts *)
begin
writeln('Hello, World!');
readkey;
end.
这将产生以下结果 - Hello, World!
让我们看看上述程序的各个部分 - program HelloWorld;程序program HelloWorld;的第一行program HelloWorld; 表示程序的名称。 该程序的第二行uses crt; 是一个预处理器命令,它告诉编译器在进行实际编译之前包含crt单元。 begin和end语句中包含的下一行是主程序块。 Pascal中的每个块都包含在begin语句和end语句中。 但是,表示主程序结束的结束语句后面是句号(。)而不是分号(;)。 主程序块的begin语句是程序执行开始的地方。 编译器将忽略(*...*)的行,并将其添加到程序中添加comment 。 writeln('Hello, World!');声明writeln('Hello, World!'); 使用Pascal中可用的writeln函数,它会导致消息“Hello,World!” 显示在屏幕上。 声明readkey; 允许显示暂停,直到用户按下某个键。 它是crt单元的一部分。 一个单元就像Pascal中的一个库。 最后一个声明end. 结束你的计划。 编译并执行Pascal程序 打开文本编辑器并添加上述代码。 将文件另存为hello.pas 打开命令提示符并转到保存文件的目录。 在命令提示符下键入fpc hello.pas,然后按Enter键编译代码。 如果代码中没有错误,命令提示符将带您到下一行并生成hello可执行文件和hello.o对象文件。 现在,在命令提示符下键入hello以执行您的程序。 您将能够在屏幕上看到“Hello World”,并且程序会等待您按任意键。 $ fpc hello.pas
Free Pascal Compiler version 2.6.0 [2011/12/23] for x86_64
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling hello.pas
Linking hello
8 lines compiled, 0.1 sec
$ ./hello
Hello, World!
确保免费的pascal编译器fpc在您的路径中,并且您在包含源文件hello.pas的目录中运行它。 Pascal - Basic Syntax 您已经看到了pascal程序的基本结构,因此很容易理解pascal编程语言的其他基本构建块。 变量 (Variables) 变量定义放在以var关键字开头的块中,然后是变量的定义,如下所示: var
A_Variable, B_Variable ... : Variable_Type;
Pascal变量在函数的代码体外声明,这意味着它们不在begin和end对中声明,但它们在过程/函数的定义之后和begin关键字之前声明。 对于全局变量,它们在程序头之后定义。 Functions/Procedures 在Pascal中, procedure是要执行的指令集,没有返回值, function是具有返回值的过程。 功能/程序的定义如下 - Function Func_Name(params...) : Return_Value;
Procedure Proc_Name(params...);
注释 (Comments) 多行注释用大括号括起来,星号用{* ... *}括起来。 Pascal允许用括号{...}括起来的单行注释。 {* This is a multi-line comments
and it will span multiple lines. *}
{ This is a single line comment in pascal }
区分大小写 (Case Sensitivity) Pascal是一种非敏感语言,这意味着您可以在任何一种情况下编写变量,函数和过程。 与变量A_Variable一样,a_variable和A_VARIABLE在Pascal中具有相同的含义。 Pascal声明 Pascal程序由语句组成。 每个陈述都指明了该计划的明确职责。 这些工作可以是声明,分配,读取数据,写入数据,做出逻辑决策,转移程序流程控制等。 例如 - readln (a, b, c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
writeln(area);
Pascal中的保留字 Pascal中的语句设计有一些特定的Pascal单词,称为保留单词。 例如,单词,程序,输入,输出,var,real,begin,readline,writeline和end都是保留字。 以下是Pascal中可用的保留字列表。 andarraybegincaseconstdivdodowntoelseendfileforfunctiongotoifinlabelmodnilnotoforpackedprocedureprogramrecordrepeatsetthentotypeuntilvarwhilewith Pascal中的字符集和标识符 Pascal字符集包括 - 全部大写字母(AZ) 全部小写字母(az) 所有数字(0-9) 特殊符号 - + * /:= ,. ;。 ()[] = {}`空格 Pascal程序中的实体(如变量和常量,类型,函数,过程和记录等)具有名称或标识符。 标识符是字母和数字的序列,以字母开头。 不得在标识符中使用特殊符号和空格。 Pascal - Data Types 实体的数据类型指示与其相关联的含义,约束,可能的值,操作,功能和存储模式。 整数,实数,布尔和字符类型称为标准数据类型。 数据类型可以分类为标量,指针和结构化数据类型。 标量数据类型的示例是整数,实数,布尔值,字符,子范围和枚举。 结构化数据类型由标量类型组成; 例如,数组,记录,文件和集合。 我们稍后将讨论指针数据类型。 Pascal数据类型 Pascal数据类型可以总结如下图所示 - 键入声明 类型声明用于声明标识符的数据类型。 类型声明的语法是 - type-identifier-1, type-identfier-2 = type-specifier;
例如,以下声明将变量days和age定义为整数类型,yes和true定义为Boolean类型,name和city定义为字符串类型,费用和费用作为实际类型。 type
days, age = integer;
yes, true = boolean;
name, city = string;
fees, expenses = real;
整数类型 (Integer Types) 下表提供了有关标准整数类型的详细信息,其中包含Object Pascal中使用的存储大小和值范围 - 类型 最低限度 最大值 格式 Integer-21474836482147483647 签名32位 Cardinal04294967295 无符号32位 Shortint -128127 签名8位 Smallint -3276832767 签名16位 Longint -21474836482147483647 签名32位 Int64 -2^63 2 ^ 63 - 1 签名64位 Byte0255 无符号8位 Word065535 无符号16位 Longword04294967295 无符号32位 Constants 使用常量可使程序更具可读性,并有助于在程序开头的某个位置保留特殊数量。 Pascal允许numerical, logical, string和character常量。 可以通过指定const声明在程序的声明部分声明const 。 常量类型声明的语法如下 - const
Identifier = contant_value;
以下是一些不断声明的例子 - VELOCITY_LIGHT = 3.0E=10;
PIE = 3.141592;
NAME = 'Stuart Little';
CHOICE = yes;
OPERATOR = '+';
必须在变量声明之前给出所有常量声明。 枚举类型 枚举数据类型是用户定义的数据类型。 它们允许在列表中指定值。 枚举数据类型只允许assignment运算符和relational运算符。 枚举数据类型可以声明如下 - type
enum-identifier = (item1, item2, item3, ... )
以下是枚举类型声明的一些示例 - type
SUMMER = (April, May, June, July, September);
COLORS = (Red, Green, Blue, Yellow, Magenta, Cyan, Black, White);
TRANSPORT = (Bus, Train, Airplane, Ship);
项目在枚举类型的域中列出的顺序定义了项目的顺序。 例如,在枚举类型SUMMER中,April在五月之前,五月在六月之前,依此类推。 枚举类型标识符的域不能由数字或字符常量组成。 子范围类型 子范围类型允许变量采用位于特定范围内的值。 例如,如果选民age应介于18至100年之间,则可将名为年龄的变量宣布为 - var
age: 18 ... 100;
我们将在下一节详细介绍变量声明。 您还可以使用类型声明定义子范围类型。 声明子范围类型的语法如下 - type
subrange-identifier = lower-limit ... upper-limit;
以下是子范围类型声明的一些示例 - const
P = 18;
Q = 90;
type
Number = 1 ... 100;
Value = P ... Q;
可以从已定义的枚举类型的子集创建子范围类型,例如 - type
months = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec);
Summer = Apr ... Aug;
Winter = Oct ... Dec;
Pascal - Variable Types 变量只不过是我们的程序可以操作的存储区域的名称。 Pascal中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局; 可存储在该内存中的值范围; 以及可以应用于变量的操作集。 变量的名称可以由字母,数字和下划线字符组成。 它必须以字母或下划线开头。 Pascal not case-sensitive ,因此大写和小写字母在这里意味着相同。 根据前一章中解释的基本类型,将有以下基本变量类型 - Pascal中的基本变量 Sr.No 类型和描述 1 Character 通常是一个八位字节(一个字节)。 这是一个整数类型。 2 Integer 机器最自然的整数大小。 3 Real 单精度浮点值。 4 Boolean 指定true或false逻辑值。 这也是整数类型。 5 Enumerated 指定用户定义的列表。 6 Subrange 表示变量,其值位于范围内。 7 String 存储一组字符。 Pascal编程语言还允许定义各种其他类型的变量,我们将在后续章节中介绍它们,如指针,数组,记录,集合和文件等。在本章中,我们只研究基本变量类型。 Pascal中的变量声明 在我们在Pascal程序中使用它们之前,必须声明所有变量。 所有变量声明后跟var关键字。 声明指定变量列表,后跟冒号(:)和类型。 变量声明的语法是 - var
variable_list : type;
这里,type必须是有效的Pascal数据类型,包括字符,整数,实数,布尔值或任何用户定义的数据类型等,variable_list可以包含一个或多个用逗号分隔的标识符名称。 这里显示了一些有效的变量声明 - var
age, weekdays : integer;
taxrate, net_income: real;
choice, isready: boolean;
initials, grade: char;
name, surname : string;
在上一个教程中,我们已经讨论过Pascal允许声明一个类型。 可以通过名称或标识符来标识类型。 此类型可用于定义该类型的变量。 例如, type
days, age = integer;
yes, true = boolean;
name, city = string;
fees, expenses = real;
现在,如此定义的类型可用于变量声明 - var
weekdays, holidays : days;
choice: yes;
student_name, emp_name : name;
capital: city;
cost: expenses;
请注意type声明和var声明之间的区别。 类型声明指示类型的类别或类,例如整数,实数等,而变量规范指示变量可以采用的值的类型。 您可以将Pascal中的type声明与C中的typedef进行比较。最重要的是,变量名称是指将要存储变量值的内存位置。 类型声明不是这样。 Pascal中的变量初始化 为变量分配一个带冒号和等号的值,后跟一个常量表达式。 赋值的一般形式是 - variable_name := value;
默认情况下,Pascal中的变量不会初始化为零。 它们可能含有垃圾值。 因此,在程序中初始化变量是一种更好的做法。 变量可以在其声明中初始化(分配初始值)。 初始化之后是var关键字,初始化语法如下 - var
variable_name : type = value;
一些例子是 - age: integer = 15;
taxrate: real = 0.5;
grade: char = 'A';
name: string = 'John Smith';
让我们看一个例子,它利用到目前为止讨论的各种类型的变量 - program Greetings;
const
message = ' Welcome to the world of Pascal ';
type
name = string;
var
firstname, surname: name;
begin
writeln('Please enter your first name: ');
readln(firstname);
writeln('Please enter your surname: ');
readln(surname);
writeln;
writeln(message, ' ', firstname, ' ', surname);
end.
编译并执行上述代码时,会产生以下结果 - Please enter your first name:
John
Please enter your surname:
Smith
Welcome to the world of Pascal John Smith
枚举变量 您已经了解了如何使用简单的变量类型,如整数,实数和布尔值。 现在,让我们看一下枚举类型的变量,可以定义为 - var
var1, var2, ... : enum-identifier;
声明枚举类型后,可以声明该类型的变量。 例如, type
months = (January, February, March, April, May, June, July, August, September, October, November, December);
Var
m: months;
...
M := January;
以下示例说明了这一概念 - program exEnumeration;
type
beverage = (coffee, tea, milk, water, coke, limejuice);
var
drink:beverage;
begin
writeln('Which drink do you want?');
drink := limejuice;
writeln('You can drink ', drink);
end.
编译并执行上述代码时,会产生以下结果 - Which drink do you want?
You can drink limejuice
子范围变量 子范围变量声明为 - var
subrange-name : lowerlim ... uperlim;
子范围变量的例子是 - var
marks: 1 ... 100;
grade: 'A' ... 'E';
age: 1 ... 25;
以下计划说明了这一概念 - program exSubrange;
var
marks: 1 .. 100;
grade: 'A' .. 'E';
begin
writeln( 'Enter your marks(1 - 100): ');
readln(marks);
writeln( 'Enter your grade(A - E): ');
readln(grade);
writeln('Marks: ' , marks, ' Grade: ', grade);
end.
编译并执行上述代码时,会产生以下结果 - Enter your marks(1 - 100):
100
Enter your grade(A - E):
A
Marks: 100 Grade: A
Pascal - Constants 常量是在程序执行期间保持不变的实体。 Pascal只允许声明以下类型的常量 - Ordinal types 设置类型 指针类型(但唯一允许的值是Nil)。 Real typesCharString 声明常量 声明常量的语法如下 - const
identifier = constant_value;
下表提供了一些有效的常量声明的示例 - Real type constant Sr.No 常数类型和示例 1 Ordinal(Integer)type constant valid_age = 21; 2 Set type constant 元音=(A,E,I,O,U)的集合; 3 Pointer type constant P =无; 4 e = 2.7182818; velocity_light = 3.0E + 10; 5 Character type constant Operator ='+'; 6 String type constant 总统='约翰尼德普'; 以下示例说明了这一概念 - program const_circle (input,output);
const
PI = 3.141592654;
var
r, d, c : real; {variable declaration: radius, dia, circumference}
begin
writeln('Enter the radius of the circle');
readln(r);
d := 2 * r;
c := PI * d;
writeln('The circumference of the circle is ',c:7:2);
end.
编译并执行上述代码时,会产生以下结果 - Enter the radius of the circle
23
The circumference of the circle is 144.51
观察程序的输出语句中的格式。 变量c的格式为十进制符号后面的总位数7和2位。 Pascal允许使用数值变量进行此类输出格式化。 Pascal - Operators 运算符是一个符号,告诉编译器执行特定的数学或逻辑操作。 Pascal允许以下类型的运算符 - 算术运算符 关系运算符 布尔运算符 位操作符 设置运算符 字符串运算符 让我们逐一讨论算术,关系,布尔和位运算符。 我们稍后将讨论集合运算符和字符串运算。 算术运算符 (Arithmetic Operators) 下表显示了Pascal支持的所有算术运算符。 假设变量A保持10,变量B保持20,则 - 显示示例 操作者 描述 例 + 添加两个操作数 A + B将给出30 - 从第一个减去第二个操作数 A - B将给-10 * 将两个操作数相乘 A * B将给出200 / 分子除以分母 B/A会给2 % 模数运算符和整数除法后的余数 B%A将给出0 关系运算符 (Relational Operators) 下表显示了Pascal支持的所有关系运算符。 假设变量A保持10,变量B保持20,则 - 显示示例 操作者 描述 例 = 检查两个操作数的值是否相等,如果是,则条件变为真。 (A = B)不是真的。 <> 检查两个操作数的值是否相等,如果值不相等,则条件变为真。 (A <> B)是真的。 > 检查左操作数的值是否大于右操作数的值,如果是,则条件变为真。 (A> B)不是真的。 < 检查左操作数的值是否小于右操作数的值,如果是,则条件变为真。 (A < B) 为真 >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 (A> = B)不是真的。 <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 (A <= B)是真的。 布尔运算符 下表显示了Pascal语言支持的所有布尔运算符。 所有这些运算符都处理布尔操作数并生成布尔结果。 假设变量A保持为真,变量B保持为假,则 - 显示示例 操作者 描述 例 and 称为布尔AND运算符。 如果两个操作数都为真,则条件成立。 (A和B)是假的。 然后 它类似于AND运算符,但它保证了编译器评估逻辑表达式的顺序。 从左到右,仅在必要时评估右操作数。 (A和B)是假的。 or 称为布尔OR运算符。 如果两个操作数中的任何一个为真,则条件成立。 (A或B)是真的。 要不然 它类似于布尔OR,但它保证了编译器评估逻辑表达式的顺序。 从左到右,仅在必要时评估右操作数。 (A或B)是真的。 not 称为布尔NOT运算符。 用于反转其操作数的逻辑状态。 如果条件为真,则Logical NOT运算符将使其为false。 不(A和B)是真的。 位运算符 按位运算符处理位并执行逐位运算。 所有这些运算符都处理整数操作数并产生整数结果。 按位和(&),按位或(|)和按位不是(〜)的真值表如下 - p q p&q p | q 〜p 〜流量 000011010110111100100101 假设A = 60; 和B = 13; 现在以二进制格式,他们将如下 - A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A ^ B = 0011 0001 ~A = 1100 0011 Pascal支持的Bitwise运算符如下表所示。 假设变量A保持60而变量B保持13,则: 显示示例 操作者 描述 例 & 如果二进制AND运算符存在于两个操作数中,则它会将结果复制到结果中。 (A&B)将给出12,即0000 1100 | 二进制OR运算符如果存在于任一操作数中,则复制一位。 (A | B)将给出61,即0011 1101 ! 二进制OR运算符如果存在于任一操作数中,则复制一位。 与|相同 运算符。 (A!B)将给出61,即0011 1101 ~ 二元一元补语运算符是一元的,具有“翻转”位的效果。 (~A)将给出-61,由于带符号的二进制数,它是2的补码形式的1100 0011。 << 二进制左移运算符。 左操作数值向左移动右操作数指定的位数。 A << 2将给出240,即1111 0000 >> 二进制右移运算符。 左操作数值向右移动右操作数指定的位数。 A >> 2将给出15,即0000 1111 请注意,Pascal的不同实现在按位运算符方面有所不同。 我们在这里使用的编译器Free Pascal支持以下按位运算符 - 运算符 操作 notBitwise NOTandBitwise ANDorBitwise OR xorBitwise XOR shl 按位向左移位 shr 按位向右移位 << 按位向左移位 >> 按位向右移位 Pascal中的运算符优先级 运算符优先级确定表达式中的术语分组。 这会影响表达式的计算方式。 某些运算符的优先级高于其他运算符; 例如,乘法运算符的优先级高于加法运算符。 例如x = 7 + 3 * 2; 这里,x被赋值为13,而不是20,因为operator *的优先级高于+,所以它首先乘以3 * 2然后加到7中。 此处,具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。 在表达式中,将首先评估更高优先级的运算符。 显示示例 操作者 优先权 ~, not,Highest*, /, div, mod, and, &|, !, +, -, or,=, <>, <, <=, >, >=, in 否则,然后 LowestPascal - Decision Making 决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及在条件被确定为真时要执行的一个或多个语句,以及可选的,如果条件要执行的其他语句被认定是假的。 以下是大多数编程语言中常见决策结构的一般形式 - Pascal编程语言提供以下类型的决策制定语句。 单击以下链接以检查其详细信息。 Sr.No 声明和说明 1 if - then statement if - then statement由布尔表达式后跟一个或多个语句组成。 2 If-then-else statement if - then statement后面可以跟一个可选的else statement ,该else statement在布尔表达式为false时执行。 3 嵌套if语句 您可以在另一个if或else if语句中使用if或else if语句。 4 case statement case语句允许根据值列表测试变量的相等性。 5 case - else statement 它类似于if-then-else语句。 在这里,一个else case statement跟在case statement 。 6 嵌套的case语句 您可以在另一个case语句中使用一个case语句。 Pascal - Loops 当您需要多次执行代码块时,可能会出现这种情况。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。 编程语言提供各种控制结构,允许更复杂的执行路径。 循环语句允许我们多次执行语句或语句组,以下是大多数编程语言中循环语句的一般形式 - Pascal编程语言提供以下类型的循环结构来处理循环需求。 单击以下链接以查看其详细信息。 Sr.No 循环类型和描述 1 while-do循环 在给定条件为真时重复语句或语句组。 它在执行循环体之前测试条件。 2 for-do循环 多次执行一系列语句,并缩写管理循环变量的代码。 3 重复 - 直到循环 像while语句一样,除了它测试循环体末尾的条件。 4 嵌套循环 你可以在任何一个或多个循环中使用一个或多个循环,用于或重复直到循环。 循环控制语句 (Loop Control Statements) 循环控制语句将执行从其正常序列更改。 当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。 Pascal支持以下控制语句。 单击以下链接以查看其详细信息。 Sr.No 控制声明和描述 1 break statement 终止loop或case语句并将执行转移到循环或case语句之后的语句。 2 continue statement 导致循环跳过其身体的其余部分,并在重复之前立即重新测试其状态。 3 goto statement 将控制转移到带标签的声明。 虽然不建议在程序中使用goto语句。 Pascal - 函数子程序 (Subprograms) 子程序是执行特定任务的程序单元/模块。 这些子程序组合在一起形成更大的程序。 这基本上被称为“模块化设计”。 子程序/程序可以调用子程序,称为调用程序。 Pascal提供两种子程序 - Functions - 这些子程序返回单个值。 Procedures - 这些子程序不直接返回值。 功能 (Functions) function是一组一起执行任务的语句。 每个Pascal程序至少有一个函数,即程序本身,所有最简单的程序都可以定义其他函数。 函数declaration告诉编译器函数的名称,返回类型和参数。 函数definition提供函数的实际主体。 Pascal标准库提供了许多程序可以调用的内置函数。 例如,函数AppendStr()附加两个字符串,函数New()动态地将内存分配给变量和更多函数。 定义一个函数 (Defining a Function) 在Pascal中,使用function关键字定义函数。 函数定义的一般形式如下 - function name(argument(s): type1; argument(s): type2; ...): function_type;
local declarations;
begin
...
< statements >
...
name:= expression;
end;
Pascal中的函数定义由函数header ,局部declarations和函数body 。 函数头由关键字函数和赋予函数的name组成。 以下是函数的所有部分 - Arguments - 参数建立调用程序和函数标识符之间的链接,也称为形式参数。 参数类似于占位符。 调用函数时,将值传递给参数。 该值称为实际参数或参数。 参数列表是指函数的类型,顺序和参数数量。 使用这种形式参数是可选的。 这些参数可以具有标准数据类型,用户定义的数据类型或子范围数据类型。 出现在函数语句中的形式参数列表可以是简单的或下标的变量,数组或结构化变量,或子程序。 Return Type - 所有函数必须返回一个值,因此必须为所有函数分配一个类型。 function-type是函数返回的值的数据类型。 它可以是标准的,用户定义的标量或子范围类型,但它不能是结构化类型。 Local declarations - 局部声明是指标签,常量,变量,函数和过程的声明,它们仅适用于函数体。 Function Body - 函数体包含一组语句,用于定义函数的功能。 它应始终包含在保留字开头和结尾之间。 它是所有计算完成的函数的一部分。 必须有一个类型的赋值语句 - name := expression; 在函数体中为函数名赋值。 执行该函数时返回该值。 正文中的最后一个陈述必须是最终陈述。 以下是一个示例,说明如何在pascal中定义函数 - (* function returning the max between two numbers *)
function max(num1, num2: integer): integer;
var
(* local variable declaration *)
result: integer;
begin
if (num1 > num2) then
result := num1
else
result := num2;
max := result;
end;
函数声明 (Function Declarations) 函数declaration告诉编译器函数名称以及如何调用函数。 函数的实际主体可以单独定义。 功能声明包含以下部分 - function name(argument(s): type1; argument(s): type2; ...): function_type;
对于上面定义的函数max(),以下是函数声明 - function max(num1, num2: integer): integer;
在一个源文件中定义函数并在另一个文件中调用该函数时,需要函数声明。 在这种情况下,您应该在调用该函数的文件顶部声明该函数。 调用一个函数 (Calling a Function) 在创建函数时,您可以定义函数必须执行的操作。 要使用函数,您必须调用该函数来执行定义的任务。 当程序调用一个函数时,程序控制被转移到被调用的函数。 被调用的函数执行已定义的任务,当执行其返回语句或达到最后结束语句时,它将程序控制返回给主程序。 要调用函数,只需要传递必需的参数和函数名称,如果函数返回一个值,那么您可以存储返回的值。 以下是一个显示用法的简单示例 - program exFunction;
var
a, b, ret : integer;
(*function definition *)
function max(num1, num2: integer): integer;
var
(* local variable declaration *)
result: integer;
begin
if (num1 > num2) then
result := num1
else
result := num2;
max := result;
end;
begin
a := 100;
b := 200;
(* calling a function to get max value *)
ret := max(a, b);
writeln( 'Max value is : ', ret );
end.
编译并执行上述代码时,会产生以下结果 - Max value is : 200
Pascal - Procedures Procedures是子程序,它不是返回单个值,而是允许获得一组结果。 定义程序 在Pascal中,使用procedure关键字定义procedure 。 程序定义的一般形式如下 - procedure name(argument(s): type1, argument(s): type 2, ... );
< local declarations >
begin
< procedure body >
end;
Pascal中的过程definition由头,局部declarations和过程body组成。 过程标题由关键字procedure和给定procedure的名称组成。 以下是程序的所有部分 - Arguments - 参数建立调用程序和过程标识符之间的链接,也称为形式参数。 过程中参数的规则与函数的参数规则相同。 Local declarations - 局部声明引用标签,常量,变量,函数和过程的声明,这些声明仅适用于过程主体。 Procedure Body - 过程主体包含一组语句,用于定义过程的作用。 它应始终包含在保留字开头和结尾之间。 它是完成所有计算的过程的一部分。 以下是名为findMin()的过程的源代码。 此过程采用4个参数x,y,z和m,并将前三个变量中的最小值存储在名为m的变量中。 变量m通过reference传递(稍后我们将通过引用讨论传递参数) - procedure findMin(x, y, z: integer; var m: integer);
(* Finds the minimum of the 3 values *)
begin
if x < y then
m := x
else
m := y;
if z m := z;
end; { end of procedure findMin }
程序声明 过程declaration告诉编译器有关过程名称以及如何调用过程的信息。 程序的实际主体可以单独定义。 过程声明具有以下语法 - procedure name(argument(s): type1, argument(s): type 2, ... );
请注意,该name of the procedure is not associated with any type的name of the procedure is not associated with any type 。 对于上面定义的过程findMin() ,以下是声明 - procedure findMin(x, y, z: integer; var m: integer);
调用程序 在创建过程时,您可以定义过程必须执行的操作。 要使用该过程,您必须调用该过程来执行定义的任务。 当程序调用过程时,程序控制将转移到被调用的过程。 被调用的过程执行定义的任务,当到达其最后一个结束语句时,它将控制返回给调用程序。 要调用过程,您只需要传递所需的参数以及过程名称,如下所示 - program exProcedure;
var
a, b, c, min: integer;
procedure findMin(x, y, z: integer; var m: integer);
(* Finds the minimum of the 3 values *)
begin
if x < y then
m:= x
else
m:= y;
if z < m then
m:= z;
end; { end of procedure findMin }
begin
writeln(' Enter three numbers: ');
readln( a, b, c);
findMin(a, b, c, min); (* Procedure call *)
writeln(' Minimum: ', min);
end.
编译并执行上述代码时,会产生以下结果 - Enter three numbers:
89 45 67
Minimum: 45
递归子程序 我们已经看到程序或子程序可能会调用另一个子程序。 当子程序调用自身时,它被称为递归调用,该过程称为递归。 为了说明这个概念,让我们计算一个数的阶乘。 数字n的因子定义为 - n! = n*(n-1)!
= n*(n-1)*(n-2)!
...
= n*(n-1)*(n-2)*(n-3)... 1
以下程序通过递归调用自身来计算给定数字的阶乘。 program exRecursion;
var
num, f: integer;
function fact(x: integer): integer; (* calculates factorial of x - x! *)
begin
if x=0 then
fact := 1
else
fact := x * fact(x-1); (* recursive call *)
end; { end of function fact}
begin
writeln(' Enter a number: ');
readln(num);
f := fact(num);
writeln(' Factorial ', num, ' is: ' , f);
end.
编译并执行上述代码时,会产生以下结果 - Enter a number:
5
Factorial 5 is: 120
以下是另一个例子,它使用recursive函数为给定数字生成Fibonacci Series数列 - program recursiveFibonacci;
var
i: integer;
function fibonacci(n: integer): integer;
begin
if n=1 then
fibonacci := 0
else if n=2 then
fibonacci := 1
else
fibonacci := fibonacci(n-1) + fibonacci(n-2);
end;
begin
for i:= 1 to 10 do
write(fibonacci (i), ' ');
end.
编译并执行上述代码时,会产生以下结果 - 0 1 1 2 3 5 8 13 21 34
子程序的论点 如果子程序( function or procedure )要使用参数,它必须声明接受参数值的变量。 这些变量称为子程序的formal parameters 。 形式参数的行为与子程序中的其他局部变量相似,并且在进入子程序时创建,并在退出时销毁。 在调用子程序时,有两种方法可以将参数传递给子程序 - Sr.No 通话类型和说明 1 call by value [值传递] 此方法将参数的实际值复制到子程序的形式参数中。 在这种情况下,对子程序内的参数所做的更改对参数没有影响。 2 call by reference [引用传递] 此方法将参数的地址复制到形式参数中。 在子程序内,该地址用于访问调用中使用的实际参数。 这意味着对参数所做的更改会影响参数。 默认情况下,Pascal使用call by value来传递参数。 通常,这意味着子程序中的代码不能改变用于调用子程序的参数。 我们在“Pascal - Functions”一章中使用的示例程序使用call by value名为max()的函数。 然而,此处提供的示例程序( exProcedure )使用call by reference调用过程findMin()。 Pascal - Variable Scope 任何编程中的范围都是程序的一个区域,其中定义的变量可以存在,并且超出该变量无法访问。 有三个地方,其中变量可以用Pascal编程语言声明 - 在子程序或块中,称为局部变量 在所有子程序之外,称为全局变量 在子程序参数的定义中称为形式参数 让我们解释什么是local和global变量和形式参数。 局部变量 (Local Variables) 在子程序或块内声明的变量称为局部变量。 它们只能由子程序或代码块中的语句使用。 本地变量不属于他们自己的子程序。 以下是使用局部变量的示例。 这里,所有变量a , b和c都是名为exLocal程序的本地exLocal 。 program exLocal;
var
a, b, c: integer;
begin
(* actual initialization *)
a := 10;
b := 20;
c := a + b;
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
end.
编译并执行上述代码时,会产生以下结果 - value of a = 10 b = 20 c = 30
现在,让我们更多地扩展程序,让我们创建一个名为display的过程,它将拥有自己的一组变量a , b和c并从程序exLocal显示它们的值。 program exLocal;
var
a, b, c: integer;
procedure display;
var
a, b, c: integer;
begin
(* local variables *)
a := 10;
b := 20;
c := a + b;
writeln('Winthin the procedure display');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
end;
begin
a:= 100;
b:= 200;
c:= a + b;
writeln('Winthin the program exlocal');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
display();
end.
编译并执行上述代码时,会产生以下结果 - Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
value of a = 10 b = 20 c = 30
全局变量 (Global Variables) 全局变量在函数之外定义,通常在程序之上。 全局变量将在程序的整个生命周期中保持其值,并且可以在为程序定义的任何函数内访问它们。 任何函数都可以访问global变量。 也就是说,全局变量在声明后可用于整个程序。 以下是使用global变量和local变量的示例 - program exGlobal;
var
a, b, c: integer;
procedure display;
var
x, y, z: integer;
begin
(* local variables *)
x := 10;
y := 20;
z := x + y;
(*global variables *)
a := 30;
b:= 40;
c:= a + b;
writeln('Winthin the procedure display');
writeln(' Displaying the global variables a, b, and c');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
writeln('Displaying the local variables x, y, and z');
writeln('value of x = ', x , ' y = ', y, ' and z = ', z);
end;
begin
a:= 100;
b:= 200;
c:= 300;
writeln('Winthin the program exlocal');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
display();
end.
编译并执行上述代码时,会产生以下结果 - Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
Displaying the global variables a, b, and c
value of a = 30 b = 40 c = 70
Displaying the local variables x, y, and z
value of x = 10 y = 20 z = 30
请注意,过程显示可以访问变量a,b和c,它们是关于显示的全局变量以及它自己的局部变量。 程序对于局部变量和全局变量可以具有相同的名称,但函数内的局部变量值将优先考虑。 让我们稍微改变前面的例子,现在程序显示的局部变量与a , b , c名字相同 - program exGlobal;
var
a, b, c: integer;
procedure display;
var
a, b, c: integer;
begin
(* local variables *)
a := 10;
b := 20;
c := a + b;
writeln('Winthin the procedure display');
writeln(' Displaying the global variables a, b, and c');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
writeln('Displaying the local variables a, b, and c');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
end;
begin
a:= 100;
b:= 200;
c:= 300;
writeln('Winthin the program exlocal');
writeln('value of a = ', a , ' b = ', b, ' and c = ', c);
display();
end.
编译并执行上述代码时,会产生以下结果 - Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
Displaying the global variables a, b, and c
value of a = 10 b = 20 c = 30
Displaying the local variables a, b, and c
value of a = 10 b = 20 c = 30
Pascal - Strings Pascal中的字符串实际上是一个具有可选大小规范的字符序列。 字符可以是数字,字母,空白,特殊字符或所有字符的组合。 Extended Pascal根据系统和实现提供多种类型的字符串对象。 我们将讨论程序中使用的更常见的字符串类型。 您可以通过多种方式定义字符串 - Character arrays - 这是一个字符串,它是由单引号括起来的零个或多个字节大小的字符序列。 String variables - 字符串类型的变量,如Turbo Pascal中所定义。 Short strings - 具有大小规范的String类型的变量。 Null terminated strings - pchar类型的变量。 AnsiStrings - Ansistrings是没有长度限制的字符串。 Pascal只提供一个字符串运算符,字符串连接运算符(+)。 例子 (Examples) 以下程序打印前四种字符串。 我们将在下一个例子中使用AnsiStrings。 program exString;
var
greetings: string;
name: packed array [1..10] of char;
organisation: string[10];
message: pchar;
begin
greetings := 'Hello ';
message := 'Good Day!';
writeln('Please Enter your Name');
readln(name);
writeln('Please Enter the name of your Organisation');
readln(organisation);
writeln(greetings, name, ' from ', organisation);
writeln(message);
end.
编译并执行上述代码时,会产生以下结果 - Please Enter your Name
John Smith
Please Enter the name of your Organisation
Infotech
Hello John Smith from Infotech
以下示例使用了更多函数,让我们看看 - program exString;
uses sysutils;
var
str1, str2, str3 : ansistring;
str4: string;
len: integer;
begin
str1 := 'Hello ';
str2 := 'There!';
(* copy str1 into str3 *)
str3 := str1;
writeln('appendstr( str3, str1) : ', str3 );
(* concatenates str1 and str2 *)
appendstr( str1, str2);
writeln( 'appendstr( str1, str2) ' , str1 );
str4 := str1 + str2;
writeln('Now str4 is: ', str4);
(* total lenghth of str4 after concatenation *)
len := byte(str4[0]);
writeln('Length of the final string str4: ', len);
end.
编译并执行上述代码时,会产生以下结果 - appendstr( str3, str1) : Hello
appendstr( str1, str2) : Hello There!
Now str4 is: Hello There! There!
Length of the final string str4: 18
Pascal字符串函数和过程 Pascal支持各种操作字符串的函数和过程。 这些子程序在实施方面有所不同。 在这里,我们列出了Free Pascal提供的各种字符串操作子程序 - Sr.No. 功能与目的 1 function AnsiCompareStr(const S1: ; const S2:):Integer; 比较两个字符串 2 function AnsiCompareText(const S1: ; const S2:):Integer; 比较两个字符串,不区分大小写 3 function AnsiExtractQuotedStr(var Src: PChar; Quote: Char):; 从字符串中删除引号 4 function AnsiLastChar(const S:):PChar; 获取string的最后一个字符 5 function AnsiLowerCase(const s:): 将字符串转换为全小写 6 function AnsiQuotedStr(const S: ; Quote: Char):; 引用一个字符串 7 function AnsiStrComp(S1: PChar;S2: PChar):Integer; 比较字符串区分大小写 8 function AnsiStrIComp(S1: PChar; S2: PChar):Integer; 比较字符串不区分大小写 9 function AnsiStrLComp(S1: PChar; S2: PChar; MaxLen: Cardinal):Integer; 比较区分大小写的L字符区分大小写 10 function AnsiStrLIComp(S1: PChar; S2: PChar; MaxLen: Cardinal):Integer; 比较字符串的L个字符不区分大小写 11 function AnsiStrLastChar(Str: PChar):PChar; 获取string的最后一个字符 12 function AnsiStrLower(Str: PChar):PChar; 将字符串转换为全小写 13 function AnsiStrUpper(Str: PChar):PChar; 将字符串转换为全大写 14 function AnsiUpperCase(const s:):; 将字符串转换为全大写 15 procedure AppendStr(var Dest: ; const S:); 附加2个字符串 16 procedure AssignStr(var P: PString; const S:); 在堆上分配字符串的值 17 function CompareStr(const S1: ; const S2:):Integer; overload; 比较两个区分大小写的字符串 18 function CompareText(const S1: ; const S2:):Integer; 比较两个字符串不区分大小写 19 procedure DisposeStr(S: PString); overload; 从堆中删除字符串 20 procedure DisposeStr(S: PShortString); overload; 从堆中删除字符串 21 function IsValidIdent( const Ident:):Boolean; 字符串是有效的pascal标识符 22 function LastDelimiter(const Delimiters: ; const S:):Integer; 字符串中最后出现的字符 23 function LeftStr(const S: ; Count: Integer):; 获取字符串的前N个字符 24 function LoadStr(Ident: Integer):; 从资源加载字符串 25 function LowerCase(const s: ):; overload; 将字符串转换为全小写 26 function LowerCase(const V: variant ):; overload; 将字符串转换为全小写 27 function NewStr(const S:):PString; overload; 在堆上分配新字符串 28 function RightStr(const S: ; Count: Integer):; 获取字符串的最后N个字符 29 function StrAlloc(Size: Cardinal):PChar; 为字符串分配内存 30 function StrBufSize(Str: PChar):SizeUInt; 为字符串保留内存 31 procedure StrDispose(Str: PChar); 从堆中删除字符串 32 function StrPas(Str: PChar):; 将PChar转换为pascal字符串 33 function StrPCopy(Dest: PChar; Source:):PChar; 复制pascal字符串 34 function StrPLCopy(Dest: PChar; Source: ; MaxLen: SizeUInt):PChar; 复制N个字节的pascal字符串 35 function UpperCase(const s:):; 将字符串转换为全大写 Pascal - Booleans Pascal提供数据类型Boolean,使程序员能够定义,存储和操作逻辑实体,例如常量,变量,函数和表达式等。 布尔值基本上是整数类型。 布尔类型变量有两个预定义的可能值True和False 。 解析为布尔值的表达式也可以分配给布尔类型。 Free Pascal还支持ByteBool , WordBool和LongBool类型。 它们分别是Byte,Word或Longint类型。 值False等于0(零),并且在转换为布尔值时,任何非零值都被视为True。 如果将布尔值True分配给LongBool类型的变量,则将其转换为-1。 应该注意,逻辑运算符and/or not为布尔数据类型定义的。 布尔数据类型声明 使用var关键字声明布尔类型的变量。 var
boolean-identifier: boolean;
例如, var
choice: boolean;
例子 (Example)program exBoolean;
var
exit: boolean;
choice: char;
begin
writeln('Do you want to continue? ');
writeln('Enter Y/y for yes, and N/n for no');
readln(choice);
if(choice = 'n') then
exit := true
else
exit := false;
if (exit) then
writeln(' Good Bye!')
else
writeln('Please Continue');
readln;
end.
编译并执行上述代码时,会产生以下结果 - Do you want to continue?
Enter Y/y for yes, and N/n for no
N
Good Bye!
Y
Please Continue
Pascal - Arrays Pascal编程语言提供了一种称为数组的数据结构,它可以存储相同类型元素的固定大小顺序集合。 数组用于存储数据集合,但将数组视为相同类型的变量集合通常更有用。 您可以声明一个数组变量,例如数字,并使用数字[1],数字[2]和...,数字[100]来代表单个变量,例如number1,number2,...和number100,而不是声明单个变量。个别变数。 索引访问数组中的特定元素。 所有阵列都包含连续的内存位置。 最低地址对应于第一个元素,最高地址对应于最后一个元素。 请注意,如果你想要一个从索引0开始的C样式数组,你只需要从0开始索引,而不是1。 声明数组 (Declaring Arrays) 要在Pascal中声明一个数组,程序员可以声明该类型,然后创建该数组的变量或直接声明数组变量。 一维数组类型声明的一般形式是 - type
array-identifier = array[index-type] of element-type;
Where, array-identifier - 表示数组类型的名称。 index-type - 指定数组的下标; 它可以是除真实之外的任何标量数据类型 element-type - 指定要存储的值的类型 例如, type
vector = array [ 1..25] of real;
var
velocity: vector;
现在,velocity是矢量类型的可变数组,足以容纳25个实数。 要从0索引启动数组,声明将是 - type
vector = array [ 0..24] of real;
var
velocity: vector;
数组下标的类型 在Pascal中,数组下标可以是任何标量类型,如整数,布尔,枚举或子范围,除了真实。 数组下标也可能有负值。 例如, type
temperature = array [-10 .. 50] of real;
var
day_temp, night_temp: temperature;
让我们再举一个下标是字符类型的例子 - type
ch_array = array[char] of 1..26;
var
alphabet: ch_array;
下标可以是枚举类型 - type
color = ( red, black, blue, silver, beige);
car_color = array of [color] of boolean;
var
car_body: car_color;
初始化数组 (Initializing Arrays) 在Pascal中,通过赋值来初始化数组,方法是指定特定的下标或使用for-do循环。 例如 - type
ch_array = array[char] of 1..26;
var
alphabet: ch_array;
c: char;
begin
...
for c:= 'A' to 'Z' do
alphabet[c] := ord[m];
(* the ord() function returns the ordinal values *)
访问数组元素 (Accessing Array Elements) 通过索引数组名称来访问元素。 这是通过将元素的索引放在数组名称后面的方括号中来完成的。 例如 - a: integer;
a: = alphabet['A'];
上面的语句将从名为alphabet的数组中取出第一个元素,并将值赋给变量a。 以下是一个例子,它将使用所有上述三个概念即。 声明,分配和访问数组 - program exArrays;
var
n: array [1..10] of integer; (* n is an array of 10 integers *)
i, j: integer;
begin
(* initialize elements of array n to 0 *)
for i := 1 to 10 do
n[ i ] := i + 100; (* set element at location i to i + 100 *)
(* output each array element's value *)
for j:= 1 to 10 do
writeln('Element[', j, '] = ', n[j] );
end.
编译并执行上述代码时,会产生以下结果 - Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
Element[10] = 110
Pascal Arrays详细信息 数组对Pascal很重要,需要更多细节。 以下几个与数组相关的重要概念应该对Pascal程序员清楚 - Sr.No 概念与描述 1 多维数组 Pascal支持多维数组。 多维数组的最简单形式是二维数组。 2 动态数组 在这种类型的数组中,初始长度为零。 必须使用标准SetLength函数设置数组的实际长度。 3 打包阵列 这些数组是比特打包的,即每个字符或真值都存储在连续的字节中,而不是使用一个存储单元,通常是一个字(4个字节或更多)。 4 将数组传递给子程序 通过指定没有索引的数组名称,可以将子程序传递给子程序。 Pascal - Pointers Pascal中的指针简单易学。 使用指针可以更轻松地执行某些Pascal编程任务,并且在不使用指针的情况下无法执行其他任务(如动态内存分配)。 所以有必要学习指向成为一个完美的Pascal程序员。 让我们开始通过简单而简单的步骤学习它们。 如您所知,每个变量都是一个内存位置,每个内存位置都定义了其地址,可以使用指针变量的名称来访问它,该变量表示内存中的地址。 什么是指针? 指针是动态变量,其值是另一个变量的地址,即存储器位置的直接地址。 与任何变量或常量一样,必须先声明指针,然后才能使用它来存储任何变量地址。 指针变量声明的一般形式是 - type
ptr-identifier = ^base-variable-type;
指针类型通过在插入符号(^)的向上箭头前缀为基本类型来定义。 基类型定义数据项的类型。 一旦指针变量被定义为某种类型,它就可以仅指向该类型的数据项。 一旦定义了指针类型,我们就可以使用var声明来声明指针变量。 var
p1, p2, ... : ptr-identifier;
以下是一些有效的指针声明 - type
Rptr = ^real;
Cptr = ^char;
Bptr = ^ Boolean;
Aptr = ^array[1..5] of real;
date-ptr = ^ date;
Date = record
Day: 1..31;
Month: 1..12;
Year: 1900..3000;
End;
var
a, b : Rptr;
d: date-ptr;
通过使用相同的插入符号(^)取消引用指针变量。 例如,由指针rptr引用的关联变量是rptr^ 。 可以访问 - rptr^ := 234.56;
以下示例将说明此概念 - program exPointers;
var
number: integer;
iptr: ^integer;
begin
number := 100;
writeln('Number is: ', number);
iptr := @number;
writeln('iptr points to a value: ', iptr^);
iptr^ := 200;
writeln('Number is: ', number);
writeln('iptr points to a value: ', iptr^);
end.
编译并执行上述代码时,会产生以下结果 - Number is: 100
iptr points to a value: 100
Number is: 200
iptr points to a value: 200
在Pascal中打印内存地址 在Pascal中,我们可以使用地址运算符(@)将变量的地址分配给指针变量。 我们使用此指针来操作和访问数据项。 但是,如果由于某种原因,我们需要使用内存地址本身,我们需要将它存储在word类型变量中。 让我们扩展上面的例子来打印存储在指针iptr的内存地址 - program exPointers;
var
number: integer;
iptr: ^integer;
y: ^word;
begin
number := 100;
writeln('Number is: ', number);
iptr := @number;
writeln('iptr points to a value: ', iptr^);
iptr^ := 200;
writeln('Number is: ', number);
writeln('iptr points to a value: ', iptr^);
y := addr(iptr);
writeln(y^);
end.
编译并执行上述代码时,会产生以下结果 - Number is: 100
iptr points to a value: 100
Number is: 200
iptr points to a value: 200
45504
NIL指针 如果您没有要分配的确切地址,将NIL值分配给指针变量始终是一个好习惯。 这是在变量声明时完成的。 指定NIL指针指向无处。 考虑以下程序 - program exPointers;
var
number: integer;
iptr: ^integer;
y: ^word;
begin
iptr := nil;
y := addr(iptr);
writeln('the vaule of iptr is ', y^);
end.
编译并执行上述代码时,会产生以下结果 - The value of ptr is 0
要检查nil指针,可以使用if语句,如下所示 - if(ptr <> nill )then (* succeeds if p is not null *)
if(ptr = nill)then (* succeeds if p is null *)
Pascal指针细节 指针有很多但很简单的概念,它们对Pascal编程非常重要。 有以下几个重要的指针概念,Pascal程序员应该清楚 - Sr.No 概念与描述 1 Pascal - 指针算术 可以在指针上使用四个算术运算符:递增,递减,+, - 2 Pascal - 指针数组 您可以定义数组以包含许多指针。 3 Pascal - 指向指针 Pascal允许您在指针上指针等等。 4 在Pascal中传递指向子程序的指针 通过引用或地址传递参数都可以通过被调用的子程序在调用子程序中更改传递的参数。 5 从Pascal中的子程序返回指针 Pascal允许子程序返回指针。 Pascal - Records Pascal数组允许您定义可以包含多个相同类型数据项的变量类型,但是记录是Pascal中可用的另一个用户定义数据类型,它允许您组合不同类型的数据项。 记录包含不同的字段。 假设您想要在库中跟踪您的书籍,您可能希望跟踪每本书的以下属性 - TitleAuthorSubject 书名 定义记录 要定义记录类型,可以使用类型声明语句。 记录类型定义为 - type
record-name = record
field-1: field-type1;
field-2: field-type2;
...
field-n: field-typen;
end;
以下是您宣布图书记录的方式 - type
Books = record
title: packed array [1..50] of char;
author: packed array [1..50] of char;
subject: packed array [1..100] of char;
book_id: integer;
end;
记录变量以通常的方式定义 var
r1, r2, ... : record-name;
或者,您可以直接将记录类型变量定义为 - var
Books : record
title: packed array [1..50] of char;
author: packed array [1..50] of char;
subject: packed array [1..100] of char;
book_id: integer;
end;
访问记录的字段 要访问记录的任何字段,我们使用成员访问运算符(。)。 成员访问运算符被编码为记录变量名称和我们希望访问的字段之间的句点。 以下是解释结构用法的示例 - program exRecords;
type
Books = record
title: packed array [1..50] of char;
author: packed array [1..50] of char;
subject: packed array [1..100] of char;
book_id: longint;
end;
var
Book1, Book2: Books; (* Declare Book1 and Book2 of type Books *)
begin
(* book 1 specification *)
Book1.title := 'C Programming';
Book1.author := 'Nuha Ali ';
Book1.subject := 'C Programming Tutorial';
Book1.book_id := 6495407;
(* book 2 specification *)
Book2.title := 'Telecom Billing';
Book2.author := 'Zara Ali';
Book2.subject := 'Telecom Billing Tutorial';
Book2.book_id := 6495700;
(* print Book1 info *)
writeln ('Book 1 title : ', Book1.title);
writeln('Book 1 author : ', Book1.author);
writeln( 'Book 1 subject : ', Book1.subject);
writeln( 'Book 1 book_id : ', Book1.book_id);
writeln;
(* print Book2 info *)
writeln ('Book 2 title : ', Book2.title);
writeln('Book 2 author : ', Book2.author);
writeln( 'Book 2 subject : ', Book2.subject);
writeln( 'Book 2 book_id : ', Book2.book_id);
end.
编译并执行上述代码时,会产生以下结果 - Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
记录为子程序参数 您可以将记录作为子程序参数传递,与传递任何其他变量或指针的方式非常相似。 您可以按照上面示例中访问的方式访问记录字段 - program exRecords;
type
Books = record
title: packed array [1..50] of char;
author: packed array [1..50] of char;
subject: packed array [1..100] of char;
book_id: longint;
end;
var
Book1, Book2: Books; (* Declare Book1 and Book2 of type Books *)
(* procedure declaration *)
procedure printBook( var book: Books );
begin
(* print Book info *)
writeln ('Book title : ', book.title);
writeln('Book author : ', book.author);
writeln( 'Book subject : ', book.subject);
writeln( 'Book book_id : ', book.book_id);
end;
begin
(* book 1 specification *)
Book1.title := 'C Programming';
Book1.author := 'Nuha Ali ';
Book1.subject := 'C Programming Tutorial';
Book1.book_id := 6495407;
(* book 2 specification *)
Book2.title := 'Telecom Billing';
Book2.author := 'Zara Ali';
Book2.subject := 'Telecom Billing Tutorial';
Book2.book_id := 6495700;
(* print Book1 info *)
printbook(Book1);
writeln;
(* print Book2 info *)
printbook(Book2);
end.
编译并执行上述代码时,会产生以下结果 - Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
指针记录 您可以按照与定义指向任何其他变量的指针非常类似的方式定义指向记录的指针,如下所示 - type
record-ptr = ^ record-name;
record-name = record
field-1: field-type1;
field-2: field-type2;
...
field-n: field-typen;
end;
现在,您可以将记录类型变量的地址存储在上面定义的指针变量中。 要声明已创建指针类型的变量,请使用var关键字 - var
r1, r2, ... : record-ptr;
在使用这些指针之前,必须为记录名称类型变量创建存储,这些变量将由这些指针操作。 new(r1);
new(r2);
要使用指向该记录的指针访问记录成员,必须使用^。 运算符如下 - r1^.feild1 := value1;
r1^.feild2 := value2;
...
r1^fieldn := valuen;
最后,当不再使用存储时,不要忘记将其用于处置 - dispose(r1);
dispose(r2);
让我们使用指向Books记录的指针重写第一个示例。 希望您能够轻松理解这个概念 - program exRecords;
type
BooksPtr = ^ Books;
Books = record
title: packed array [1..50] of char;
author: packed array [1..50] of char;
subject: packed array [1..100] of char;
book_id: longint;
end;
var
(* Declare Book1 and Book2 of pointer type that refers to Book type *)
Book1, Book2: BooksPtr;
begin
new(Book1);
new(book2);
(* book 1 specification *)
Book1^.title := 'C Programming';
Book1^.author := 'Nuha Ali ';
Book1^.subject := 'C Programming Tutorial';
Book1^.book_id := 6495407;
(* book 2 specification *)
Book2^.title := 'Telecom Billing';
Book2^.author := 'Zara Ali';
Book2^.subject := 'Telecom Billing Tutorial';
Book2^.book_id := 6495700;
(* print Book1 info *)
writeln ('Book 1 title : ', Book1^.title);
writeln('Book 1 author : ', Book1^.author);
writeln( 'Book 1 subject : ', Book1^.subject);
writeln( 'Book 1 book_id : ', Book1^.book_id);
(* print Book2 info *)
writeln ('Book 2 title : ', Book2^.title);
writeln('Book 2 author : ', Book2^.author);
writeln( 'Book 2 subject : ', Book2^.subject);
writeln( 'Book 2 book_id : ', Book2^.book_id);
dispose(Book1);
dispose(Book2);
end.
编译并执行上述代码时,会产生以下结果 - Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
With 语句 我们已经讨论过可以使用成员访问运算符(。)访问记录的成员。 这样,每次都必须写入记录变量的名称。 With语句提供了另一种方法。 请看我们的第一个示例中的以下代码片段 - (* book 1 specification *)
Book1.title := 'C Programming';
Book1.author := 'Nuha Ali ';
Book1.subject := 'C Programming Tutorial';
Book1.book_id := 6495407;
可以使用With语句编写相同的赋值 - (* book 1 specification *)
With Book1 do
begin
title := 'C Programming';
author := 'Nuha Ali ';
subject := 'C Programming Tutorial';
book_id := 6495407;
end;
Pascal - Variants Pascal支持一种名为variant的独特存储类型。 您可以在变量变量中指定任何简单类型的值。 存储在变体中的值的类型仅在运行时确定。 几乎任何简单类型都可以分配给变体:序数类型,字符串类型,int64类型。 结构化类型(如集合,记录,数组,文件,对象和类)与变量不是分配兼容的。 您还可以指定变量的指针。 Free Pascal支持变体。 声明变体 您可以使用var关键字声明变体类型,就像任何其他类型一样。 声明变体类型的语法是 - var
v: variant;
现在,这个变量变量v可以分配给几乎所有简单类型,包括枚举类型,反之亦然。 type
color = (red, black, white);
var
v : variant;
i : integer;
b : byte;
w : word;
q : int64;
e : extended;
d : double;
en : color;
as : ansistring;
ws : widestring;
begin
v := i;
v := b;
v := w;
v := q;
v := e;
v := en;
v := d:
v := as;
v := ws;
end;
例子 (Example) 以下示例将说明这一概念 - Program exVariant;
uses variants;
type
color = (red, black, white);
var
v : variant;
i : integer;
r: real;
c : color;
as : ansistring;
begin
i := 100;
v:= i;
writeln('Variant as Integer: ', v);
r:= 234.345;
v:= r;
writeln('Variant as real: ', v);
c := red;
v := c;
writeln('Variant as Enumerated data: ', v);
as:= ' I am an AnsiString';
v:= as;
writeln('Variant as AnsiString: ', v);
end.
编译并执行上述代码时,会产生以下结果 - Variant as Integer: 100
Variant as real: 234.345
Variant as Enumerated data: 0
Variant as AnsiString: I am an AnsiString
Pascal - Sets 集合是相同类型的元素的集合。 Pascal允许定义设置数据类型。 集合中的元素称为其成员。 在数学中,集合通过将成员braces{}在braces{}内来表示。 但是,在Pascal中,set元素包含在方括号[]中,它们被称为set构造函数。 定义集类型和变量 Pascal集类型定义为 type
set-identifier = set of base type;
集类型的变量定义为 var
s1, s2, ...: set-identifier;
要么, s1, s2...: set of base type;
一些有效的集类型声明的示例是 - type
Days = (mon, tue, wed, thu, fri, sat, sun);
Letters = set of char;
DaySet = set of days;
Alphabets = set of 'A' .. 'Z';
studentAge = set of 13..20;
设置运算符 您可以在Pascal集上执行以下设置操作。 Sr.No 操作和描述 1 Union 这将连接两个集合,并为两个集合中的成员提供一个新集合。 2 Difference 获取两个集合的差异,并给出一个新集合,其中的元素与任何集合都不相同。 3 Intersection 获取两个集合的交集,并给出一个新集合,其中包含两个集合共有的元素。 4 Inclusion 如果P中的所有项目也在Q中但是反之亦然,则集合P包括在集合Q中。 5 Symmetric difference 获取两个集合的对称差异,并给出一组元素,这些元素位于任一集合中,而不是在它们的交集中。 6 In 它检查会员资格。 下表显示了Free Pascal支持的所有集合运算符。 假设S1和S2是两个字符集,这样 - S1:= ['a','b','c']; S2:= ['c','d','e']; 操作者 描述 例 + 联盟两套 S1 + S2将给出一组 ['a','b','c','d','e'] - 两套的差异 S1-S2将给出一组 ['a','b'] * 交叉两套 S1 * S2将给出一组 ['C'] >< 两组的对称差异 S1> = 检查两组的相等性 S1 = S2将给出布尔值False <> 检查两组不相等 S1 <> S2将给出布尔值True <= 包含(检查一组是否是另一组的子集) S1 <= S2将给出布尔值False Include 包括集合中的元素; 基本上它是一个集合的联合和一个相同基类型的元素 包含(S1,['d'])将给出一组 ['A B C D'] Exclude 从集合中排除元素; 基本上它是一个集合的差异和相同基本类型的元素 排除(S2,['d'])将给出一组 ['c','e'] In 检查设置集合中元素的成员资格 S2中的['e']给出布尔值True 例子 (Example) 以下示例说明了其中一些运算符的使用 - program setColors;
type
color = (red, blue, yellow, green, white, black, orange);
colors = set of color;
procedure displayColors(c : colors);
const
names : array [color] of String[7]
= ('red', 'blue', 'yellow', 'green', 'white', 'black', 'orange');
var
cl : color;
s : String;
begin
s:= ' ';
for cl:=red to orange do
if cl in c then
begin
if (s<>' ') then s :=s +' , ';
s:=s+names[cl];
end;
writeln('[',s,']');
end;
var
c : colors;
begin
c:= [red, blue, yellow, green, white, black, orange];
displayColors(c);
c:=[red, blue]+[yellow, green];
displayColors(c);
c:=[red, blue, yellow, green, white, black, orange] - [green, white];
displayColors(c);
c:= [red, blue, yellow, green, white, black, orange]*[green, white];
displayColors(c);
c:= [red, blue, yellow, green]><[yellow, green, white, black];
displayColors(c);
end.
编译并执行上述代码时,会产生以下结果 - [ red , blue , yellow , green , white , black , orange]
[ red , blue , yellow , green]
[ red , blue , yellow , black , orange]
[ green , white]
[ red , blue , white , black]
Pascal - File Handling Pascal将文件视为一系列组件,它们必须是统一类型。 文件的类型由组件的类型决定。 文件数据类型定义为 - type
file-name = file of base-type;
其中,base-type表示文件组件的类型。 除了另一种文件类型之外,基类型可以是整数,实数,布尔,枚举,子范围,记录,数组和集合。 使用var声明创建文件类型的变量 - var
f1, f2,...: file-name;
以下是定义一些文件类型和文件变量的一些示例 - type
rfile = file of real;
ifile = file of integer;
bfile = file of boolean;
datafile = file of record
arrfile = file of array[1..4] of integer;
var
marks: arrfile;
studentdata: datafile;
rainfalldata: rfile;
tempdata: ifile;
choices: bfile;
创建和写入文件 让我们编写一个程序,为学生的记录创建一个数据文件。 它会创建一个名为students.dat的文件,并将学生的数据写入其中 - program DataFiles;
type
StudentRecord = Record
s_name: String;
s_addr: String;
s_batchcode: String;
end;
var
Student: StudentRecord;
f: file of StudentRecord;
begin
Assign(f,'students.dat');
Rewrite(f);
Student.s_name := 'John Smith';
Student.s_addr := 'United States of America';
Student.s_batchcode := 'Computer Science';
Write(f,Student);
Close(f);
end.
编译和运行时,程序会在工作目录中创建一个名为students.dat的文件。 您可以使用文本编辑器(如记事本)打开文件,以查看John Smith的数据。 从文件中读取 (Reading from a File) 我们刚刚创建并写入名为students.dat的文件中。 现在,让我们编写一个程序,从文件中读取学生的数据 - program DataFiles;
type
StudentRecord = Record
s_name: String;
s_addr: String;
s_batchcode: String;
end;
var
Student: StudentRecord;
f: file of StudentRecord;
begin
assign(f, 'students.dat');
reset(f);
while not eof(f) do
begin
read(f,Student);
writeln('Name: ',Student.s_name);
writeln('Address: ',Student.s_addr);
writeln('Batch Code: ', Student.s_batchcode);
end;
close(f);
end.
编译并执行上述代码时,会产生以下结果 - Name: John Smith
Address: United States of America
Batch Code: Computer Science
文件作为子程序参数 Pascal允许将文件变量用作标准和用户定义的子程序中的参数。 以下示例说明了此概念。 该程序创建一个名为rainfall.txt的文件并存储一些降雨数据。 接下来,它打开文件,读取数据并计算平均降雨量。 请注意, if you use a file parameter with subprograms, it must be declared as a var parameter. program addFiledata;
const
MAX = 4;
type
raindata = file of real;
var
rainfile: raindata;
filename: string;
procedure writedata(var f: raindata);
var
data: real;
i: integer;
begin
rewrite(f, sizeof(data));
for i:=1 to MAX do
begin
writeln('Enter rainfall data: ');
readln(data);
write(f, data);
end;
close(f);
end;
procedure computeAverage(var x: raindata);
var
d, sum: real;
average: real;
begin
reset(x);
sum:= 0.0;
while not eof(x) do
begin
read(x, d);
sum := sum + d;
end;
average := sum/MAX;
close(x);
writeln('Average Rainfall: ', average:7:2);
end;
begin
writeln('Enter the File Name: ');
readln(filename);
assign(rainfile, filename);
writedata(rainfile);
computeAverage(rainfile);
end.
编译并执行上述代码时,会产生以下结果 - Enter the File Name:
rainfall.txt
Enter rainfall data:
34
Enter rainfall data:
45
Enter rainfall data:
56
Enter rainfall data:
78
Average Rainfall: 53.25
文本文件 Pascal中的文本文件由字符行组成,其中每行以行尾标记结束。 您可以声明并定义这样的文件 - type
file-name = text;
普通字符文件和文本文件之间的区别在于文本文件被分成行,每行由特殊的行尾标记终止,由系统自动插入。 以下示例创建并写入名为contact.txt的文本文件 - program exText;
var
filename, data: string;
myfile: text;
begin
writeln('Enter the file name: ');
readln(filename);
assign(myfile, filename);
rewrite(myfile);
writeln(myfile, 'Note to Students: ');
writeln(myfile, 'For details information on Pascal Programming');
writeln(myfile, 'Contact: IOWIKI');
writeln('Completed writing');
close(myfile);
end.
编译并执行上述代码时,会产生以下结果 - Enter the file name:
contact.txt
Completed writing
附加到文件 附加到文件意味着写入已经包含某些数据的现有文件而不覆盖该文件。 以下程序说明了这一点 - program exAppendfile;
var
myfile: text;
info: string;
begin
assign(myfile, 'contact.txt');
append(myfile);
writeln('Contact Details');
writeln('webmaster@iowiki.com');
close(myfile);
(* let us read from this file *)
assign(myfile, 'contact.txt');
reset(myfile);
while not eof(myfile) do
begin
readln(myfile, info);
writeln(info);
end;
close(myfile);
end.
编译并执行上述代码时,会产生以下结果 - Contact Details
webmaster@iowiki.com
Note to Students:
For details information on Pascal Programming
Contact: IOWIKI
文件处理函数 (File Handling Functions) Free Pascal提供以下文件处理功能/程序 - Sr.No. 功能名称和描述 1 procedure Append(var t: Text); 以附加模式打开文件 2 procedure Assign(out f: file; const Name:); 为文件指定名称 3 procedure Assign(out f: file; p: PChar); 为文件指定名称 4 procedure Assign(out f: file; c: Char); 为文件指定名称 5 procedure Assign(out f: TypedFile; const Name:); 为文件指定名称 6 procedure Assign(out f: TypedFile; p: PChar); 为文件指定名称 7 procedure Assign(out f: TypedFile; c: Char); 为文件指定名称 8 procedure Assign(out t: Text; const s:); 为文件指定名称 9 procedure Assign(out t: Text; p: PChar); 为文件指定名称 10 procedure Assign(out t: Text; c: Char); 为文件指定名称 11 procedure BlockRead(var f: file; var Buf; count: Int64; var Result: Int64); 将文件中的数据读入内存 12 procedure BlockRead(var f: file; var Buf; count: LongInt; var Result: LongInt); 将文件中的数据读入内存 13 procedure BlockRead(var f: file; var Buf; count: Cardinal; var Result: Cardinal); 将文件中的数据读入内存 14 procedure BlockRead(var f: file; var Buf; count: Word; var Result: Word); 将文件中的数据读入内存 15 procedure BlockRead(var f: file; var Buf; count: Word; var Result: Integer); 将文件中的数据读入内存 16 procedure BlockRead(var f: file; var Buf; count: Int64); 将文件中的数据读入内存 17 procedure BlockWrite(var f: file; const Buf; Count: Int64; var Result: Int64); 将数据从内存写入文件 18 procedure BlockWrite(var f: file; const Buf; Count: LongInt; var Result: LongInt); 将数据从内存写入文件 19 procedure BlockWrite(var f: file; const Buf; Count: Cardinal; var Result: Cardinal); 将数据从内存写入文件 20 procedure BlockWrite(var f: file; const Buf; Count: Word; var Result: Word); 将数据从内存写入文件 21 procedure BlockWrite(var f: file; const Buf; Count: Word; var Result: Integer); 将数据从内存写入文件 22 procedure BlockWrite(var f: file; const Buf; Count: LongInt); 将数据从内存写入文件 23 procedure Close(var f: file); 关闭文件 24 procedure Close(var t: Text); 关闭文件 25 function EOF(var f: file):Boolean; 检查文件结尾 26 function EOF(var t: Text):Boolean; 检查文件结尾 27 function EOF: Boolean; 检查文件结尾 28 function EOLn(var t: Text):Boolean; 检查行尾 29 function EOLn: Boolean; 检查行尾 30 procedure Erase(var f: file); 从磁盘删除文件 31 procedure Erase(var t: Text); 从磁盘删除文件 32 function FilePos( var f: file):Int64; 在文件中的位置 33 function FileSize(var f: file):Int64; 文件大小 34 procedure Flush(var t: Text); 将文件缓冲区写入磁盘 35 function IOResult: Word; 返回上一个文件IO操作的结果 36 procedure Read(var F: Text; Args: Arguments); 从文件读入变量 37 procedure Read(Args: Arguments); 从文件读入变量 38 procedure ReadLn(var F: Text; Args: Arguments); 从文件读入变量并转到下一行 39 procedure ReadLn(Args: Arguments); 从文件读入变量并转到下一行 40 procedure Rename(var f: file; const s:); 重命名磁盘上的文件 41 procedure Rename(var f: file; p: PChar); 重命名磁盘上的文件 42 procedure Rename(var f: file; c: Char); 重命名磁盘上的文件 43 procedure Rename(var t: Text; const s); 重命名磁盘上的文件 44 procedure Rename(var t: Text; p: PChar); 重命名磁盘上的文件 45 procedure Rename( var t: Text; c: Char); 重命名磁盘上的文件 46 procedure Reset(var f: file; l: LongInt); 打开文件进行阅读 47 procedure Reset(var f: file); 打开文件进行阅读 48 procedure Reset(var f: TypedFile); 打开文件进行阅读 49 procedure Reset(var t: Text); 打开文件进行阅读 50 procedure Rewrite(var f: file; l: LongInt); 打开文件进行写入 51 procedure Rewrite(var f: file); 打开文件进行写入 52 procedure Rewrite(var f: TypedFile); 打开文件进行写入 53 procedure Rewrite(var t: Text); 打开文件进行写入 54 procedure Seek(var f: file; Pos: Int64); 设置文件位置 55 function SeekEOF(var t: Text):Boolean; 将文件位置设置为文件末尾 56 function SeekEOF: Boolean; 将文件位置设置为文件末尾 57 function SeekEOLn(var t: Text):Boolean; 将文件位置设置为行尾 58 function SeekEOLn: Boolean; 将文件位置设置为行尾 59 procedure SetTextBuf(var f: Text; var Buf); 设置文件缓冲区的大小 60 procedure SetTextBuf(var f: Text; var Buf; Size: SizeInt); 设置文件缓冲区的大小 61 procedure Truncate(var F: file); 在位置截断文件 62 procedure Write(Args: Arguments); 将变量写入文件 63 procedure Write(var F: Text; Args: Arguments); 将变量写入文件 64 procedure Writeln(Args: Arguments); 将变量写入文件并附加换行符 65 procedure WriteLn(var F: Text; Args: Arguments); 将变量写入文件并附加换行符 Pascal - Memory Management 本章介绍Pascal中的动态内存管理。 Pascal编程语言为内存分配和管理提供了多种功能。 动态分配内存 在进行编程时,如果您了解数组的大小,那么它很容易,您可以将其定义为数组。 例如,要存储任何人的姓名,它最多可以包含100个字符,因此您可以按如下方式定义内容 - var
name: array[1..100] of char;
但现在,让我们考虑一种情况,您不知道需要存储的文本的长度,例如,您想要存储有关主题的详细说明。 在这里,我们需要定义一个指向string的指针,而不需要定义需要多少内存。 Pascal提供了一个new的过程来创建指针变量。 program exMemory;
var
name: array[1..100] of char;
description: ^string;
begin
name:= 'Zara Ali';
new(description);
if not assigned(description) then
writeln(' Error - unable to allocate required memory')
else
description^ := 'Zara ali a DPS student in class 10th';
writeln('Name = ', name );
writeln('Description: ', description^ );
end.
编译并执行上述代码时,会产生以下结果 - Name = Zara Ali
Description: Zara ali a DPS student in class 10th
现在,如果您需要定义一个具有特定字节数的指针,稍后将引用它,您应该使用getmem函数或getmem过程,它具有以下语法 - procedure Getmem(
out p: pointer;
Size: PtrUInt
);
function GetMem(
size: PtrUInt
):pointer;
在前面的示例中,我们声明了一个指向字符串的指针。 字符串的最大值为255个字节。 如果你真的不需要那么多的空间或更大的空间,就字节而言, getmem子程序允许指定它。 让我们使用getmem重写前面的例子 - program exMemory;
var
name: array[1..100] of char;
description: ^string;
begin
name:= 'Zara Ali';
description := getmem(200);
if not assigned(description) then
writeln(' Error - unable to allocate required memory')
else
description^ := 'Zara ali a DPS student in class 10th';
writeln('Name = ', name );
writeln('Description: ', description^ );
freemem(description);
end.
编译并执行上述代码时,会产生以下结果 - Name = Zara Ali
Description: Zara ali a DPS student in class 10th
因此,您可以完全控制并且可以在分配内存时传递任何大小的值,而不像数组一样,一旦定义了大小,就无法更改。 调整大小和释放内存 当你的程序出来时,操作系统会自动释放程序分配的所有内存,但是当你不再需要内存时,这是一个很好的做法,那么你应该释放那个内存。 Pascal提供了使用new.过程释放动态创建的变量的过程new. 如果使用getmem子程序分配了内存,则需要使用子程序freemem释放该内存。 freemem子程序具有以下语法 - procedure Freemem(
p: pointer;
Size: PtrUInt
);
function Freemem(
p: pointer
):PtrUInt;
或者,您可以通过调用ReAllocMem函数来增加或减少分配的内存块的大小。 让我们再次检查上面的程序,并使用ReAllocMem和freemem子程序。 以下是ReAllocMem的语法 - function ReAllocMem(
var p: pointer;
Size: PtrUInt
):pointer;
以下是使用ReAllocMem和freemem子程序的示例 - program exMemory;
var
name: array[1..100] of char;
description: ^string;
desp: string;
begin
name:= 'Zara Ali';
desp := 'Zara ali a DPS student.';
description := getmem(30);
if not assigned(description) then
writeln('Error - unable to allocate required memory')
else
description^ := desp;
(* Suppose you want to store bigger description *)
description := reallocmem(description, 100);
desp := desp + ' She is in class 10th.';
description^:= desp;
writeln('Name = ', name );
writeln('Description: ', description^ );
freemem(description);
end.
编译并执行上述代码时,会产生以下结果 - Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th
内存管理函数 (Memory Management Functions) Pascal提供了大量内存管理功能,用于实现各种数据结构并在Pascal中实现低级编程。 其中许多功能都依赖于实现。 Free Pascal提供以下内存管理功能和程序 - SN 功能名称和描述 1 function Addr(X: TAnytype):Pointer; 返回变量的地址 2 function Assigned(P: Pointer):Boolean; 检查指针是否有效 3 function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt; 每字节比较2个内存缓冲区字节 4 function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt; 每字节比较2个内存缓冲区字节 5 function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt; 每字节比较2个内存缓冲区字节 6 function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt; 每字节比较2个内存缓冲区字节 7 function Cseg: Word; 返回代码段 8 procedure Dispose(P: Pointer); 释放动态分配的内存 9 procedure Dispose(P: TypedPointer; Des: TProcedure); 释放动态分配的内存 10 function Dseg: Word; 返回数据段 11 procedure FillByte(var x; count: SizeInt; value: Byte); 用8位模式填充内存区域 12 procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char); 填充具有特定字符的内存区域 13 procedure FillDWord( var x; count: SizeInt; value: DWord); 使用32位模式填充内存区域 14 procedure FillQWord( var x; count: SizeInt; value: QWord); 使用64位模式填充内存区域 15 procedure FillWord( var x; count: SizeInt; Value: Word); 使用16位模式填充内存区域 16 procedure Freemem( p: pointer; Size: PtrUInt); 释放分配的内存 17 procedure Freemem( p: pointer ); 释放分配的内存 18 procedure Getmem( out p: pointer; Size: PtrUInt); 分配新内存 19 procedure Getmem( out p: pointer); 分配新内存 20 procedure GetMemoryManager( var MemMgr: TMemoryManager); 返回当前内存管理器 21 function High( Arg: TypeOrVariable):TOrdinal; 返回open数组或枚举的最高索引 22 function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt; 在内存范围中查找字节大小的值 23 function IndexChar( const buf; len: SizeInt; b: Char):SizeInt; 在内存范围中查找char大小的值 24 function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt; 在内存范围中查找DWord大小(32位)的值 25 function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt; 在内存范围中查找QWord大小的值 26 function Indexword( const buf; len: SizeInt; b: Word):SizeInt; 在内存范围中查找字大小的值 27 function IsMemoryManagerSet: Boolean; 是否设置了内存管理器 28 function Low( Arg: TypeOrVariable ):TOrdinal; 返回打开数组或枚举的最低索引 29 procedure Move( const source; var dest; count: SizeInt ); 将数据从内存中的一个位置移动到另一个位置 30 procedure MoveChar0( const buf1; var buf2; len: SizeInt); 将数据移动到第一个零字符 31 procedure New( var P: Pointer); 为变量动态分配内存 32 procedure New( var P: Pointer; Cons: TProcedure); 动态地为变量分配内存 33 function Ofs( var X ):LongInt; 返回变量的偏移量 34 function ptr( sel: LongInt; off: LongInt):farpointer; 将段和偏移量组合到指针 35 function ReAllocMem( var p: pointer; Size: PtrUInt):pointer; 调整堆上的内存块大小 36 function Seg( var X):LongInt; 返回段 37 procedure SetMemoryManager( const MemMgr: TMemoryManager ); 设置内存管理器 38 function Sptr: Pointer; 返回当前堆栈指针 39 function Sseg: Word; 返回堆栈段寄存器值 Pascal - Units Pascal程序可以包含称为单元的模块。 一个单元可能包含一些代码块,而这些代码块又由变量和类型声明,语句,过程等组成.Pascal和Pascal中有许多内置单元允许程序员定义和编写自己的单元以供使用后来在各种节目中。 使用内置单元 使用子句将内置单元和用户定义单元都包含在程序中。 我们已经在Pascal - Variants教程中使用了变体单元。 本教程介绍如何创建和包含用户定义的单元。 但是,让我们首先看看如何在程序中包含内置单元crt - program myprog;
uses crt;
以下示例说明了使用crt单元 - Program Calculate_Area (input, output);
uses crt;
var
a, b, c, s, area: real;
begin
textbackground(white); (* gives a white background *)
clrscr; (*clears the screen *)
textcolor(green); (* text color is green *)
gotoxy(30, 4); (* takes the pointer to the 4th line and 30th column)
writeln('This program calculates area of a triangle:');
writeln('Area = area = sqrt(s(s-a)(s-b)(s-c))');
writeln('S stands for semi-perimeter');
writeln('a, b, c are sides of the triangle');
writeln('Press any key when you are ready');
readkey;
clrscr;
gotoxy(20,3);
write('Enter a: ');
readln(a);
gotoxy(20,5);
write('Enter b:');
readln(b);
gotoxy(20, 7);
write('Enter c: ');
readln(c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
gotoxy(20, 9);
writeln('Area: ',area:10:3);
readkey;
end.
它与我们在Pascal教程开头使用的程序相同,编译并运行它以查找更改的效果。 创建和使用Pascal单元 要创建单元,您需要编写要存储在其中的模块或子程序,并将其保存在扩展名为.pas的文件中。 此文件的第一行应以关键字unit开头,后跟单元名称。 例如 - unit calculateArea;
以下是创建Pascal单元的三个重要步骤 - 文件名和单元名应完全相同。 因此,我们的单位calculateArea将保存在名为calculateArea.pas.的文件中calculateArea.pas. 下一行应包含单个关键字interface 。 在此行之后,您将编写本单元中将包含的所有函数和过程的声明。 在函数声明之后,写下单词implementation ,这又是一个关键字。 在包含关键字实现的行之后,提供所有子程序的定义。 以下程序创建名为calculateArea的单元 - unit CalculateArea;
interface
function RectangleArea( length, width: real): real;
function CircleArea(radius: real) : real;
function TriangleArea( side1, side2, side3: real): real;
implementation
function RectangleArea( length, width: real): real;
begin
RectangleArea := length * width;
end;
function CircleArea(radius: real) : real;
const
PI = 3.14159;
begin
CircleArea := PI * radius * radius;
end;
function TriangleArea( side1, side2, side3: real): real;
var
s, area: real;
begin
s := (side1 + side2 + side3)/2.0;
area := sqrt(s * (s - side1)*(s-side2)*(s-side3));
TriangleArea := area;
end;
end.
接下来,让我们编写一个使用上面定义的单元的简单程序 - program AreaCalculation;
uses CalculateArea,crt;
var
l, w, r, a, b, c, area: real;
begin
clrscr;
l := 5.4;
w := 4.7;
area := RectangleArea(l, w);
writeln('Area of Rectangle 5.4 x 4.7 is: ', area:7:3);
r:= 7.0;
area:= CircleArea(r);
writeln('Area of Circle with radius 7.0 is: ', area:7:3);
a := 3.0;
b:= 4.0;
c:= 5.0;
area:= TriangleArea(a, b, c);
writeln('Area of Triangle 3.0 by 4.0 by 5.0 is: ', area:7:3);
end.
编译并执行上述代码时,会产生以下结果 - Area of Rectangle 5.4 x 4.7 is: 25.380
Area of Circle with radius 7.0 is: 153.938
Area of Triangle 3.0 by 4.0 by 5.0 is: 6.000
Pascal - Date and Time 您编写的大多数软件都需要实现某种形式的日期函数来返回当前日期和时间。 日期是日常生活的重要组成部分,无需思考即可轻松与他们合作。 Pascal还提供了强大的日期算术工具,可以轻松操作日期。 但是,对于不同的编译器,这些函数的实际名称和工作方式是不同的。 获取当前日期和时间 Pascal的TimeToString函数以冒号(:)分隔的形式为您提供当前时间。 以下示例显示如何获取当前时间 - program TimeDemo;
uses sysutils;
begin
writeln ('Current time : ',TimeToStr(Time));
end.
编译并执行上述代码时,会产生以下结果 - Current time : 18:33:08
Date函数以TDateTime格式返回当前日期。 TDateTime是一个double值,需要一些解码和格式化。 以下程序演示了如何在程序中使用它来显示当前日期 - Program DateDemo;
uses sysutils;
var
YY,MM,DD : Word;
begin
writeln ('Date : ',Date);
DeCodeDate (Date,YY,MM,DD);
writeln (format ('Today is (DD/MM/YY): %d/%d/%d ',[dd,mm,yy]));
end.
编译并执行上述代码时,会产生以下结果 - Date: 4.111300000000000E+004
Today is (DD/MM/YY):23/7/2012
Now函数返回当前日期和时间 - Program DatenTimeDemo;
uses sysutils;
begin
writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
end.
编译并执行上述代码时,会产生以下结果 - Date and Time at the time of writing : 23/7/2012 18:51:
Free Pascal提供了一个名为TTimeStamp的简单时间戳结构,它具有以下格式 - type TTimeStamp = record
Time: Integer;
Date: Integer;
end;
各种日期和时间功能 Free Pascal提供以下日期和时间功能 - Sr.No. 功能名称和描述 1 function DateTimeToFileDate(DateTime: TDateTime):LongInt; 将DateTime类型转换为文件日期。 2 function DateTimeToStr( DateTime: TDateTime):; 构造DateTime的字符串表示形式 3 function DateTimeToStr(DateTime: TDateTime; const FormatSettings: TFormatSettings):; 构造DateTime的字符串表示形式 4 procedure DateTimeToString(out Result: ;const FormatStr: ;const DateTime: TDateTime); 构造DateTime的字符串表示形式 5 procedure DateTimeToString(out Result: ; const FormatStr: ; const DateTime: TDateTime; const FormatSettings: TFormatSettings); 构造DateTime的字符串表示形式 6 procedure DateTimeToSystemTime(DateTime: TDateTime; out SystemTime: TSystemTime); 将DateTime转换为系统时间 7 function DateTimeToTimeStamp( DateTime: TDateTime):TTimeStamp; 将DateTime转换为时间戳 8 function DateToStr(Date: TDateTime):; 构造日期的字符串表示 9 function DateToStr(Date: TDateTime; const FormatSettings: TFormatSettings):; 构造日期的字符串表示 10 function Date: TDateTime; 获取当前日期 11 function DayOfWeek(DateTime: TDateTime):Integer; 获取星期几 12 procedure DecodeDate(Date: TDateTime; out Year: Word; out Month: Word; out Day: Word); 将DateTime解码为年月和日 13 procedure DecodeTime(Time: TDateTime; out Hour: Word; out Minute: Word; out Second: Word; out MilliSecond: Word); 将DateTime解码为小时,分钟和秒 14 function EncodeDate(Year: Word; Month: Word; Day: Word):TDateTime; 将日期,日期和月份编码为DateTime 15 function EncodeTime(Hour: Word; Minute: Word; Second: Word; MilliSecond: Word):TDateTime; 将日期,分钟和秒编码到DateTime 16 function FormatDateTime(const FormatStr: ; DateTime: TDateTime):; 返回DateTime的字符串表示形式 17 function FormatDateTime(const FormatStr: ; DateTime: TDateTime; const FormatSettings: TFormatSettings):; 返回DateTime的字符串表示形式 18 function IncMonth(const DateTime: TDateTime; NumberOfMonths: Integer = 1):TDateTime; 添加1个月 19 function IsLeapYear(Year: Word):Boolean; 确定年份是否为闰年 20 function MSecsToTimeStamp(MSecs: Comp):TTimeStamp; 将毫秒数转换为时间戳 21 function Now: TDateTime; 获取当前日期和时间 22 function StrToDateTime(const S:):TDateTime; 将字符串转换为DateTime 23 function StrToDateTime(const s: ShortString; const FormatSettings: TFormatSettings):TDateTime; 将字符串转换为DateTime 24 function StrToDateTime(const s: AnsiString; const FormatSettings: TFormatSettings):TDateTime; 将字符串转换为DateTime 25 function StrToDate(const S: ShortString):TDateTime; 将字符串转换为日期 26 function StrToDate(const S: Ansistring):TDateTime; 将字符串转换为日期 27 function StrToDate(const S: ShortString; separator: Char):TDateTime; 将字符串转换为日期 28 function StrToDate(const S: AnsiString; separator: Char):TDateTime; 将字符串转换为日期 29 function StrToDate(const S: ShortString; const useformat: ; separator: Char):TDateTime; 将字符串转换为日期 30 function StrToDate(const S: AnsiString; const useformat: ; separator: Char):TDateTime; 将字符串转换为日期 31 function StrToDate(const S: PChar; Len: Integer; const useformat: ; separator: Char = #0):TDateTime; 将字符串转换为日期 32 function StrToTime(const S: Shortstring):TDateTime; 将字符串转换为时间 33 function StrToTime(const S: Ansistring):TDateTime; 将字符串转换为时间 34 function StrToTime(const S: ShortString; separator: Char):TDateTime; 将字符串转换为时间 35 function StrToTime(const S: AnsiString; separator: Char):TDateTime; 将字符串转换为时间 36 function StrToTime(const S: ; FormatSettings: TFormatSettings):TDateTime; 将字符串转换为时间 37 function StrToTime(const S: PChar; Len: Integer; separator: Char = #0):TDateTime; 将字符串转换为时间 38 function SystemTimeToDateTime(const SystemTime: TSystemTime):TDateTime; 将系统时间转换为日期时间 39 function TimeStampToDateTime(const TimeStamp: TTimeStamp):TDateTime; 将时间戳转换为DateTime 40 function TimeStampToMSecs(const TimeStamp: TTimeStamp):comp; 将时间戳转换为毫秒数 41 function TimeToStr(Time: TDateTime):; 返回Time的字符串表示形式 42 function TimeToStr(Time: TDateTime; const FormatSettings: TFormatSettings):; 返回Time的字符串表示形式 43 function Time: TDateTime; 获取当前时间 以下示例说明了上述某些功能的使用 - Program DatenTimeDemo;
uses sysutils;
var
year, month, day, hr, min, sec, ms: Word;
begin
writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
writeln('Today is ',LongDayNames[DayOfWeek(Date)]);
writeln;
writeln('Details of Date: ');
DecodeDate(Date,year,month,day);
writeln (Format ('Day: %d',[day]));
writeln (Format ('Month: %d',[month]));
writeln (Format ('Year: %d',[year]));
writeln;
writeln('Details of Time: ');
DecodeTime(Time,hr, min, sec, ms);
writeln (format('Hour: %d:',[hr]));
writeln (format('Minutes: %d:',[min]));
writeln (format('Seconds: %d:',[sec]));
writeln (format('Milliseconds: %d:',[hr]));
end.
编译并执行上述代码时,会产生以下结果: Date and Time at the time of writing : 7/24/2012 8:26:
Today is Tuesday
Details of Date:
Day:24
Month:7
Year: 2012
Details of Time:
Hour: 8
Minutes: 26
Seconds: 21
Milliseconds: 8
Pascal - Object Oriented 我们可以想象我们的宇宙由不同的物体组成,如太阳,地球,月亮等。同样,我们可以想象我们的汽车由不同的物体组成,如车轮,转向,齿轮等。同样,有面向对象的编程概念,假设所有内容都是对象,并使用不同的对象实现软件。 在Pascal中,有两种用于实现现实世界对象的结构数据类型 - Object typesClass typesObject-Oriented Concepts 在我们详细介绍之前,让我们定义与面向对象Pascal相关的重要Pascal术语。 Object - 对象是一种特殊的记录,包含记录等字段; 但是,与记录不同,对象包含过程和函数作为对象的一部分。 这些过程和函数作为指向与对象类型相关的方法的指针。 Class - 类的定义方式与对象几乎相同,但它们的创建方式有所不同。 Class在程序的Heap上分配,而Object在Stack上分配。 它是指向对象的指针,而不是对象本身。 Instantiation of a class - 实例化意味着创建该类类型的变量。 由于类只是一个指针,当声明类类型的变量时,只为指针分配内存,而不是为整个对象分配内存。 只有在使用其构造函数对其进行实例化时,才会为该对象分配内存。 类的实例也称为“对象”,但不要将它们与Object Pascal对象混淆。 在本教程中,我们将为Pascal对象编写'Object',为概念对象或类实例编写'object'。 Member Variables - 这些是在类或对象中定义的变量。 Member Functions - 这些是在类或对象中定义的函数或过程,用于访问对象数据。 Visibility of Members - 对象或类的成员也称为字段。 这些领域具有不同的可见性。 可见性是指成员的可访问性,即这些成员可以访问的确切位置。 对象有三个可见性级别:public,private和protected。 类具有五种可见性类型:公共,私有,严格私有,受保护和已发布。 我们将详细讨论可见性。 Inheritance - 当通过继承父类的现有功能来定义类时,则认为它是继承的。 这里子类将继承父类的所有或几个成员函数和变量。 对象也可以继承。 Parent Class - 由另一个类继承的类。 这也称为基类或超类。 Child Class - 从另一个类继承的类。 这也称为子类或派生类。 Polymorphism - 这是一个面向对象的概念,其中相同的功能可用于不同的目的。 例如,函数名称将保持不变,但它可能需要不同数量的参数,并且可以执行不同的任务。 Pascal类实现多态。 对象不实现多态。 Overloading - 它是一种多态,其中一些或所有运算符具有不同的实现,具体取决于它们的参数类型。 类似地,函数也可以通过不同的实现来重载。 Pascal类实现重载,但Objects不实现。 Data Abstraction - 隐藏实现细节(抽象)的任何数据表示。 Encapsulation - 指我们将所有数据和成员函数封装在一起以形成对象的概念。 Constructor - 指特殊类型的函数,只要从类或对象形成对象,就会自动调用该函数。 Destructor函数 - 指一种特殊类型的函数,只要删除对象或类或超出范围,就会自动调用该函数。 定义Pascal对象 使用类型声明声明对象。 对象声明的一般形式如下 - type object-identifier = object
private
field1 : field-type;
field2 : field-type;
...
public
procedure proc1;
function f1(): function-type;
end;
var objectvar : object-identifier;
让我们定义一个Rectangle Object,它有两个整数类型的数据成员 - length和width以及一些用于操作这些数据成员的成员函数和一个绘制矩形的过程。 type
Rectangle = object
private
length, width: integer;
public
constructor init;
destructor done;
procedure setlength(l: inteter);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
创建对象后,您将能够调用与该对象相关的成员函数。 一个成员函数只能处理相关对象的成员变量。 下面的示例演示如何设置两个矩形对象的长度和宽度,并通过调用成员函数来绘制它们。 r1.setlength(3);
r1.setwidth(7);
writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);
writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
以下是一个完整的示例,说明如何在Pascal中使用对象 - program exObjects;
type
Rectangle = object
private
length, width: integer;
public
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth(): integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
begin
r1.setlength(3);
r1.setwidth(7);
writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);
writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
end.
编译并执行上述代码时,会产生以下结果 - Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
对象成员的可见性 可见性表示对象成员的可访问性。 Pascal对象成员有三种类型的可见性 - Sr.No 可见性和可访问性 1 Public 成员可以由程序单元外的其他单元使用 2 Private 成员只能在当前单位中访问。 3 Protected 成员仅可用于父对象的后续对象。 默认情况下,对象的字段和方法是公共的,并导出到当前单位之外。 Pascal对象的构造函数和析构函数 - Constructors是特殊类型的方法,只要创建对象,就会自动调用这些方法。 只需通过声明一个带有关键字构造函数的方法,就可以在Pascal中创建一个构造函数。 通常,方法名称为Init,但是,您可以提供自己的任何有效标识符。 您可以将任意数量的参数传递给构造函数。 Destructors构函数是在销毁对象期间调用的方法。 析构函数方法会破坏构造函数创建的任何内存分配。 下面的示例将为Rectangle类提供构造函数和析构函数,它将在创建对象时初始化矩形的长度和宽度,并在超出作用域时将其销毁。 program exObjects;
type
Rectangle = object
private
length, width: integer;
public
constructor init(l, w: integer);
destructor done;
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
constructor Rectangle.init(l, w: integer);
begin
length := l;
width := w;
end;
destructor Rectangle.done;
begin
writeln(' Desctructor Called');
end;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth(): integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
begin
r1.init(3, 7);
writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1, init(5, 4));
writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth());
pr1^.draw;
pr1^.init(7, 9);
writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
r1.done;
end.
编译并执行上述代码时,会产生以下结果 - Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Draw a rectangle: 7 by 9
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
Destructor Called
Pascal对象的继承 Pascal对象可以选择从父对象继承。 以下程序说明了Pascal对象中的继承。 让我们创建另一个名为TableTop对象,它继承自Rectangle对象。 program exObjects;
type
Rectangle = object
private
length, width: integer;
public
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
TableTop = object (Rectangle)
private
material: string;
public
function getmaterial(): string;
procedure setmaterial( m: string);
procedure displaydetails;
procedure draw;
end;
var
tt1: TableTop;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth():integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
function TableTop.getmaterial(): string;
begin
getmaterial := material;
end;
procedure TableTop.setmaterial( m: string);
begin
material := m;
end;
procedure TableTop.displaydetails;
begin
writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth());
writeln('Material: ', self.getmaterial());
end;
procedure TableTop.draw();
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
writeln('Material: ', material);
end;
begin
tt1.setlength(3);
tt1.setwidth(7);
tt1.setmaterial('Wood');
tt1.displaydetails();
writeln;
writeln('Calling the Draw method');
tt1.draw();
end.
以下是应注意的重点 - 对象Tabletop继承了Rectangle对象的所有成员。 TableTop也有一个draw方法。 使用TableTop对象调用draw方法时,将调用TableTop的绘制。 有一个名为self的隐式实例,它引用了对象的当前实例。 编译并执行上述代码时,会产生以下结果 - Table Top: 3 by 7
Material: Wood
Calling the Draw Method
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood
Pascal - Classes 您已经看到Pascal Objects展示了面向对象范式的一些特征。 它们实现了封装,数据隐藏和继承,但它们也有局限性。 例如,Pascal Objects不参与多态。 因此,类被广泛用于在程序中实现适当的面向对象行为,尤其是基于GUI的软件。 Class的定义方式与Object几乎相同,但它是指向Object而不是Object本身的指针。 从技术上讲,这意味着Class在程序的堆上分配,而Object在堆栈上分配。 换句话说,当您将变量声明为对象类型时,它将占用堆栈上与对象大小相同的空间,但是当您声明类类型的变量时,它将始终采用指针的大小在堆栈上。 实际的类数据将在堆上。 定义Pascal类 使用类型声明以与对象相同的方式声明类。 类声明的一般形式如下 - type class-identifier = class
private
field1 : field-type;
field2 : field-type;
...
public
constructor create();
procedure proc1;
function f1(): function-type;
end;
var classvar : class-identifier;
值得注意的是以下要点 - 类定义应仅在程序的类型声明部分下。 使用class关键字定义class 。 字段是存在于类的每个实例中的数据项。 方法在类的定义中声明。 Root类中有一个名为Create的预定义构造函数。 每个抽象类和每个具体类都是Root的后代,因此所有类都至少有一个构造函数。 Root类中有一个名为Destroy的预定义析构函数。 每个抽象类和每个具体类都是Root的后代,因此,所有类都至少有一个析构函数。 让我们定义一个Rectangle类,它有两个整数类型数据成员 - 长度和宽度,一些成员函数用于操作这些数据成员和一个绘制矩形的过程。 type
Rectangle = class
private
length, width: integer;
public
constructor create(l, w: integer);
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
让我们编写一个完整的程序,创建一个矩形类的实例并绘制矩形。 这是我们在讨论Pascal对象时使用的相同示例。 您会发现这两个程序几乎相同,但以下情况除外 - 您需要包含{$ mode objfpc}指令才能使用这些类。 您需要包含{$ m +}指令以使用构造函数。 类实例化与对象实例化不同。 只声明变量不会为实例创建空间,您将使用构造函数create来分配内存。 这是完整的例子 - {$mode objfpc} // directive to be used for defining classes
{$m+} // directive to be used for using constructor
program exClass;
type
Rectangle = class
private
length, width: integer;
public
constructor create(l, w: integer);
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
constructor Rectangle.create(l, w: integer);
begin
length := l;
width := w;
end;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth(): integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
begin
r1:= Rectangle.create(3, 7);
writeln(' Draw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
r1.setlength(4);
r1.setwidth(6);
writeln(' Draw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
end.
编译并执行上述代码时,会产生以下结果 - Draw Rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw Rectangle: 4 by 6
* * * * * *
* * * * * *
* * * * * *
* * * * * *
class成员的可见性 可见性表示class成员的可访问性。 Pascal类成员有五种可见性 - Sr.No 可见性和可访问性 1 Public 这些成员始终可访问。 2 Private 只能在包含类定义的模块或单元中访问这些成员。 可以从类方法内部或从它们外部访问它们。 3 Strict Private 这些成员只能从类本身的方法中访问。 同一单元中的其他类或后代类无法访问它们。 4 Protected 这与private相同,除了这些成员可以访问后代类型,即使它们是在其他模块中实现的。 5 Published 这与Public相同,但如果编译器处于{$ M +}状态,编译器将生成这些类的自动流所需的类型信息。 已发布部分中定义的字段必须是类类型。 Pascal类的构造函数和析构函数 构造函数是特殊方法,只要创建对象,就会自动调用这些方法。 因此,我们通过构造函数初始化许多东西来充分利用这种行为。 Pascal提供了一个名为create()的特殊函数来定义构造函数。 您可以将任意数量的参数传递给构造函数。 下面的示例将为名为Books的类创建一个构造函数,它将在创建对象时初始化该书的价格和标题。 program classExample;
{$MODE OBJFPC} //directive to be used for creating classes
{$M+} //directive that allows class constructors and destructors
type
Books = Class
private
title : String;
price: real;
public
constructor Create(t : String; p: real); //default constructor
procedure setTitle(t : String); //sets title for a book
function getTitle() : String; //retrieves title
procedure setPrice(p : real); //sets price for a book
function getPrice() : real; //retrieves price
procedure Display(); // display details of a book
end;
var
physics, chemistry, maths: Books;
//default constructor
constructor Books.Create(t : String; p: real);
begin
title := t;
price := p;
end;
procedure Books.setTitle(t : String); //sets title for a book
begin
title := t;
end;
function Books.getTitle() : String; //retrieves title
begin
getTitle := title;
end;
procedure Books.setPrice(p : real); //sets price for a book
begin
price := p;
end;
function Books.getPrice() : real; //retrieves price
begin
getPrice:= price;
end;
procedure Books.Display();
begin
writeln('Title: ', title);
writeln('Price: ', price:5:2);
end;
begin
physics := Books.Create('Physics for High School', 10);
chemistry := Books.Create('Advanced Chemistry', 15);
maths := Books.Create('Algebra', 7);
physics.Display;
chemistry.Display;
maths.Display;
end.
编译并执行上述代码时,会产生以下结果 - Title: Physics for High School
Price: 10
Title: Advanced Chemistry
Price: 15
Title: Algebra
Price: 7
与名为create的隐式构造函数一样,还有一个隐式析构函数方法destroy,您可以使用它释放类中使用的所有资源。 继承 (Inheritance) Pascal类定义可以选择从父类定义继承。 语法如下 - type
childClas-identifier = class(baseClass-identifier)
< members >
end;
下面的示例提供了一个小说类,它继承了Books类并根据需求添加了更多功能。 program inheritanceExample;
{$MODE OBJFPC} //directive to be used for creating classes
{$M+} //directive that allows class constructors and destructors
type
Books = Class
protected
title : String;
price: real;
public
constructor Create(t : String; p: real); //default constructor
procedure setTitle(t : String); //sets title for a book
function getTitle() : String; //retrieves title
procedure setPrice(p : real); //sets price for a book
function getPrice() : real; //retrieves price
procedure Display(); virtual; // display details of a book
end;
(* Creating a derived class *)
type
Novels = Class(Books)
private
author: String;
public
constructor Create(t: String); overload;
constructor Create(a: String; t: String; p: real); overload;
procedure setAuthor(a: String); // sets author for a book
function getAuthor(): String; // retrieves author name
procedure Display(); override;
end;
var
n1, n2: Novels;
//default constructor
constructor Books.Create(t : String; p: real);
begin
title := t;
price := p;
end;
procedure Books.setTitle(t : String); //sets title for a book
begin
title := t;
end;
function Books.getTitle() : String; //retrieves title
begin
getTitle := title;
end;
procedure Books.setPrice(p : real); //sets price for a book
begin
price := p;
end;
function Books.getPrice() : real; //retrieves price
begin
getPrice:= price;
end;
procedure Books.Display();
begin
writeln('Title: ', title);
writeln('Price: ', price);
end;
(* Now the derived class methods *)
constructor Novels.Create(t: String);
begin
inherited Create(t, 0.0);
author:= ' ';
end;
constructor Novels.Create(a: String; t: String; p: real);
begin
inherited Create(t, p);
author:= a;
end;
procedure Novels.setAuthor(a : String); //sets author for a book
begin
author := a;
end;
function Novels.getAuthor() : String; //retrieves author
begin
getAuthor := author;
end;
procedure Novels.Display();
begin
writeln('Title: ', title);
writeln('Price: ', price:5:2);
writeln('Author: ', author);
end;
begin
n1 := Novels.Create('Gone with the Wind');
n2 := Novels.Create('Ayn Rand','Atlas Shrugged', 467.75);
n1.setAuthor('Margaret Mitchell');
n1.setPrice(375.99);
n1.Display;
n2.Display;
end.
编译并执行上述代码时,会产生以下结果 - Title: Gone with the Wind
Price: 375.99
Author: Margaret Mitchell
Title: Atlas Shrugged
Price: 467.75
Author: Ayn Rand
值得注意的是以下要点 - Books类的成员具有protected可见性。 Novels类有两个构造函数,因此overload运算符用于函数重载。 Books.Display过程已声明为virtual ,因此Novels类中的相同方法可以override它。 Novels.Create构造函数使用inherited关键字调用基类构造函数。 Interfaces 定义接口以向实现者提供通用功能名称。 不同的实现者可以根据他们的要求实现这些接口。 你可以说,接口是由开发人员实现的骨架。 以下是界面示例 - type
Mail = Interface
Procedure SendMail;
Procedure GetMail;
end;
Report = Class(TInterfacedObject, Mail)
Procedure SendMail;
Procedure GetMail;
end;
请注意,当一个类实现一个接口时,它应该实现该接口的所有方法。 如果未实现接口的方法,则编译器将给出错误。 抽象类 抽象类是无法实例化的,只能继承的类。 通过在类定义中包含单词symbol abstract来指定抽象类,如下所示 - type
Shape = ABSTRACT CLASS (Root)
Procedure draw; ABSTRACT;
...
end;
从抽象类继承时,父类声明中标记为abstract的所有方法都必须由子类定义; 此外,必须使用相同的可见性定义这些方法。 静态关键字 将类成员或方法声明为静态使它们可以访问而无需实例化类。 声明为static的成员无法使用实例化的类对象访问(尽管静态方法可以)。 以下示例说明了这一概念 - program StaticExample;
{$mode objfpc}
{$static on}
type
myclass=class
num : integer;static;
end;
var
n1, n2 : myclass;
begin
n1:= myclass.create;
n2:= myclass.create;
n1.num := 12;
writeln(n2.num);
n2.num := 31;
writeln(n1.num);
writeln(myclass.num);
myclass.num := myclass.num + 20;
writeln(n1.num);
writeln(n2.num);
end.
编译并执行上述代码时,会产生以下结果 - 12
31
31
51
51
您必须使用指令{$ static on}来使用静态成员。
<上一篇.Pascal - 课程( Classes)
Pascal - 有用的资源.下一篇>
编程技术
JAVA技术
PYTHON编程
WEB开发
脚本语言
↑回到顶部↑
WIKI教程 @2018
Pascal(结构化编程语言)_百度百科
al(结构化编程语言)_百度百科 网页新闻贴吧知道网盘图片视频地图文库资讯采购百科百度首页登录注册进入词条全站搜索帮助首页秒懂百科特色百科知识专题加入百科百科团队权威合作下载百科APP个人中心PASCAL是一个多义词,请在下列义项上选择浏览(共3个义项)展开添加义项Pascal播报讨论上传视频结构化编程语言收藏查看我的收藏0有用+10本词条由“科普中国”科学百科词条编写与应用工作项目 审核 。Pascal是一种过程式编程语言,由Niklaus Wirth于1968年设计并于1970年发布,并以法国数学家和哲学家Blaise Pascal的名字命名。Pascal可以运行在多种平台上,例如Windows、Mac OS和各种版本的UNIX/Linux。 [3]软件名称Pascal软件平台Windows、Mac OS、UNIX、Linux等 [4]上线时间1971年软件语言Pascal开发商 Niklaus Wirth [5]目录1产生背景2语言特点▪特点▪缺点3主要版本4编程技巧▪基本符号▪开发工具▪语言结构▪保留字▪标识符▪错误代码5运用产生背景播报编辑Pascal由瑞士苏黎世联邦工业大学的Niklaus Wirth教授于六十年代末设计并创立。1971年,以电脑先驱帕斯卡pascal的名字为之命名 [1]。Pascal语言语法严谨,一出世就受到广泛欢迎,迅速地从欧洲传到美国。Pascal基于ALGOL编程语言,为纪念法国数学家和哲学家布莱兹·帕斯卡而命名。维尔特后来开发了类似Pascal的Modula-2和Oberon。在开发Pascal之前,维尔特开发了语言Euler,然后开发了Algol-W。Pascal是最早出现的结构化编程语言,具有丰富的数据类型和简洁灵活的操作语句。高级语言发展过程中,Pascal是一个重要的里程碑。Pascal语言是第一个系统地体现了E.W.Dijkstra和C.A.R.Hoare定义的结构化程序设计概念的语言。最初,Pascal在很大程度上但不是完全地为了教授学生结构化编程。很多代学生已使用Pascal作为本科课程的入门语言。Pascal的变种也逐渐地用于从研究项目到PC游戏和嵌入式系统的所有领域。更新的Pascal编译器存在于广泛使用它的领域。GCC,Gnu C编译器,最初是用Pascal的一种方言Pastel编写的(见GCC#概观)。Pascal是Apple Lisa和早期Mac开发使用的高级语言;最初Macintosh操作系统的部分是从Pascal源代码手工翻译成Motorola 68000汇编语言的。流行的排版系统TeX是由高德纳使用基于DEC PDP-10 Pascal的最初文学编程系统WEB编写的,而像Total Commander的应用是使用Delphi(即Object Pascal)编写的。Object Pascal仍然广泛用于开发像Skype这样的Windows应用。语言特点播报编辑特点丰富的数据结构和构造数据结构的方法。除了整型、实型、布尔型和数组外,还提供了字符、枚举、子域、记录、集合、文件、指针等类型。由这些数据结构可以方便地描述各种事务元。简明灵活的控制结构。具体的结构语句有复合语句、如果语句、情况语句、While 语句、Repeat语句、For 语句和处理记录变量的分量的缩写形式———With 语句。它可称为第一个结构化程序设计语言。编译运行效率高。有利于书写程序设计语言的编译程序。严格的结构化形式。 [2]查错能力强。Pascal强调的结构化编程带来了非结构化语言如Fortran之流无法比拟的美和乐趣,Unix崇尚的“小即是美”、“没有消息就是好消息”。正因为上述特点,Pascal语言可以被方便地用于描述各种算法与数据结构。尤其是对于程序设计的初学者,Pascal语言有益于培养良好的程序设计风格和习惯。高级语言发展过程中,PASCAL是一个重要的里程碑。1971年,瑞士联邦技术学院尼克劳斯·沃尔斯(N.Wirth)教授发明了另一种简单明晰的电脑语言,这就是以电脑先驱帕斯卡的名字命名的PASCAL语言。PASCAL语言语法严谨,编程语言。沃尔斯一生还写作了大量有关程序设计、算法和数据结构的著作,因此,他获得了1984年度“图灵奖”。⒈ 结构化Pascal可以方便地书写出结构化程序,保证了程序的正确性和易读性。在结构化这一点上,Pascal比其它算法语言更好。⒉ 数据类型丰富Pascal是一种强类型语言。它提供了整数型、实数型、字符型、布尔型、枚举型、子界型以及由以上类型构成的数组类型、集合类型、记录类型和文件类型。此外,还提供了其它许多语言中所没有的指针类型。丰富的数据结构和上述的结构化性质,使得Pascal可以被方便地用来描述复杂的算法。⒊ 适用性好既适用于数值运算,也适用于非数值运算领域。有些语言只适用于数值计算,有些语言则适用于商业数据处理和管理领域。Pascal的功能较强,能广泛应用于各种领域。⒋ 书写较自由得益于语句末的分号做分隔符,Pascal允许一行写多个语句,一个语句可以分写在多行上,这样就可以使Pascal程序写得象诗歌格式一样优美,便于阅读,但一行不可超过257个字符。由于以上特点,许多学校选Pascal作为程序设计课程中的一种主要的语言。它能给学生严格而良好的程序设计的基本训练,培养学生结构化程序设计的风格。缺点传统PASCAL的标准库中缺乏对网络编程的支持,并且仅通过自带的graph单元难以实现较好的图形界面(GUI),这些缺点大多需要嵌入汇编语言代码才能得到解决,缺乏与机器语言的接口。另一方面,作为一个面向过程的编程语言,和90年代兴起的面向对象的语言相比,不利于大型软件的开发。尽管Pascal非常流行(然而在八十到九十年代时比21世纪更加流行),依据维尔特的对这种语言的定义来构建Pascal,使它不适合在非教学的场合使用,这遭到了广泛的批评。 推广了C语言的Brian Kernighan早在1981年就在他的论文《Why Pascal Is Not My Favourite Programming Language》对Pascal提出了严厉的抨击。主要版本播报编辑在Pascal问世以来的三十余年间,先后产生了适合于不同机型的各种各样版本。其中影响最大的莫过于Turbo Pascal系列软件。它是由美国Borland公司设计、研制的一种适用于微机的Pascal编译系统。该编译系统由1983年推出1.0版本发展到1992年推出的7.0版本,其版本不断更新,而功能更趋完善。应用最广泛的是Free Pascal 2.04。Pascal有6个主要的版本,分别是Action Pascal Unextended Pascal、Extended Pascal、Object-Oriented Extensions to Pascal、Borland Pascal和Delphi Object Pascal。其中,Unextended Pascal、Extended Pascal和Object-Oriented Extensions to Pascal是由Pascal标准委员会所创立和维护的,Unextended Pascal类似于瑞士Niklaus Wirth教授和K.Jensen于1974年联名发表的Pascal用户手册和报告,而Extended Pascal则是在其基础上进行了扩展,加入了许多新的特性,它们都属于正式的Pascal标准;Object-Oriented Extensions to Pascal是由Pascal标准委员会发表的一份技术报告,在Extended Pascal的基础上增加了一些用以支持面向对象程序设计的特性,但它属于非正式的标准。Action Pascal则以中文作为程序代码表达的语言形式。是一个高级解释性编程语言。Borland Pascal和Delphi Object Pascal是由Borland公司专门为其开发的编译工具设计的Pascal语言,前者是用于DOS的Turbo Pascal系列和Windows 3.x的Turbo Pascal for Windows的传统高级语言,后者是用于Windows的Delphi和Linux的Kylix的面向对象程序设计语言,它们都不是正式的Pascal标准,具有专利性。但由于Turbo Pascal系列和Delphi功能强大并且广为流行,Borland Pascal和Delphi Object Pascal已自成为一种标准,为许多人所熟悉。编程技巧播报编辑基本符号Pascal语言在 OEM-美国 编码下只能使用以下几类基本符号:英文字母A B C D E F G H I J K L M N O P Q R S T U V W X Y Za b c d e f g h i j k l m n o p q r s t u v w x y z数字1 2 3 4 5 6 7 8 9 0其他符号+ - * / = <> <= >= > < ( ):= , . ; : .. ‘ ’ ^ @$ div mod shr shl运算符优先级not,(,)1(最优先)*,/,div,mod,and2xor,+,-,or3不等号<>4(末优先)注:Pascal语言除了可以使用以上规定的字符外,不得使用其他任何符号;注:Pascal中div是整除,mod是求余;Free Pascal 中,大写字母与小写字母没有区别,只是除了字符串中的字母,即是说:A与a被认作同一个字母。ASCII码Pascal中,字符代码是由ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)码进行转换的。由函数chr(x) (求编号x对应的字符)和ord(x) (求字符x或枚举型X对应的编号)进行转换执行。开发工具Turbo PascalTurbo Pascal 它提供了一个集成环境的工作系统,集编辑、编译、运行、调试等多功能于一体。出版年代版本名称主要特色1983Turbo Pascal 1.0Turbo Pascal 2.0Turbo-87 Pascal提高实数运算速度并扩大值域1985Turbo Pascal 3.0增加图形功能Turbo BCD Pascal特别适合应用于商业1987Turbo Pascal 4.0提供集成开发环境(IDE),引入单元概念1988Turbo Pascal 5.0增加调试功能1989Turbo Pascal 5.5支持面向对象的程序设计(OPP)1990Turbo Pascal 6.0提供面向对象的应用框架和库(Turbo Vision)1992Turbo Pascal 7.0面向对象的应用系统、更完善的IDETurbo Vision 2.01993Borland Pascal 7.0 开发Object Windows提供对OLE应用的支持1995Delphi (Object Pascal)开发Object pascal语言,使能应用于网络编程操作Visual PascalFree Pascal2005DEV Pascal 1.9.22008super pascal2010CP Pascal Editor 3.5可输入中文,支持一些Free pascal不支持的过程2011lazarus 0.9.30图形应用程序编辑2012Lazarus 1.0功能更加强大Pascal是一门编程语言,而Turbo Pascal/Free Pascal是Pascal程序的编译系统。Turbo Pascal是DOS下的一种16位编程工具,在Delphi出现之前,它是世界上最多人使用的Pascal编程工具,拥有编译速度极快的先进编译器和功能强大而又简便易用的集成开发环境(IDE),在微机程序员中广为流行,正是它的出现奠定了Pascal在DOS/Windows平台上不可动摇的根基,现常见的版本有Turbo Pascal 5.5、Turbo Pascal 6.0和Borland Turbo Pascal with Objects 7.0。Turbo Pascal 6.0与Turbo Pascal 5.5相比,主要是IDE更为强大,而其程序设计功能改变不大,只是增加了一些新的功能,例如可以内嵌asm汇编语句等。而Borland Turbo Pascal with Objects 7.0(简称Borland Pascal 7.0)则有了新的飞跃,首先是IDE进一步加强,提供了程序浏览器,然后是程序设计功能有了很大的提升,新增了一些十分有用的标准子程序,支持比较完善的面向对象程序设计功能,并提供了DOS实模式、DOS保护模式和Windows模式三种程序编译模式,能够编写出可以使用扩充内存(XMS)的保护模式应用程序或者在Windows 3.x下运行的Windows程序,另外还提供了一个对象窗口库(OWL),使用它可以快速的开发出具有一致的视窗界面(DOS或Windows 3.x)的应用程序。Borland Pascal 7.0在1992年推出,是Turbo Pascal系列在DOS下的最后版本。Free PascalFree Pascal是由一个国际组织开发的32/64位Pascal编程工具,属于自由软件,可用于各种操作系统。根据编译选项的不同,它可以使用Turbo Pascal兼容语法、Delphi 语法或者其它语法进行编写程序。由于它拥有32/64位的编译器,而且一直在更新发展中,因此它的功能比Borland Pascal更加强大,拥有许多现代程序设计的特征。但它对程序员的吸引力比不上拥有VCL和CLX的Delphi和Kylix。Free Pascal是一个在多种版本Pascal和Delphi下的产物,比较成熟的版本是由FreePascal. org发布的2.2.4版本(最新版本为3.0.0),由于是Pascal上的改版,在FP里加入了很多以前没有的东西,例如:FillChar系列内存块赋值语句,用Power代替了**(乘方),但是**还是可以使用。另外FP加强了与内存的互容性,增大对内存的支持,FP里的内存限制是TP和BP里的将近上万倍。FP还进一步加强了单元支持、面向对象程序设计的支持、显卡(声卡)的支持、图形高级覆盖的支持、Windows\Linux\OS/2\..等众多系统的支持。在FP的较稳定版本中,可以方便的利用Win32编译模式,编译出Windows应用程序,与Delphi的功能相当。同时对动态连接库、控件、数据库、文件、网络、OpenGL的深入支持,使得 FP 在各种 Pascal编译系统中脱颖而出。更值得提出的是,FP支持Delphi及C++的部分语言,例如:A+=2这样的C Style语言,在FP里完美支持。FP中支持单目、双目操作符,即所有版本的Pascal的符号和“@”等特殊符号。FP 支持运算符重载,即可以重新自己定义运算符。FP现为竞赛推荐工具。最新发布版本为 2014 年3 月11 日发布的 2.6.4。最新 bugfix 版本为 svn repo 里的 2.4.3。最稳定版本为2.4.4。Free Pascal与Turbo Pascal的区别,Free Pascal使用的是跨平台的32位编译器,最大可以利用4GB的内存。而对于Turbo Pascal来说,由于是16位的编译器,数据类型和变量不能超过64 KB,而且只限在Windows上使用。这使得Free Pascal与Turbo Pascal存在着如下差别:1. 表达式执行的顺序是不确定的。比如表达式a:=f(1)+g(2);不保证f(1)一定在g(2)之前执行;2. 布尔表达式不一定要全部计算,只要最终结果已经能够确定,就不再计算其他部分;3. 乘方x^y可以表示成x**y。但x是实数且y是整数的时候不能这样表示。一般还是用换底公式(exp(y*ln(x)))来计算x^y;4. 因为在Free Pascal中添加了函数重载功能,所以函数和过程在使用时,参数的类型必须和定义的完全一致。函数可以返回复杂的类型,比如记录和数组;5. 在Free Pascal中,集合中的元素都是4个字节长的;6. Free Pascal在程序结束之前一定要关闭输出文件,否则输出文件可能不能被正确地写入;7. Free Pascal支持长文件名。在Windows系统中文件名的大小写是无关的。由于信息学竞赛的评测系统是Linux,而Linux对文件名区分大小写,所以程序中用到的文件名必须和系统中的文件名完全一致。最后,如果代码遵守ANSI Pascal标准,就完全可以从Turbo Pascal移植到Free Pascal中使用。LazarusLazarus是一个用于Free Pascal的快速应用开发(RAD)的面向对象的Pascal集成开发环境(IDE)。Lazarus 对于窗口管理来说是中性的。可以工作在KDE(1.13版本)下,也可以工作在GNOME(1.23版本)或其他窗口管理器(MVM、WindowMaker)。Lazarus的设计目标是应用Free Pascal,所以所有凡是Free Pascal能运行的平台,Lazarus也可以运行。最新版本能运行于Linux,Win9x/2000/xp/win7和FreeBSD。21世纪,已提供32位和64位版本支持。Lazarus的工作界面、外观和操作和Borland 的Delphi IDE非常相似,所不同的是Lazarus 是完全的自由软件。Lazarus 可以直接移植Delphi的代码。Lazarus的编程语言是以Pascal为基础的。Pascal语言具有可读性好、编写容易的特点,这使得它很适合作为基础的开发语言。同时,使用编译器创建的应用程序只生成单个可执行文件(.EXE,但生成的可执行文件体积相对Delphi的来说有点大,只包含一个空窗体的工程生成的可执行文件就达到了10多M。这里,可以通过编译选项来减小可执行文件的大小,可以减为1M多点,然后通过UPX压缩,可以减为600多K。)。正是这种结合,使得Pascal成为Lazarus这种先进开发环境的编程语言。Lazarus的最新版本为1.2.4。CP Pascal EditorCP Pascal Editor 有两大特色,第一,它含有一个初学者知识库,在代码的任意关键字处双击鼠标左键,提示面板上将会显示与该关键词相关的知识,例如数据类型范围等。另外,CP Pascal Editor含有CP代码快速输入模式,这项功能使您可以在编写程序时使用来自其他语言的语法,甚至一些伪代码表达方式。当您完成输入时,CP会自动将这些代码转换为Pascal代码,而且支持中文,弥补了Free Pascal不支持中文的缺陷。在 CP Pascal Editor 中含有中文错误提示信息,并大幅度提高编辑速度,而且它的稳定性好,支持语法高亮,支持代码中输入中文,还具有Math与Crt等常用单元。虽然它的界面还停留在传统的pascal编程界面,有些老套,但从功能上来看十分适合Pascal语言编写者使用。语言结构任何程序设计语言都有一定的规则。使用Pascal语言必须遵循其本身所规定的规则来编写程序。尽管不同版本的Pascal语言所采用的符号的数量、形式不尽相同,但其基本成分一般都符合标准Pascal的规定。下面我们首先来了解Pascal语言的程序基本结构。为了明显起见,先举一个最简单的Pascal程序例子:【例1】programli1(input,output);//程序首部
var
r,l,s:real;//定义变量
begin
write('inputr:');
readln(r);
s:=pi*r*r;
//pi是pascal系统定义的常量,即圆周率,FP中按实数输出为3.1415926535897932E+0000
l:=2*pi*r;
writeln('s=',s:0:6);
//":0:6"是双场宽,用于实型变量的输出,":0"是场宽,":6"是小数部分长度
writeln('l=',l:0:6);
end.//结束从这个简单的程序可以看到:⒈ 一个Pascal程序分为两个部分:程序首部和程序体(或称分程序)。⒉ 程序首部是程序的开头部分,它包括:⑴程序标志。用"program"来标明这是一个Pascal 程序。Pascal规定任何一个控制台Pascal程序的首部都必须以此字开头。在Free Pascal中,首部也可省略。⑵程序名称。由程序设计者自己定义,如例中的li1。在写完程序首部之后,应有一个分号。⒊ 程序体是程序的主体,在有的书本里也称"分程序"。程序体包括说明部分(也可省略)和执行部分两个部分。⑴说明部分用来描述程序中用到的标号、常量、类型、变量、函数、过程等。正如示例中的“var”标注定义变量的名称、类型,其它的标注字段为:label(标号)、const(常量)、type(类型)、var(变量)、function(函数)、procedure(过程)。Pascal规定,凡程序中用到的所有变量、符号常量、数组、过程与函数、记录、文件等数据都必须"先说明,再使用"。⑵执行部分的作用是给出需要计算机执行的操作。执行部分以"begin"开始,以"end"结束,其间有若干个语句,一般为了易于阅读,begin..end中的语句应空2格(不包括“begin”和“end”),语句之间以分号隔开。执行部分之后有一个句点,表示整个程序结束。⒋ Pascal程序的书写方法比较灵活。书写程序应结构清晰、容易阅读理解。在编写程序时希望读者尽量模仿本书中例题程序格式和缩进(两个空格或一个Tab)。⒌ 在程序中,一对大括号间的文字称为注释(也可用(*、*))。注释的内容由人们根据需要书写,可以用英语或汉语表示。注释可以放在任何空格可以出现的位置。编译器对注释不予理睬。1、程序首部程序首部是程序的开头部分,由保留字program后,接程序名及程序参数表组成,结束时一定要有分号。程序名yzhch是用户自己定义的标识符,参数表一般是文件变量名,用于该程序与外界的数据交流。最常用的参数为input和output。Turbo Pascal程序首部中参数表可以省略。2、程序说明部分Pascal语言要求用户将在程序中所使用的标号、常量、类型、变量、记录、文件、以及过程和函数除了Pascal自己预先定义的标准量之外,都必须在说明部分说明后才能在程序执行部分使用。但各个内容部分是可选的,只有执行程序部分需要的时候才进行说明。3、程序执行部分紧接着说明部分的begin和end之间的部分为程序的执行部分。它由一系列语句组成,一条语句执行一定的功能,所有语句完成程序设计的任务。语句之间用“;”隔开,允许一行写多个语句,也允许一个语句写多行。最后一行的end后加“.”号表示结束。所跟其后的语句将无任何作用。Begin与end应配对出现,这是每一个Turbo Pascal程序都必须的。注意:后面将学习到的语句中,也需要引用begin和end作为程序段的分隔标记,但其必须遵守语句规则。数据类型、常量的变量概念计算机处理数据对象是一个广义的概念。例如,125、12.76是数据,’xiang qj zhong’这一串字符也是数据。前者是数值数据,后者是字符串数据,是非数值数据。显然,为了表示这些数据,它们在内存中必须以不同方式存放。为处理这些数据,计算机对它们施加的运算也不同。为此,Turbo Pascal语言建立了数据类型的概念,对描述的数据进行分类。每一种数据类型定义了一个具有相同性质的数据集合。各种数据类型的数据具有不同的性质。程序中所用到的每一个数据,包括常量和变量都有一个和它相联系的类型。由此决定了数据所具有的值,也决定了对该数据所能进行的操作。Pascal语言中数据具有丰富的类型,按它们的特点可以分为简单类型、构造类型、指针类型和过程类型四大类,如图下所示。其中,标准类型用语言系统预先定义的标准标识符表示,整型用integer表示,实型用real表示,布尔型用boolean表示,字符型用char表示。二、常量常量是指在程序中使用的一些具体的整型数、实型数和字符串。(1)整型数:如9、3、-5、0等。(2)实型数:如3.1、-6.1E+20等。(3)字符串:是用单引号括起来的一串字符,如,’book’、’96·5’、’ABC’等。以上列举的都可以作为常量在程序中使用。为了提高程序的可读性并使程序便于修改,在程序中往往用一些标识符来代表具体的常量。在Turbo Pascal语言中,可以给一些常量取个名字用一个标识符代表它,这就是常量定义。例如,Cost=60;Blank=’ ’。经常量定义的标识符又称为常量标识符。在Turbo Pascal语言中,常量定义要写在常量定义部分中。常量定义部分的一般形式:Const(常量标识符1)= (常量1);(常量标识符2)=(常量2);(常量标识符n)=(常量n);Const是保留字,表示开始一个常量定义部分,其后可以有若干个常量定义,这些常量定义之间要用“;”号分隔。例如:ConstCost=60;A=Cost+30;Pi =3.14159;Turbo Pascal语言对常量定义有如下要求:(1)常量定义要放在程序的常量定义部分,即程序首部之后,执行部分之前。(2)必须遵循先定义后使用的原则,即只有已经定义的常量标识符,才能在程序中使用。三、变量在程序执行过程中其值可以改变的数据,称为变量。每个变量都要有一个名称,这就是变量名。变量名由用户自己定义,但必须符合标识符的规定。在一个程序中,一个变量只能属于一种确定的数据类型。因此,程序中出现的每个变量都必须说明其数据类型,这样就规定了该变量的取值范围,也决定了对该变量所能执行的运算操作。变量的类型,可以是标准数据类型integer、real、boolean和char,也可以是用户自定义的各种类型。变量说明形式是:一个变量标识符或由逗号隔开的多个变量标识符在它的冒号":"后面说明其数据类型。在Turbo Pascal程序中,变量说明要写在变量说明部分中。变量说明部分的一般形式:var(变量说明1);(变量说明2);……(变量说明n);其中var是保留字,表示一个变量说明部分开始。一个var可以含有多个不同的变量说明,每个变量说明之间用分号隔开,有时称被分号隔开的变量说明为变量说明项。例如:varx,y:real;chl:char;t,f:boolean;注意:不同类型的变量一般不能互相串用。这里还应指出,变量一经说明系统就在计算机内存中为其分配一个存贮空间。在程序中使用到变量时,就在相应的内存中存入数据或取出数据,这种操作称为变量的访问。标准数据类型Pascal向程序设计者提供了丰富的数据类型,它们用于专门的目的,但却都是由简单的、非构造型的数据类型所构成的。本节介绍Turbo Pascal中最为基本的几种数据类型:整型、实型、布尔型和字符型。它们都是系统定义的简单数据类型,称为标准数据类型,其对应的名字称为标准标识符。1、整型一个整型数据用来存放整数,整型数据可以是正整数、负整数和整数零。Turbo Pascal中的整型常数必须按规定严格书写。Turbo Pascal支持五种预定义整型,它们是短整型(Shortint)、整型(Integer)、长整型(Longint)、字节型(Byte)和字类型(Word),每一种类型规定了相应的整数取值范围以及所占内存字节数(一个字节为8个二进制位)。因此,用户在具体编程定义变量类型时,要根据它们的特点选用适当的类型,以达到理想的效果。当两个不同范围类型的操作数进行运算时,得到的结果属于较大范围的类型。如下表所示。Turbo Pascal语言规定可以对整型数据进行算术运算符+、-、*、/、Div、Mod。它们分别表示加、减、乘、除、整除和取余。这六种运算,要求参加运算的两个数都是整型数,运算结果也是整型数。前四种运算与一般的算术运算加、减、乘、除相同。Div整除运算,是两个整型数相除取整数部分(商的整数部分),得到整型结果。Mod取余运算,是两个整型数相除取余数,余数的符号与被除数符号相同。例如:3 Div 2 = 1 5 Div 7 = 06 Div (-4) = - 1 (-12) Div (-5) = 27 Mod 4 = 3 (14) Mod (-4) = 2(-18) Mod (-6) = 0 6 Mod l7 = 6由此可见,a Mod b,所得结果的符号与a相同,其值(绝对值)在0~∣b∣-1之间。运算符Mod与Div之间有如下关系:a Mod b = a – (a Div b) * b (b<>0)其中Mod运算的结果的符号与a的符号相同。利用以上两种运算可以对正整数进行分离。例如:n为四位数8531,可用下法分离出它的个、十、百、千位。8531 Mod l0 = 1 (个位数)(8531 Mod l00) Div l0 = 3 (十位数)(8531 Mod l000) Div l00 = 5 (百位数)8531 Div 1000= 8 (千位数)利用 a Mod b可以判断a能否被b整除。当a Mod b = 0时,a能被b整除。2、实型一个实型数据用来存放实数。实型数据可以是正实数、负实数和实数零。实型数据一般用小数或指数形式(亦称科学表示法)表示。例如:+1993,33,3.5E+8(=3.5×105), -0.5E-3(=-0.5×10-3,),-20.0,,0.0等都是合法实型数。Turbo Pascal支持一种预定义实型,它们是基本实型(Real)、单精度实型(Single)、双精度实型(Double)、扩展实型(Extended)和装配实型(Comp)。每一种类型规定了相应的实数取值范围和所占内存字节数,以及它们所能达到的精度,即有效数字位数。因此,用户在具体编程时应根据以上的参数适当选用,以达到最佳效果。如下表所示。对于此类实型数据,若其绝对值大于上界,则产生上溢;绝对值小于下界,则产生下溢,下溢导致结果为0。Comp类型的取值范围是-263+1~238-1之间的整数,相当于十进制的-9.218~9.218。由于Comp类型的数据表示成二进制形式的数,这种类型的变量有时处理起来比较方便,特别对于数值很大的整数间的计算,这种数据类型很有用。Turbo Pascal语言允许实型数使用下列运算符进行运算。运算符:+、-、*、/分别表示加、减、乘和除。其中"/"叫实数除,即使两个整型数相除,其结果也总是实型,如: 7/2=3.5 6/3=2.03、字符型用标准标识符Char标明字符型。字符型数据可以是字母、符号、数字(0-9)等ASCII码的所有字符。Turbo Pascal支持扩展ASCII码,共包括256个字符。但非印刷字符是不能在标准显示上显示或打印输出。在计算机内部,字符集的元素是以该元素在字符集内的顺序位置来标记的,位置取值范围为0~255,我们称这些整数为字符在字符集内的序数值或序号。每个字符型数据在内存中占一个字节。将字符用单引号括起来,即成字符常数,如,’X’,’7’,’?’。字符常数可按字符的序数值确定大小关系,也就是说它们的大小由它们所对应的ASCII码值决定,如:’Y’,’Z’,’A’<’a’。由于采用ASCII码,字符依ASCII码序号排列。这样,字符与ASCII码序号有一一对应的映射关系。4、布尔型一个布尔型数据用来存放逻辑值,或称布尔值。Turbo Pascal支持预定义布尔型,以标准标识符Boolean表示。Boolean一词,系根据19世纪英国数学家George boole (1815-1864)的名字而得,George boole为现代布尔代数之父。布尔型数据的值只有两个:True(逻辑真)和False(逻辑假)。布尔型是顺序类型,规定False(大于)、>=(大于等于)、<>(不等于)NOT(非)、AND(与)、OR(或)、XOR(异或)运算关系函 数标准函数。Turbo Pascal语言提供了自变量为整型量的标准函数有顺序函数算术函数和转换函数等。标准函数是Turbo Pascal语言预先定义的,它们实际上是能完成特定功能的称步子程序的程序段。每个标准函数都用一个标识符来标识,每个标准函数都能完成一个特定的功能,在程序中可以直接调用它们。Turbo Pascal语言中某些标准函数与数学中的函数有相似之处。整数类型函数整型是顺序类型,即所有的整型数都是按一定的顺序排列的。如3的后序数是4,350的后序数是351。以后介绍的布尔型、字符型、枚举类型和子界类型等都是顺序类型。顺序函数可以对顺序类型数据进行操作,但要注意它们自变量的取值范围。①前趋函数:Pred(x)的函数值为x-l,例如:Pred (6)=5 Pred (-21)=-22②后继函数:Succ (x)的函数值为x+l,例如:Succ (l5)=16 Succ (-114)= -113③自增函数:Inc (x)的函数值亦为x+1,例如:Inc(24)=25 Inc(-36)=-35④自减函数:Dec(x)的函数值亦为x-1,例如:Dec(45)=44 Dec(-46)=-47绝对值函数:Abs (x)的函数值为︱X︱,例如:Abs (-119)=119 Abs (101)=101平方函数:Sqrt(x)的函数值为X2,例如:Sqrt(-5)=25 Sqrt (10)= 100以上四个函数的结果仍是整型数。⑤奇函数:Odd (x),函数的结果为布尔型。当X为奇数时,函数值为true;当X为偶数时,函数值为false。例如:Odd (13)= True Odd (16)= False⑥字符函数:Chr (X),函数值是序号的ASCII字符,属字符型。例如:Chr (65)=’A’ Chr (32)=’ ’⑦序号函数:Val(X),函数值是ASCII字符所对应的序号,属整型。例如:Val('+')=43 Val('_')=95二、实数类型函数在下列算术函数中,X可以是实型或整型数的表达式。对于函数Abs和Sqr,其结果类型和变量X的类型相同,其他算术函数的结果类型都是实型。绝对值函数Abs(x):函数值为x的绝对值平方函数Sqr (x):函数值为x的平方小数函数Frac (x):函数值为x的小数部分整数函数Int (x):函数值为x的整数部分正弦函数Sin (x):函数值为x的正弦,其申,x的单位为弧度余弦函数Cos (x):函数值为x的余弦,其中,x的单位为弧度指数函数Exp (x):函数值为e*x对数函数Ln (X):函数值为x的自然对数平方根函数的Sqrt (x):函数值为x的平方根反正切函数Arctan(x):函数值为x的反正切,单位为弧度随机函数Random:无自变量时,函数值取(0,1)间的随机小数;有自变量且为Word类型时,函数值取(0,自变量)间的随机整数。三、字符类型函数Turbo Pascal语言提供如下自变量为字符型的标准函数,其中Ch为字符型。后继函数Succ (ch):例如,Succ (’8’)=’9’ Succ (’E’)=’F’对字符集的最后一个字符,Succ函数无意义。前趋函数Pred (ch):例如,Pred (’7’)=’6’ Pred (’B’)=’ A’序数函数Ord (ch)::给出字符ch在ASCII字符集中的序号,结果为整型。注意:Ord (’7’)<>7,正确的是:Ord (’7’)=Ord(’0’)+7=48+7=55若ch是数字字符,则Ord (ch)-Ord ('0')是该数字字符的数值。例如:Ord (’7’)-Ord(’0’)=7前面介绍的字符函数Chr (i)是Ord (ch)的逆函数。例如:Chr (55)= ’7’ Chr (Ord(’A’))=’A’三、布尔类型函数Turbo Pascal语言提供布尔型函数主要是几个字符型函数。Ord (B)例如:Ord (false)=0 Ord (true)=1表达式运算是对数据进行加工处理的过程,得到运算结果的数学公式或其它式子统称为表达式。表达式可以是常量也可以是变量或算式,在表达式中又可分为:算术表达式、逻辑表达式和字符串表达式。1、算术表达式:算术表达式是最常用的表达式,又称为数值表达式。它是通过算术运算符来进行运算的数学公式。我们先来看Visual Basic中的算术运算符:算术运算符运算符表达式 说 明 举 例* X*Y 求X乘Y的值 6*7=42/ X/Y 求X除Y的值(浮点数运算) 2.76/1.2=2.3div X div Y 求X除Y的整数商(对整型数计算) 25=5Mod X mod Y 求X除Y的余数(对整型数运算) 25 mod 4=1+ X+Y 加法运算 32+2=34- X-Y 减法运算 48-21=27由于Visual Basic只能识别按其格式书写的数学表达式,所以必须将我们常用的数学表达式转换成Visual Basic表达式。例如:数学式 Visual Basic表达式2、逻辑运算逻辑运算的结果只有两个:True(真)和False(假)。Visual Basic提供了六种关系运算符和四种逻辑运算符:=(等于)、<(小于)、<=(小于等于)、>(大于)、>=(大于等于)、<>(不等于)NOT(非)、AND(与)、OR(或)、XOR(异或)运算关系p q NOT p p AND q p OR qTrue True False True TrueTrue False False False TrueFalse True True False TrueFalse false True False False例如:5>3 结果为 True, “a”>”b” 结果为False。3、表达式的运算优先顺序在进行表达式的转换过程中,必须了解各种运算的优先顺序,使转换后的表达式能满足数学公式的运算要求。运算优先顺序为:括号→函数→乘方→乘、除→加、减→字符连接运算符→关系运算符→逻辑运算符如果同级的运算是按从左到右次序进行;多层括号由里向外。例:(10+6)*3^2*COS(1)/2*8+7① ④ ③ ⑤ ② ⑥ ⑦ ⑧Sqrt(Abs(p/n-1))+1④ ③ ① ② ⑤2.1 Pascal字符与符号1.标识符(1) 标识符的定义:标识符就是以字母开头的字母数字序列,有效长度为63个字符,并且大小写等效。可以用来标示常量、变量、程序、函数等。例如例1.1中的Area(程序名),pi(符号常量),s、r(变量名)都是标识符。(2) 标识符的分类:a.保留字(关键字)所谓保留字是指在Pascal语言中具有特定的含义,你必须了解它的含义,以便于正确的使用,否则会造成错误。标准Pascal语言中的保留字一共有35个,Turbo Pascal语言一共有51个。下面是Pascal语言的保留字:AND,ARRAY,BEGIN,CASE,CONST,DIV,DO,DOWNTO,ELSE,END,FILE,FOR,FUNTION,GOTO,IF,IN,LABEL,MOD,NIL,NOT,OF,OR,PACKED,PROCEDURE,PROGRAM,RECORD,REPEAT,SET,THEN,TO,TYPE,UNTIL,VAR,WHILE,WITH等b.标准标识符:指Pascal语言预先定义的标识符,具有特殊含义。以下列举了Turbo Pascal语言部分常用的标准表识符:标准常量 False Maxint True标准类型 Boolean Char Real Integer标准函数 Abs Arctan Chr Cos Eof Eoln ExpLn Odd Ord Pred Round Sin SqrSqrt Succ Trunc标准过程 Dispose Get New Pack Page Put ReadReadln Reset Rewrite Unpack Write Writeln标准文件 Input Outputc.用户自定义标识符:由你自己根据需要来定义。(1)选用的标识符不能和保留字相同。(2)语法上允许预定义的标准标识符作为你自己定义的标识符使用,但最好还是不要用。以下列举了你自己在定义标识符时可以用的字符:A..Z,a..z,0..9和_(下划线),其中首位必须是字母,字母不区分大小写。2.2 Pascal数据类型数据是程序设计的一个重要内容,其重要特征----数据类型,确定了该数据的形、取值范围以及所能参与的运算。Turbo Pascal 提供了丰富的数据类型,这些数据类型可以分为三大类:简单类型、构造类型和指针类型,其中简单类型可以分为标准类型(整型、实型、字符型和布尔型)和自定义类型(枚举型和子界型),构造类型可以分为数组类型、集合类型、记录类型和文件类型。这些数据类型中除了指针类型是动态数据类型外,其他的都是静态数据类型。在这些数据类型中的简单类型都是有序类型,除了实型以外的简单类型都是顺序类型,所谓顺序类型就是他们的值不仅是有序的而且是有顺序号。在这里主要介绍整型、实型、字符型和布尔型四种常用的数据类型。1.整型一个整型数据用来存放整数。Turbo Pascal支持五种预定义整型,它们是shortint(短整型)、 integer(整型)、 longint(长整型)、 byte(字节型)和 word(字类型),Turbo Pascal分别用相同的名字作为他们的标识符。每一种类型规定了相应的整数取值范围以及所占用的内存字节数。类型 数值范围 占字节数 格式shortint -128..128 1 带符号8位integer -32768..32767 2 带符号16位longint -2147483648..2147483647 4 带符号32位byte 0..255 1 不带符号8位word 0..65535 2 不带符号16位Turbo Pascal规定了两个预定义整型常量标识符maxint和maxlonint,他们各表示确定的常数值,maxint为32767, longint为2147483647,他们的类型分别是integer 和longint2.实型一个实型数据用来存放实数。Turbo Pascal支持五种预定义实型,它们是real(基本实型)、 single(但精度实型)、double(双精度实型)、extended(扩展实型)、comp(装配实型),Turbo Pascal分别用相同的名字作为他们的标识符。每一种类型规定了相应的实数取值范围、所占用的内存字节数以及它们所能达到的精度类型 数值范围 占字节数 有效位数real 2.9e-39..1.7e38 6 11..12single 1.5e-45..3.4e38 4 7..8double 5.0e-324..1.7e308 8 15..16Turbo Pascal支持两种用于执行实型运算的代码生成模式:软件仿真模式和80x87浮点模式。除了real可以在软件仿真模式下直接运行以外,其他类型必须在80x87浮点模式下运行。3.布尔型一个布尔型数据用来存放逻辑值(布尔值)。布尔型的值只有两个:false和true,并且false的序号是0,true的序号是1。false 和true都是预定义常数标识符,分别表示逻辑假和逻辑真。并且true=<常量>;...<常量标识符>=<常量>;常量标识符的类型由定义它的常量的类型决定。例如:const a=12 隐含说明a是整型;const r=3.21 隐含说明r是实型......(3)常量定义部分必须以保留字const开头,可以包含一个或几个常量定义,而且每个常量均以分号结束。(4)Turbo Pascal类型常量类型常量,又称变量常数,它是Turbo Pascal的一个扩充特性。类型常量的定义与标准Pascal规定的常数定义和变量说明有所区别。类型常量定义的语法格式:const<简单类型常量标识符>:简单类型=常数;例如:constcounter:integer=0;flag:boolean=true;index:0..100=0;2.变量(1)变量:在某个程序中的运行过程中其值可以发生改变的量(2)变量说明:变量说明出现在说明部分。它的语法格式是:var<变量标识符列表>:<类型>;...<变量标识符列表>:<类型>;其中,保留字var表示开始一个变量说明部分。变量标识符列表是一个用逗号隔开的标识符序列,冒号后面的类型是类型标识符。每个变量说明均以分号结束。program (程序名);var定义变量如:integer、real、long int 、short int、boolean(此为,标志的变量)begin程序开始例如:vara,b,c:integer;m,n:real;2.4 标准函数1.算术函数函数标识符 自变量类型 意义 结果类型abs 整型、实型 绝对值 同自变量arctan 整型、实型 反正切 实型cos 整型、实型 余弦 实型exp 整型、实型 指数 实型frac 整型、实型 小数部分 实型int 整型、实型 整数部分 实型ln 整型、实型 自然对数 实型pi 无自变量 圆周率 实型sin 整型、实型 正弦 实型sqr 整型、实型 平方 同自变量sqrt 整型、实型 平方根 实型例:abs(-4)=4 abs(-7.49)=7.49 arctan(0)=0.0sin(pi)=0.0 cos(pi)=-1.0 frac(-3.71)=-0.71int(-3.71)=-3.0 sqr(4)=16 sqrt(4)=22.标准函数函数标识符 自变量类型 意义 结果类型odd 整型 判断奇数 布尔型pred 离散类型 求前趋 同自变量succ 离散类型 求后继 同自变量例:odd(1000)=false pred(2000)=1999 succ(2000)=2001odd(3)=true pred('x')='w succ('x')='y'3.转换函数函数标识符 自变量类型 意义 结果类型chr byte 自变量对应的字符 字符型ord 离散类型 自变量对应的序号 longintround 实型 四舍五入 longinttrunc 实型 截断取整 longint例:chr(66)='B' ord('A')=65 round(-4.3)=-5 trunc(2.88)=24.杂类函数函数标识符 自变量类型 意义 结果类型random 无自变量 [0,1间的随机实数 realrandom word [0,自变量间的随机整数) wordrandomize 无自变量 初始化内部随机数产生器 longintupcase 字符型 使小写英文字母变为大写 字符型downcase 字符型 使小写英文字母变为大写 字符型2.5 运算符和表达式1.运算符和优先级(1)运算符是实型,如果全部的运算对象都是整型并且运算不是除法,则结果为整型,若运算是除法,则结果是实型 a.算术运算符运算符 运算 运算对象 结果类型+ 加 整型、实型 只要有一个运算对象是实型,结果就- 减 整型、实型 是实型,如果全部的运算对象都是整* 乘 整型、实型 型并且运算不是除法,则结果为整型,/ 除 整型、实型 若运算是除法,则结果是实型。div 整除 整型 整型mod 取余 整型 整型b.逻辑运算符运算符 运算 运算对象 结果类型not 逻辑非 布尔型 布尔型and 逻辑与 布尔型 布尔型or 逻辑或 布尔型 布尔型xor 逻辑异或 布尔型 布尔型c.关系运算符运算符 运算 运算对象 结果类型= 等于 简单类型 布尔型<> 不等于 简单类型 布尔型< 小于 简单类型 布尔型> 大于 简单类型 布尔型<= 小于等于 简单类型 布尔型>= 大于等于 简单类型 布尔型(2)优先级运算符 优先级not 1(高)*,/,div,mod,and 2xor,+,-,or 3in,=,<,>,>=,<=,<> 4(低)2.表达式(1)算术表达式:算术表达式是由算术运算符连接常量、变量、函数的式子。算术表达式中各个运算符的次序为: ( )-->函数-->*,/,div,mod-->+,1(2)布尔表达式:Turbo Pascal提供给布尔表达式以下基本操作:逻辑运算和关系运算。(3)数学上的表达式与pascal语言表达式的区别数学表达式PASCAL表达式注意2a 2*a *号不能省略a÷b a/b 除号的写法a≠b a<>b 不等号的写法a≤b a<=b 小于等于号的写法a≥b a>=b 大于等于号的写法主要语句:读入:Read/ReadLn:读入内容/读入内容并将读入指针转到下一行。输出:Write/WriteLn:输出内容/输出内容并将输出指针转到下一行。赋值:<变量>:=<表达式>判断:ifcase循环:forwhileuntil退出:break(跳出循环), exit(跳出过程/函数). halt(终止程序)其它参见Pascal 大小写将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用Pascal 大小写。例如:BackColor但pascal实际并不区分大小写。在字符操作中,大小写有区分。比如'a'<>'A'。程序框架program {程序名} {程序参数表};label//一般省略{标号说明};const{常量说明};type{类型说明};var{变量说明};operator {符号名+参数}beginend;function {(函数名+形参(形参可省略)):函数类型}begin{函数说明};end;procedure {(过程名+形参(形参可省略))}begin{过程说明};end;begin{程序语句};end。保留字Pascal语言中保留字可分为如下6种类型:1.程序、函数、过程的符号:program、function、procedure;2.说明部分的专用定义符号:array、const、file、lable、packed、var、record、set、type、of;3.语句专用符号:case、do、downto、else、for、goto、if、repeat、then、to、until、while、with、forward;4.运算符号:and、not、or、in、div、mod;5.分隔符号:begin、end;6.空指针常量:NULL。标识符标准常量:false,true,maxint.标准类型:integer,real,char,string,boolean,text.标准文件:input,output.标准函数:abs,arctan,chr,cos,eof,eoln,exp,ln,odd,ord,pred,round,sin,sqr,sqrt,succ,trunc.标准过程:get,new,pack,page,put,read,readln,reset,rewrite,unpack,write,writeln.real 实数integer 整型longint 长整型shortint 短整型int64 超长整型single 单精度double 双精度char 单个字符string字符串型ansistring内存字符串型int64 -2^63-2^63-1的整数类型qword无符号的整型(0~2^64-1)begin 开始end 结束if 如果for ... to .... do 循环read 输入 (readln 输入并换行)write 输出(writeln 并换行输出)then 那么(常与if连用)else 否则 (常与if和then连用,当if后面的条件为假时,程序就会执行else后的语句)boolean布尔型true 真false 假错误代码常见错误1无效DOS功能号2文件未找到3路径未找到4打开文件过多5禁止文件存取6无效文件句柄12无效文件存取代码15无效驱动器号16不能删除当前目录17不能跨驱动器改文件名100磁盘读错误101磁盘写错误102文件变量未赋值103文件未打开104文件未用输入方式打开105文件未用输出方式打开106无效数字格式150磁盘写保护151未知单元152驱动器未准备好153未知命令154数据CRC校验错155驱动器请求的结构长度错156磁盘定位错157未知媒介类型158扇区未找到159打印机缺纸160设备写失败161设备读失败162硬件故障200被零除201范围检查错202堆栈溢出错203堆溢出错204无效指针操作205浮点上溢出206浮点下溢出207无效浮点运算208未安装覆盖管理程序209覆盖文件读错210对象未初始化211调用抽象方法212流登计错213**下标越界214**溢出215算术上溢错误216存取非法217控制-C218授权指令219无效的TYPECAST220无效的变体TYPECAST221无效的变体操作222没有变体方法调用DISPATCHER223不能建立变体数组224变体不包含数组225变体数组边界错误226TLS初始化错误错误类型1内存溢出2缺标识符3标识符未定义4标识符重定义5语法错误6实型常量错7整型常量错8字符串常量跨行9文件嵌套过多10非正常文件结束11行过长12缺类型标识符13打开文件过多14无效文件名15文件未找到16磁盘满17无效编译指示18文件过多19指针定义中未定义类型20缺变量标识符21类型错误22结构过长24文件分量不能为文件25无效字符串长度26类型不匹配27无效子界基类型28下界大于上界29缺有序类型30缺整型常数31缺常数32缺整型或实型常数33缺指针类型标识符34无效的函数结果类型35缺标号标识符36缺BEGIN37缺END38缺整型表达式39缺有序表达式40缺布尔表达式41操作数类型与操作符不匹配42表达式错43非法赋值44缺字段标识符45目标文件过长46未定义外部标识符47无效*.OBJ文件记录48代码段过长49数据段过长50缺DO51无效PUBLIC定义52无效EXTRN定义53EXTRN定义过多54缺0F55缺INTERFACE56无效重定位引用57缺THEN58缺T0或DOWNTO59未定义的向前引用60过程过多61无效类型转换62被零除63无效文件类型64不能读写该类型的变量65缺指针变量66缺字符串变量67缺字符串表达式68单元循环引用69单元名不匹配70单元版本不匹配71单元重名72单元文件格式错误73缺IMPLEMENTATI0N74常数与CASE类型不相匹配75缺记录变量76常数越界77缺文件变量78缺指针变量79缺整型或实型表达式80标号不在当前块中81标号已定义82标号未定义83无效参数84缺UNIT85缺“;”86缺“:”87缺“,”88缺“(”89缺“)”90缺“=”91缺“:=”92缺“[”或“(.”93缺“]”或“.)”94缺“.”96变量过多97无效FOR控制变量98缺整型变量99此处不允许用文件100字符串长度不匹配101无效字顺序102缺字符串常数103缺整型或实型变量104缺有序变量105INLINE错106缺字符表达式107重定位项过多112CASE常量越界113语句错114不能调用中断过程116必须在8087方式下编译117未找到目标地址118此处不允许包含文件120缺NIL121无效限定符122无效变量引用123符号过多124语句部分过长126文件必须为变量参数127条件符号过多128条件指令错位130初始条件定义错131过程和函数头与前面定义的不匹配132严重磁盘错误133不能计算该表达式134表达式错误结束135无效格式说明符136无效间接引用137此处不允许结构变量138无SYSTEM单元不能计算139不能存取该符号140无效浮点运算141不能将覆盖编译至内存142缺过程和函数变量143无效过程或函数引用144不能覆盖该单元147缺对象类型148不允许局部对象类型149缺VIRTUAL150缺方法标识符151不允许虚拟构造方法152缺构造方法标识符153缺释放方法标识符154FAIL只允许在构造方法内使用155无效的操作符和操作数组合156缺内存引用157不能加减可重定位符号158无效寄存器组合159未激活286/287指令160无效符号引用161代码生成错162缺ASM运用播报编辑Turbo Pascal系列软件作为开发系统软件与就任软件及实施科学计算和教学的有力工具,下发挥着越来越大的作用。也是国际和全国青少年信息学奥林匹克竞赛指定的语言之一。从历届信息学竞赛的情况看,它是最能出成绩和选手最欢迎的语言。以后的例子就以Turbo Pascal 7.0进行程序设计。下面我们就以一个实例来看一看Pascal程序的结构,从中认识到Pascal语言程序的书写方式,以及其规范的标准设计方式。例1:输入一个圆的半径,求出其圆周长。设圆的半径为R,周长为L,我们知道公式如下:L=2πR它的Pascal程序如下:programyzhch(input,output);{程序首部}
const{常量说明}
pi=3.14159
var{变量说明}
l,r:real;
begin{程序开始}
readln(r);{输入半径}
l:=2*pi*r;{计圆周长}
writeln('l=',l);{输出圆周长}
end.{结束程序}从以上简单的例子可以看出,Pascal程序是由程序首部、程序说明部分和程序执行部分组成。具体如下所示:program程序名;{程序首部}
说明部分{说明部分}
begin{程序开始}
语句1;{执行语句}
语句2;{执行语句}
……
{执行语句}
end.{结束程序}新手上路成长任务编辑入门编辑规则本人编辑我有疑问内容质疑在线客服官方贴吧意见反馈投诉建议举报不良信息未通过词条申诉投诉侵权信息封禁查询与解封©2024 Baidu 使用百度前必读 | 百科协议 | 隐私政策 | 百度百科合作平台 | 京ICP证030173号 京公网安备110000020000
Pascal - 基本语法
Pascal - 基本语法
w3schools 教程
HTML
CSS
JAVASCRIPT
BOOTSTRAP
JQUERY
PHP
SQL
PYTHON
PYTHON2
JAVA
C
C++
C#
Linux
AI
教程库
参考手册
测验
练习
HOWTO
FAQ
Pascal 教程
Pascal - 主页
Pascal - 概述
Pascal - 环境设置
Pascal - 程序结构
Pascal - 基本语法
Pascal - 数据类型
Pascal - 变量类型
Pascal - 常量
Pascal - 运算符
Pascal - 决策
Pascal - 循环
Pascal - 函数
Pascal - 过程
Pascal - 变量作用域
Pascal - 字符串
Pascal - 布尔值
Pascal - 数组
Pascal - 指针
Pascal - 记录
Pascal - 变体
Pascal - 集合
Pascal - 文件处理
Pascal - 内存管理
Pascal - 单元
Pascal - 日期和时间
Pascal - 对象
Pascal - 类
❮ 上一节
下一节 ❯
Pascal - 基本语法
您已经了解了 pascal 程序的基本结构,因此很容易理解 pascal 编程语言的其他基本构建块。
变量
变量定义放在以 var 关键字开头的块中,后面是变量的定义,如下所示:
var
A_Variable, B_Variable ... : Variable_Type;
Pascal 变量在函数的代码体之外声明,这意味着它们不在 begin 和 end 对内声明,但它们是在过程/函数定义之后、begin 关键字之前声明的。 对于全局变量,它们在程序头之后定义。
函数/过程
在 Pascal 中,过程是要执行的指令集,没有返回值,函数是有返回值的过程。 函数/过程的定义如下 −
Function Func_Name(params...) : Return_Value;
Procedure Proc_Name(params...);
注释
多行注释括在大括号和星号内,如 (* ... *)。 Pascal 允许将单行注释括在大括号 { ... } 内。
(* This is a multi-line comments
and it will span multiple lines. *)
{ This is a single line comment in pascal }
区分大小写
Pascal 是一种不区分大小写的语言,这意味着您可以在任何一种情况下编写变量、函数和过程。 与变量 A_Variable 一样,a_variable 和 A_VARIABLE 在 Pascal 中具有相同的含义。
Pascal 语句
Pascal 程序由语句组成。 每条语句都指定了程序的一个明确的工作。 这些工作可以是声明、赋值、读取数据、写入数据、进行逻辑决策、转移程序流程控制等。
例如 −
readln (a, b, c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
writeln(area);
Pascal 中的保留字
Pascal 中的语句是用一些特定的 Pascal 字设计的,这些字称为保留字。 例如,program、input、output、var、real、begin、readline、writeline 和 end 都是保留字。
以下是 Pascal 中可用的保留字列表。
and
array
begin
case
const
div
do
downto
else
end
file
for
function
goto
if
in
label
mod
nil
not
of
or
packed
procedure
program
record
repeat
set
then
to
type
until
var
while
with
Pascal 中的字符集和标识符
Pascal 字符集包括 −
全部大写字母(A-Z)
全部小写字母 (a-z)
所有数字 (0-9)
特殊符号 - + * / := , . ;. () [] = {} ` 空格
Pascal 程序中的实体(如变量和常量、类型、函数、过程和记录等)都有名称或标识符。 标识符是由字母和数字组成的序列,以字母开头。 标识符中不得使用特殊符号和空格。
❮ 上一节
下一节 ❯
颜色选择器
热门教程
HTML 教程
CSS 教程
JavaScript 教程
Python 教程
SQL 教程
PHP 教程
JAVA 教程
Excel 教程
读后有收获微信请站长喝咖啡
报告错误
打印
关于
学习路线
×
错误报告
如果您发现内容有误或提出修改建议,请随时向我们发送 E-mail 邮件:
421660149@qq.com
您的建议:
您的 E-mail:
页面地址:
内容描述:
提交
×
感谢您的帮助!
您的建议已发送到 W3schools。
W3Schools 在线教程提供的内容仅用于学习和测试,不保证内容的正确性。通过使用本站内容随之而来的风险与本站无关。
Copyright 2020-2024 关于我们 | 隐私条款 | 学习路线 | 京ICP备14045893号-9
从pascal入门编程应该看什么书为好? - 知乎
从pascal入门编程应该看什么书为好? - 知乎首页知乎知学堂发现等你来答切换模式登录/注册编程计算机Pascal从pascal入门编程应该看什么书为好?也可以理解为学pascal应该看什么书 要数据结构之类的书吗?显示全部 关注者18被浏览7,155关注问题写回答邀请回答好问题添加评论分享7 个回答默认排序阿怪一名被音樂耽誤的脫口秀演員 关注http://www.tutorialspoint.com/pascal/http://wiki.freepascal.org/Object_Pascal_Tutorial但是現在好像沒什麼寫 Pascal 的必要了的樣子如果是要 debug 的話其實只要是規劃良好的 code 不怎麼需要會都能看明白的(這是 Pascal 的好處)发布于 2015-12-02 21:11赞同 2添加评论分享收藏喜欢收起暮无井见铃C++话题下的优秀答主 关注Free Pascal 的文档。辅以 C & C++ 的正规入门书籍,掌握 C 和部分 C++语法和 Pascal 语法的互换。望题主能努力实践,为 Pascal 续一秒。发布于 2016-08-04 20:58赞同 4添加评论分享收藏喜欢
Pascal - 概述
Pascal - 概述
w3schools 教程
HTML
CSS
JAVASCRIPT
BOOTSTRAP
JQUERY
PHP
SQL
PYTHON
PYTHON2
JAVA
C
C++
C#
Linux
AI
教程库
参考手册
测验
练习
HOWTO
FAQ
Pascal 教程
Pascal - 主页
Pascal - 概述
Pascal - 环境设置
Pascal - 程序结构
Pascal - 基本语法
Pascal - 数据类型
Pascal - 变量类型
Pascal - 常量
Pascal - 运算符
Pascal - 决策
Pascal - 循环
Pascal - 函数
Pascal - 过程
Pascal - 变量作用域
Pascal - 字符串
Pascal - 布尔值
Pascal - 数组
Pascal - 指针
Pascal - 记录
Pascal - 变体
Pascal - 集合
Pascal - 文件处理
Pascal - 内存管理
Pascal - 单元
Pascal - 日期和时间
Pascal - 对象
Pascal - 类
❮ 上一节
下一节 ❯
Pascal - 概述
Pascal 是一种通用高级语言,最初由 Niklaus Wirth 在 20 世纪 70 年代初开发。 它是为了将编程作为一门系统学科进行教学并开发可靠且高效的程序而开发的。
Pascal 是基于 Algol 的语言,包含许多 Algol 结构。 Algol 60 是 Pascal 的子集。 Pascal 提供多种数据类型和编程结构。 Pascal 程序易于理解和维护。
由于多种原因,Pascal 在教学和学术领域越来越受欢迎:
易于学习。
结构化语言。
它生成透明、高效且可靠的程序。
它可以在多种计算机平台上编译。
Pascal 语言的特性
Pascal 具有以下特点 −
Pascal 是一种强类型语言。
它提供广泛的错误检查。
它提供多种数据类型,例如数组、记录、文件和集。
它提供了多种编程结构。
它支持通过函数和过程进行结构化编程。
它支持面向对象编程。
关于 Pascal 的事实
Pascal 语言以法国数学家、计算机开发先驱 Blaise Pascal 的名字命名。
Niklaus Wirth 于 1970 年完成了原始 Pascal 编程语言的开发。
Pascal 基于 Algol 编程语言的块结构风格。
Pascal 被开发为一种适合将编程作为一门系统学科进行教学的语言,其实现既可靠又高效。
ISO 7185 Pascal 标准最初于 1983 年发布。
Pascal 是 Apple Lisa 以及早期 Mac 中用于开发的主要高级语言。
1986 年,Apple Computer 发布了第一个 Object Pascal 实现,1993 年,Pascal 标准委员会发布了 Pascal 的面向对象扩展。
为什么要使用 Pascal?
Pascal 允许程序员定义复杂的结构化数据类型并构建动态和递归数据结构,例如列表、树和图。 Pascal 提供了诸如记录、枚举、子范围、带有关联指针和集合的动态分配变量等功能。
Pascal 允许任意深度的嵌套过程定义。 这确实为学习编程作为基于基本概念的系统学科提供了一个良好的编程环境。
Pascal 最令人惊叹的实现是 −
Skype
Total Commander
TeX
Macromedia Captivate
Apple Lisa
Various PC Games
Embedded Systems
❮ 上一节
下一节 ❯
颜色选择器
热门教程
HTML 教程
CSS 教程
JavaScript 教程
Python 教程
SQL 教程
PHP 教程
JAVA 教程
Excel 教程
读后有收获微信请站长喝咖啡
报告错误
打印
关于
学习路线
×
错误报告
如果您发现内容有误或提出修改建议,请随时向我们发送 E-mail 邮件:
421660149@qq.com
您的建议:
您的 E-mail:
页面地址:
内容描述:
提交
×
感谢您的帮助!
您的建议已发送到 W3schools。
W3Schools 在线教程提供的内容仅用于学习和测试,不保证内容的正确性。通过使用本站内容随之而来的风险与本站无关。
Copyright 2020-2024 关于我们 | 隐私条款 | 学习路线 | 京ICP备14045893号-9
Basic Pascal Tutorial/zh CN - Free Pascal wiki
Basic Pascal Tutorial/zh CN - Free Pascal wiki
Basic Pascal Tutorial/zh CNFrom Free Pascal wikiJump to navigationJump to search
│
العربية (ar) │
български (bg) │
Deutsch (de) │
English (en) │
español (es) │
français (fr) │
italiano (it) │
日本語 (ja) │
한국어 (ko) │
русский (ru) │
slovenčina (sk) │
中文(中国大陆) (zh_CN) │
Contents
1 概览
2 目录
概览
Tao Yue 已经撰写了一份优秀的Pascal概览和教程,并且慷慨地同意将其wiki化后在Lazarus-ccr上公布,提供如下:
我们公布的内容的原始教程在https://www.taoyue.com/tutorials/pascal/
需要澄清的是这里的页面可能从原始页面修改了一些内容。
转帖Tao Yue在此wiki之外的其它地方撰写的部分内容之前,请联系原作者以获得许可。
这份教程能在这里打开:面对对象Pascal教程(Tao Yue著)或者下面的目录表
目录
面对对象Pascal语言简介
面对对象Pascal语言历史
Pascal语言编译器
Hello, world
1. 基础
程序结构
标识符
常量
变量和数据类型
赋值和操作符
标准函数
标点符号和缩进
编程作业
参考答案
2. 输入输出
输入
输出
格式化输出
文件操作
EOLN 和 EOF
编程作业2
参考答案2
3. 程序流程
顺序控制
布尔表达式
分支结构
IF语句
CASE语句
循环结构
FOR..DO循环
WHILE..DO循环
REPEAT..UNTIL循环
FOR..IN循环
编程作业3: 斐波那契数列和平方
参考答案3
4. 子程序
过程
参数传递
函数
变量作用域
递归调用
向前引用
编程作业4: 汉诺塔
参考答案4
5. 复合数据类型
枚举类型
子界类型
一维数组
多维数组
记录类型
指针类型
6. 结束语
Retrieved from "http://wiki.freepascal.org/index.php?title=Basic_Pascal_Tutorial/zh_CN&oldid=155197"
Categories: zhFPC/zh CNPascal/zh CNTutorials/zh CNNavigation menuPage actionsPageDiscussionView sourceHistoryPage actionsPageDiscussionMoreToolsIn other languagesPersonal toolsCreate accountLog inNavigationMain PageDocumentationFAQDownloadsGlossaryIndexRecent changesRandom pageHelpToolsWhat links hereRelated changesSpecial pagesPrintable versionPermanent linkPage informationSearch This page was last edited on 25 January 2023, at 03:37.Content is available under unless otherwise noted.Privacy policyAbout Free Pascal wikiDisclaimers