imtoken官网网站|pascal语言教程

作者: imtoken官网网站
2024-03-07 20:27:33

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 于 1968 年设计并于 1970 年发布,并以法国数学家和哲学家布莱斯·帕斯卡 (Blaise Pascal) 的名字命名。 Pascal 运行在多种平台上,例如 Windows、Mac OS 和各种版本的 UNIX/Linux。 本教程应该向您介绍 Pascal 的理解,以便继续使用 Delphi 和其他相关框架等。

谁适合阅读?

本教程专为愿意通过简单的步骤学习 Pascal 编程语言的软件专业人员而设计。 本教程应该让您对 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|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是一种程序编程语言,于1968年设计,由Niklaus Wirth于1970年出版,以纪念法国数学家和哲学家Blaise Pascal而命名。 Pascal运行在各种平台上,例如Windows,Mac OS和各种版本的UNIX/Linux。 本教程应向您介绍Pascal的理解,以继续Delphi和其他相关框架等。 听众 (Audience) 本教程适用于愿意通过简单易用的步骤学习Pascal编程语言的软件专业人员。 本教程应该让您对Pascal编程概念有基本的了解,在完成本教程之后,您应该具备中等水平的专业知识,从而可以将自己提升到更高水平的专业知识。 先决条件 (Prerequisites) 在继续本教程之前,您应该对软件基本概念有基本的了解,例如源代码,编译器,文本编辑器和程序执行等。如果您已经了解任何其他计算机编程语言,那么它将被添加继续优势。

<上一篇.Pascal - 教程

Pascal - 概述.下一篇>

编程技术

JAVA技术

PYTHON编程

WEB开发

脚本语言

↑回到顶部↑

WIKI教程 @2018

Pascal 基础教程 - Chaobs - 博客园

Pascal 基础教程 - Chaobs - 博客园

会员

周边

新闻

博问

AI培训

云市场

所有博客

当前博客

我的博客

我的园子

账号设置

简洁模式 ...

退出登录

注册

登录

Chaobs

不要想你能为世界做什么,想想你该为世界做什么!

博客园

首页

新随笔

联系

订阅

管理

Pascal 基础教程

Pascal现在还有人想学习吗?先给出一本不错的Pascal教程,Object Pascal的教程我日后给出。

Pascal基础教程

 

 

 

第一课  初识PASCAL语言           …………………… 1

  第二课  赋值语句与简单的输出语句  …………………… 5

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

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

  第五课  if嵌套与case语句         …………………… 23

  第六课  for循环                   …………………… 29

  第七课  while循环与repeat-until循环 …………………30

  第八课  一维数组                   …………………… 35

  第九课  多维数组                   …………………… 39

  第十课  字符数组与字符串           …………………… 45

  第十一课 枚举、子界、集合及记录类型

…………………… 51

  第十二课 过程与函数                 …………………… 66

  第十三课 动态数据类型(指针类型)   …………………… 76

  第十四课 文件                       …………………… 89

 

附录一    Pascal中的字符串函数和数学函数 ……………… 111

 

附录二    关于fillchar的使用和讨论    …………………… 116

 

附录三   

程序的调试技巧             …………………… 117

 

附录四   

Pascal的多种退出语句用法   …………………… 123

 

 

 

 

第一课 初识Pascal语言

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

一、Pascal 语言概述

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

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

二、Pascal 语言的特点

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

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

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

  ⒊能适用于数值运算和非数值运算领域。有些语言(如FORTRAN 66,ALGOL 60)只适用于数值计算,有些语言(如COBOL )则适用于商业数据处理和管理领域。PASCAL的功能较强,能广泛应用于各种领域。PASCAL语言还可以用于辅助设计,实现计算机绘图功能。

  ⒋PASCAL程序的书写格式比较自由。不象FORTRAN和COBOL那样对程序的书写格式有严格的规定。PASCAL允许一行写多个语句,一个语句可以分写在多行上,这样就可以使PASCAL程序写得象诗歌格式一样优美,便于阅读。

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

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

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

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

 

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

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

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

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

  ⑵程序名称。由程序设计者自己定义,如例中的exam1。

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

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

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

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

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

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

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

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

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

四、Turbo Pascal语言系统的使用

  目前,常用的Pascal语言系统有Turbo Pascal7.0与Borland Pascal 7.0,下面我们就来学习Turbo Pascal 7.0系统的使用。 1. 系统的启动

  在运行系统目录下的启动程序TURBO.EXE,即可启动系统。屏幕上出现如图1所示的集成环境。

2. Turbo Pascal系统集成环境简介

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

3. 新建程序窗口

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

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

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

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

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

5.程序的保存与打开

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

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

五、第一个程序

  下面程序在运行时,会提示输入一个圆的半径,然后会在屏幕上画一个圆。按回车后程序结束回到程序窗口。

Program ex1;

Uses graph;

Var Gm,Gd,R :integer;

Begin

Gd:=0;

Write('Please enter the radius:');readln(R);

Initgraph(Gm,Gd,' ');

Setcolor(Green);

Circle(320,240,R);

Readln;

Closegraph;

End.

  注意,如果上面程序运行时会出现初始化图形错误,请将系统目录下BGI子目录EGAVGA.BGI和UNITS子目录中的Graph.tpu拷贝到系统目录下BIN目录即可。

  请输入上面的程序,并练习将其存盘、打开与运行上面程序。

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

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

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

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

(一)常量

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

  ⒈整型常量

整型常量采用我们平常使用的十进制整数表示。如138,0,-512等都是整型常量,而18.或18.0都不是整型常量。

pascal中有一个标准标识符Maxint,它代表所使用的计算机系统允许的最大整型数,而最小的整型数即为-Maxint-1。

一个整型数据用来存放整数。Turbo Pascal支持五种预定义整型,它们是shortint(短整型)、 integer(整型)、 longint(长整型)、 byte(字节型)和 word(字类型),Turbo Pascal分别用相同的名字作为他们的表识符。每一种类型规定了相应的整数取值范围以及所占用的内存字节数。

类型          数值范围                    占字节数            格式

shortint     -128..128                       1              带符号8位

inteter      -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,

maxlongint为2147483647,他们的类型分别是integer

和longint。

  ⒉实型常量

  实型常量包括正实数、负实数和实数零。pascal中表示实型常量的形式有两种。

  ⑴十进制表示法

  这是人们日常使用的带小数点的表示方法。

  如0.0,-0.0,+5.61,-8.0,-6.050等都是实型常量,而0.,.37都不是合法的实数形式。

  ⑵科学记数法

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

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

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

一个实型数据用类存放实数。Turbo Pascal支持五种预定义实型,它们是real(基本实型)、 single(但精度实型)、double(双精度实型)、extended(扩展实型)、comp(装配实型),Turbo Pascal分别用相同的名字作为他们的表识符。每一种类型规定了相应的实数取值范围、所占用的内存字节数以及它们所能达到的精度。

类型             数值范围             占字节数           有效位数

real           2.9e-39..1.7e38           6              

 11..12

single         1.5e-45..3.4e38           4                7..8

double         5.0e-324..1.7e308         8                15..16

extended       3.4e-4932..1.1e4932       10               19..20

comp           -2**63+1..2**63-1         8                19..20

Turbo Pascal支持两种用于执行实型运算的代码生成模式:软件仿真模式和80x87浮点模式。除了real可以在软件仿真模式下直接运行以外,其他类型必须在80x87浮点模式下运行。

⒊字符常量

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

4.布尔常量

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

5.符号常量

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

  定义符号常量的一般格式:

CONST

<常量标识符>=<常量>

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

 

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

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

  ⑴符号常量一经定义,在程序的执行部分就只能使用该常量标识符,而不能修改其值。

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

  (二)变量

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

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

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

  1.变量名

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

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

  2.变量的类型

  常量是有类型的数据,变量在某一固定时刻用来存放一个常量,因此也应有相应的类型。如整型变量用来存放整数,实型变量用来存放实数。

  3.变量说明

  在程序中若要使用变量,变量的名称及类型在程序的变量说明部分加以定义,变量的值则在程序的执行部分中才能赋给。

  变量说明的一般格式:

  VAR

<变量标识符>[,<变量标识符>]:<类型>;

(中括号内部分表示可省,下同)

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

例如:

var

age,day:integer;

amount,average:real;

  其中,Integer(整型)、Real(实型)是标准标识符, 它们是"类型标识符",代表了确定的类型,如age和 day 被定义为整型变量,amount和average被定义为实型变量。

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

(三)算术表达式

⑴算术表达式的定义

  pascal语言中的算术表达式是由符合pascal语法规定的运算对象(包括常量、变量、函数)、算术运算符、圆括号组成的有意义的式子。如:A+3.14159*5/8.4-Abs(-1123)

⑵算术运算符

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

  ① + (加)

  ② - (减)

  ③ * (乘)

  ④ / (实数除)得到结果为实型.如5.0/2.0=2.5, 5/2=

2. 5,4/2=2.0而不等于2。

  ⑤ DIV (整除) DIV它要求除数和被除数均为整型, 结果也为整型。如10 DIV 2=5,10 DIV 3=3, 5 DIV 10=0.

-15 DIV 4= -3。DIV运算只取商的整数部分,参与DIV运算的两个对象不能为实型。

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

(3)运算优先顺序

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

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

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

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

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

二、赋值语句

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

1、 赋值语句的格式

变量名:=表达式;

其中":="称为赋值号。

2、 执行过程

计算机先计算赋值号右边表达式的值,然后将表达式的值赋给变量名代表的变量。如:A:=(9*8)-(2-1); A:=A+1

三、输出语句

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

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

1、 write语句

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

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

write(1.2,3.4,5);

write('My name is Liping');

2、 writeln语句

格式:

Write(表达式1,表达式2,……)或writeln

(二)输出语句的功能

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

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

例如以下两个程序段的输出分别为:

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

输出为:

123456

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

输出为:

1234

56

四、应用例析

例1:

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

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

程序可写如下:

Program ex1;

Var A : integer;

Begin

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

A:=A+20;Writeln('5/2:',A);

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

A:=A *4; writeln('5/4:',A);Readln;

End.

例2:

   有三个小朋友甲乙丙。甲有50粒糖果,乙有43粒糖果,两有13粒糖果。现在他们做一个游戏。从甲开始,将自己的糖分三份,自己留一份,其余两份分别给乙与丙,多余的糖果自己吃掉,然后乙与丙也依次这样做。问最后甲、乙、丙三人各有书多少粒糖果?

分析:

   这个问题中我们关心的是在游戏过程中每个小朋友的糖果个数,且他们所拥有的的糖果数是在变化的。因此可用a,b,c三个变量分别存放甲乙丙三个小朋友在某一时刻所拥有的糖果数。对于每人,分糖后,他的糖果数一定为原来的糖果数 div 3(因为分糖过程糖果的数目不一定都刚好分完,用整除恰恰可以表示多余的糖自己吃掉)。而其他两人则增加与这个小朋友现在拥有的一样的糖果。

程序可写如下:

program ex2;

 var A,B,C:integer;

begin

 A:=50;B:=43;C:=13; {初始时每个小朋友所拥有的糖果数}

 A:=A div 3; B:=B+A;C:=C+A;{甲小朋友分糖果后,每个人拥有的糖果数变化情况}

 B:=B div 3; A:=A+B;C:=C+B; {乙小朋友分糖果后,每个人拥有的糖果数变化情况}

 C:=C div 3; A:=A+C;B:=B+C; {丙小朋友分糖果后,每个人拥有的糖果数变化情况}

 writeln('A=',A,'B=',B,'C=',C); {输出结果}

 readln;

end.

注:

   上程序中倒数第三行中'A='表示一个字符串(即用一对单引号括起来的一串字符),对于字符串,输出字符串的内容(即引号内的所得字符,而引号不输出)。

以上程序的运行结果为:

A=51B=35C=16

练习二

1、已知某梯形的上底A=13,下底B=18,高H=9,求它的面积S。

2、某机关组织游泳比赛。将一堆西瓜分给前三名,把该堆西瓜中的一半又半个西瓜奖给第一名;剩下的一半又半个西瓜给第二名;把最后剩下的一半又半个西瓜给第三名,但每次分时并没切开任何一个西瓜,且刚好西瓜分完。问前三名各分到多少个西瓜

3、已知某圆的半径R=139,求该圆的周长C与面积S?

 

 

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

一、写语句的输出格式

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

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

⒈隐含的输出格式

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

       标准场宽

  ━━━━━━━━━━━━━━━━━

  数据类型  标准pascal Turbo pascal

  ─────────────────

  integer 10 实际长度

  real 22 17

  布尔型 10 4或5

  字符串 串长 串长

  ━━━━━━━━━━━━━━━━━

在Turbo Pascal系统中,对于整型字符串的输出都是按数据本身长度输出,对于布尔型数据(只有True和False两种值),TRUE为4列,FALSE为5列,一律采用大写输出。而real型数据的输出时,则按17列输出,其中第一列为符号位,正号不显示,后四位为"E±nn", 中间的12列为尾数部分。如:

writeln(sqrt(75));

则输出□8.6602540379E+00。

而writeln(sqrt(81));

则输出□9.0000000000E+00。

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

⒉指定场宽

  在写语句中输出项含有格式符号时,就是为了指定场宽。

⑴指定单场宽.

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

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

输出结果:

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

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

⑵指定双场宽

  如果输出项是实数时,如果希望输出的实数不用科学记数法输出,而用小数形式输出,可以用指定双场宽方法输出。

  双场宽输出格式为:write(实型表达式:m:n),其中m和n都是自然数,m 用以指定整个数据所占的宽度,n指定输出实数的小数位数。

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

输出:□□□8.6602

  如果双场宽不能满足输出数据的最低要求, 系统自动突破指定的场宽限制,按实际长度输出。

 

如:write(sqrt(75):5:4); 要使小数点后有4位数字,而总场宽为5,是不可能的(因为还有一个小数点, 小数点前面还有一个数字)。它最低限度要有6列,即输出为:

8.6602

例1

   写出下列程序在turbo pascal下的输出结果.

program ex;

 const s='abcdefg';

var

 i:integer;

 r:real;

 c:char;b:boolean;

begin

 i:=1234;r:=1234.5678;

 c:='#';b:=true;

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

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

 writeln(c,c:5);

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

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

end.

运行结果如下:

1234□□12341234

□1.2345678000E+03□□1234.567801234.56780

#□□□□#

abcdefg□□□abcdefgabcdefg

TRUE□TRUETRUE

3.应用例析

例2:

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

253*43=10879

253

* 43

759

+1012

10879

分析:

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

参与程序如下:

var a,b:integer;

begin

 a:=253;b:=43;

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

 writeln(a:12);

 write('*':8);writeln(b:4);

 writeln('--------':12);

 writeln(a*3:12);

 write('+':6);writeln(a*4:5);

 writeln('--------':12);

 writeln(a*b:12);

end.

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

1.读语句的一般格式:

  read(<变量名表>);

readln[(<变量名表>)];

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

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

  说明:

  ①read和readln是标准过程名,它们是标准标识符。

  ②执行到read或readln语句时,系统处于等待状态,等待用户从键盘上输入数据,系统根据变量的数据类型的语法要求判断输入的字符是否合法。如执行read(a)语句,a是整型变量,则输入的字符为数字字符时是合法的,当输入结束时,则自动将刚接受的一串数字字符转换为整数赋给变量a。

  ③在输入数值型(整型或实型)数据时,数据间要用空格或回车分隔开各个数据,输入足够个数的数据,否则仍要继续等待输入,但最后一定要有回车,表示该输入行结束,直到数据足够,该读语句执行结束,程序继续运行。

例3.

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

Read(a,b,c);

   根据③,即可列出所有可能输入格式

  (a)10□20□30←┘

  (b)10□20←┘

    30←┘

  (c)10←┘

    20□30←┘

  (d)10←┘

    20←┘

    30←┘

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

  ④read语句与readln语句的第一个区别是:

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

  Read(a,b);

  Read(c,d);

  Read(e);

如果输入数据行如下:

1□2□3□4□5□6□←┘

则a,b,c,d,e的值分别为1,2,3,4,5,如果后面无读语句则数据6是多余的,这是允许的。

  Readln则不同,在读完本Readln语句中变量所需的数据后, 该数据行中剩余的数据多余无用,或者说,在读完本Readln语句中变量所需数据后,一定要读到一个回车,否则多余的数据无用。

例4

   设要达到例1同样的目的,但语句改为:

readln(a,b);readln(c)

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

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

  

例5

   设有下列语句:

read(a,b,c);

readln(d,e);

readln;

readln(f,g);

  其中,所有变量均为整型。再设输入的数据如下:

  1□2←┘

  3□4□5□6□7□8←┘

  9□10←┘

  11←┘

  12□13←┘

列表给出每个变量的值.

分析:

   可以假想有一"数据位置指针",每读一个数据后,指针后移到该数据之后,每执行一个readln语句后,指针移到下一个数据行的开头。

  各变量的值如下表所示。

━━━━━━━━━━━━━━━━━━━━━━━━━━

变量名 a b c d e f g

──────────────────────────

值 1 2 3 4 5 11 12

──────────────────────────

  ⑥为了避免可能出现的错误,建议在程序中按下列原则使用读语句:(A)如果没有特殊需要,在一个程序中尽量避免混合使用read语句和readln语句;(B)尽量用readln语句来输入数据, 一个数据行对应一个readln语句;(C)由于执行read或readln语句时, 系统不会提供任何提示信息,因此,编程时最好在readln语句之前加以适当提示,例如:

write('Input a,b,c:');

readln(a,b,c);

在执行时,屏幕上显示:

Input a,b,c:■

其中,"■"为光标。执行readln语句后,系统处于待待输入状态, 只有输入了所需数据后才继续往下执行。

三、顺序结构程序设计

  到目前为止,我们可以用读、写语句和赋值语句编写一些简单的程序。通过阅读这些程序,可以逐步熟悉pascal程序的编写方法和应遵循的规则,为以后各章的学习打基础。

  

例6

   试编一程序,输入一梯形的上底、下底、高, 求该梯形的面积。

分析:

   整个程序分为三段:输入、计算、输出。程序中用a,b,h三个变量分别存放梯形的上、下底与高,S存放面积。 要而使用这些变量都要先说明,程序的执行部分中先输入上、下底与高,接着求面积S,最后输出结果S。

  源程序如下:

 program Tixing; {程序首部}

 var a,b,h,s:real; {程序说明部分}

begin

 write('Input a,b,h:');

 readln(a,b,h); {程序执行部分}

 s:=(a+b)*h/2;

 write('s=',s:10:3);

end.

例7

   某幼儿园里,有5个小朋友编号为1,2,3,4,5,他们按自己的编号顺序围坐在一张圆桌旁。他们身上都有若干个糖果,现在他们做一个分糖果游戏。从1号小朋友开始,将他的糖果均分三份(如果有多余的,则他将多余的糖果吃掉),自己留一份,其余两份分给他的相邻的两个小朋友。接着2号、3号、4号、5号小朋友也这如果做。问一轮后,每个小朋友手上分别有多少糖果。

分析: 

   这道问题与第二课中的例2基本一样,只不过这里有5位小朋友,且他们初始时糖果的数目不确定。这里用a,b,c,d,e分别存放5个小朋友的糖果。初始时它们的值改为由键盘输入。其它都与第二课中的例2类似。

参考程序如下:

program fentang;

var a,b,c,d,e:integer;

begin

 write('Please Enter init numbers ');readln(a,b,c,d,e);

 a:=a div 3;b:=b+a;e:=e+a;{1号均分后,1、2、5号的糖果数变化情况}

 b:=b div 3;c:=c+b;a:=a+b;{2号均分后,1、2、3号的糖果数变化情况}

 c:=c div 3;b:=b+c;d:=d+c;{3号均分后,2、3、4号的糖果数变化情况}

 d:=d div 3;c:=c+d;e:=e+d;{4号均分后,3、4、5号的糖果数变化情况}

 e:=e div 3;d:=d+e;a:=a+e;{5号均分后,4、5、1号的糖果数变化情况}

{输出结果}

 writeln('a=',a);

 writeln('b=',b);

 writeln('c=',c);

 writeln('d=',d);

 writeln('e=',e);

 readln;{暂停}

end.

例8

   编一程序求半径为R的圆的周长与面积?

分析:

   程序要先输入半径R,然后求周长c和面积s,最后输出c和s.

源程序如下:

program circle;

 const PI=3.14159;

 var r,c,s:real;

begin

 write('Enter R=');readln(r);

 c:=2*pi*r;

 s:=pi*sqr(r);

 writeln('c=',c:10:2);

 writeln('s=',s:10:2);

end.

  在程序中,为了输出实型周长C和面积S时,按照小数形式输出,采用了指定双场宽格式。

练习三

1. 编一程序,将摄氏温度换为华氏温度。公式为:

其中f为华氏温度,c是摄氏温度。

2. 编一程序,输入三角形的三边a、b、c(假设这三边可以构成一个三角形),求三角形的面积S?

(提示:可利用海伦公式

 

 

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

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

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

  在前面,我们学习了整型(integer)与实型(real)。其中integer型数据取值范围为-32768到32767之间所有整数。而real型数据取值范围为其绝对值在10-38到1038之间的所有实数。它们都是数值型的(即值都为数)。布尔型(Boolean)是一种数据的类型,这种类型只有两种值,即"真"与"假"。

  1、 布尔常量

  在Pascal语言中"真"用ture表示,"假"用False表示。所以布尔类型只有TRUE与FALSE两个常量。

  2、 布尔变量(BOOLEAN)

  如果我们将某些变量说明成布尔型,那么这些变量就是布尔变量,它们只能用于存放布尔值(ture或false)。

  例如,VAR A,B:BOOLEAN;

  3、 布尔类型是顺序类型

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

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

  a)输出

  VAR A,B:BOOLEAN;

  BEGIN

   A:=TRUE;B:=FALSE;

   WRITELN(A,B);

  END.

  TRUEFALSE

  b)布尔类型变量不能直接用读语句输入

  布尔类型变量不能通过读语句给它们提供值。事实上,我们可以通过间接方式对布尔变量进行值的输入。

  例如,以下程序是错误的:

  var a,b,c:Boolean;

  begin

   readln(a,b,c); {错误语句}

   writeln(a,b,c);

  end.

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

  1、什么是关系表达式

  用小括号、>、<、>=、<=、=、<>将两个算术表达式连接起来的式子就称为关系表达式(比较式)。

  如:3+7>8,x+y<10,2*7<=13等都是关系表达式。

  2、关系表达式的值

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

  关系表达式用于表示一个命题。如:"m为偶数"可表示为:m mod 2=0。"n为正数"可表示为:n>0。

  3.布尔运算及布尔表达式

  为了表示更复杂的命题,Pascal还引入三种逻辑运算符:not、and、or。它们分别相当于数学上的"非"、"且"和"或"的意义。

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

 

a

b

Not a

a and b

a or b

a xor b

false

false

true

false

false

false

false

true

true

false

ture

true

true

false

false

false

true

true

true

true

false

true

true

false

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

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

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

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

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

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

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

(m mod 2=1)and(n mod 2=1)"。

三、简单的IF语句

  1、格式

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

  Ⅱ、IF <布尔表达式>THEN 语句1 ELSE 语句2;

  (注意Ⅱ型IF语句中语句1后无";"号)

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

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

  3、示例

  1)例4.2输入一个整数a,判断是否为偶数。(是输出"yes"否则输出"no")。

  Program ex4_2;

   Var a:integer;

   Begin  

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

    If (a mod 2 =0)then writeln('yes')

    Else writeln('no');

    Readln;

   End.

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

  Program ex4_3;

   Var Num:integer;Price,Total:real;

   Begin

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

    Price=0.8;

    If Num>10 then Price:=Price*0.75;

    Total:=Num*Price;

    Writeln('Total=',Total:0:2);

    Readln;

   End.

  3)编写一与电脑猜"红"或"黑"的游戏。

  分析:用1代表红,0代表黑。先由计算机先出答案,然后再由人猜,猜对输出"YOU WIN"否则输出"YOU LOST"。为了模拟猜"红"或"黑"的随意性,程序中需要用到随机函数random(n)。

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

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

  在pascal语言中,系统提供了许多内部函数,其中包括|x|函数,当然它用abs(x)表示。我们如果要求x2-y的绝对值,可以调用内部函数abs(x*x-y)即可求得。Random(n)也是一个内部函数,调用它能得到0~n-1之间的整数(但它不确定的,或说是随机的)。同时由于函数是一个运算结果,所以函数的调用只能出现在表达式中。

  Program ex4_3;

   Uses crt;

   Var Computer,People:integer;

   Begin

    Randomize;

    Computer:=random(2);

    Write('You guess(0-Red 1-Black):');readln(People);

    If People=Computer then writeln('YOU WIN')

    Else writeln('YOU LOST');

    Readln;

   End.

  作业:.某车站行李托运收费标准是:10公斤或10公斤以下,收费2.5元,超过10公斤的行李,按每超过1公斤增加1.5元进行收费。

试编一程序,输入行李的重量,算出托运费。

 

 

第五课 if嵌套与case语句

 

一、IF语句的嵌套

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

  例1 计算下列函数

   

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

  源程序如下:

  program ex;

  var

    x:real;

    y:integer;

  begin

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

    if x>0 then y:=1{x>0时,y的值为1}

     else {x≤0时}

      if x=0 then y:=0

      else y:=-1;

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

  end.

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

  

  program ex;

  var

    x:real;y:integer;

  begin

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

   if x>=0 then

    if x>0 then y:=1

    else y:=0

   else y=-1;

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

  end.

  但是对于本题,下面的程序是不对的。

  y:=0;

  if x>=0 then

    if x>0 then y:=1

  else y:=-1;

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

  要使上程序段中esle与第一个then配对,应将程序段修改为:

  y:=0;               或者 y:=0;

  if x>=0                 if x>=0

   then if x>0               then

    then y:=1                begin

    else                    if x>0 then Y:=1;

   else y:=-1;                end

                      else Y:=-1;

二、case语句

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

  (一)、情况语句的一般形式:

  case <表达式> of

   <情况标号表1>:语句1;

   <情况标号表2>:语句2;

   :

   <情况标号表n>:语句n

  end;

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

  (二)、case语句的执行过程

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

  (三)、说明

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

  ②情况常量是情况表达式可能具有的值,因而应与情况表达式具有相同的类型;

  ③情况常量出现的次序可以是任意的;

  ④同一情况常量不能在同一个case语句中出现两次或两次以上;

  ⑤每个分语句前可以有一个或若干个用逗号隔开的情况常量;

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

  ⑦每个常量后面只能是一个语句或一个复合语句。

  例2 根据x的值,求函数Y的值:

    

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

  

  源程序如下:

  program ex;

  var x,y:real;

  begin

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

   case trunc(x/100) of

    0:y:=x+1;

    1:y:=x-1;

    else y:=0;

   end;{end of case}

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

  end.

三、选择结构的程序设计

  

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

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

  

  源程序如下:

  program ex;

  var year:integer;

  begin

   write('Input year:');readln(year);

   write(year:6);

   if (year mod 400=0 ) then

    writeln('is a leap year.')

   else

    if (year mod 4=0)and(year mod 100<>0)

    then writeln('is a leap year.')

    else writeln('is not a leap year.');

  end.

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

  分析:程序分为:输入月份,计算该月的天数,输出天数

  

  源程序如下:

  program days;

  var month,days:integer;

  begin

   write('Input month:');readln(month);

  case month of

    1,3,5,7,8,10,12:days:=31;

    4,6,9,11 :days:=30;

    2 :days:=28;

    else days:=0;

   end;

   if days<>0 then writeln('Days=',days);

  end.

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

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

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

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

  源程序如下:

  program pen;

   var a,b,c:integer;{a,b,c分别表示在买笔方案中,6元、5元和4元钱笔的数目}

    x,y:integer;{x,y分别表示剩余班费和买完最多的4元笔后剩的钱}

   begin

    write('x=');readln(x){输入x}

    c:=x div 4;{4元笔最多买的数目}

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

    case y of

     0 : begin a:=0;b:=0; end;

     1 : begin a:=0;b:=1;c:=c-1; end;

     2 : begin a:=1;b:=0; c:=c-1;end;

     3 : begin a:=1;b:=1; c:=c-2;end;

    end;

    writeln('a=',a,'b=',b,'c=',c);

   end.  

练 习

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

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

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

  4.输入两个正整数a,b。b最大不超过三位数,a不大于31。使a在左,b在右,拼接成一个新的数c。例如:a=2,b=16,则c=216;若a=18,b=476,则c=18476。

  提示:求c的公式为:

       c=a×K+b

  其中:

    

    

 

第六课 for循环语句

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

  

  一、for语句的一般格式

  for <控制变量>:=<表达式1> to <表达式2> do <语句>;

  for <控制变量>:=<表达式1> downto <表达式2> do <语句>;

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

  二、For语句执行过程

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

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

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

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

  ⑤返回步骤②;

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

  三、说明

  ①循环控制变量必须是顺序类型。例如,可以是整型、字符型等,但不能为实型。

  ②循环控制变量的值递增或递减的规律是:选用to则为递增;选用downto则递减。

  ③所谓循环控制变量的值"超过"终值,对递增型循环,"超过"指大于,对递减型循环,"超  过"指小于。

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

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

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

  四、应用举例

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

    var i:integer;

    begin

     for i:=1 to 100 do

     if i mod 2=0 then write(i:5);

    end.

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

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

  程序如下:

  var

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

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

  begin

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

  s:=1;

   for i:=2 to n do{从2到n累乘到s中}

    s:=s*i;

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

  end.

练 习

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

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

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

 

 

第七课 WHILE循环与REPEAT

 

一、WHILE循环

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

  while语句的形式为:

  while <布尔表达式> do

<语句>;

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

  while语句的执行过程为:

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

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

  ③返回步骤1;

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

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

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

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

  程序如下:

  var

    s : real;

    n : integer;{n表示项数}

  begin 

   s:=0.0;n:=0;

   while s<=10 do{当s的值还未超过10时}

    begin

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

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

    end;

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

  end.

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

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

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

  ①求m/n的余数r.

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

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

  ④返回重新执行第①步。

  程序如下:

  program ex4_4;

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

  begin

    write('Input m,n:');

    readln(m,n);

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

    while r<>0 do

    begin

     a:=b;b:=r;

     r:=a mod b;

    end;

    writeln('The greatest common divide is:',b:8);

  end.

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

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

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

  Repeat

   <语句1>;

   :

   <语句n>;

  until <布尔表达式>;

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

  说明:

  ①repeat语句的特点是:先执行循环,后判断结束条件,因而至少要执行一次循环体。

  ②repeat-until是一个整体,它是一个(构造型)语句,不要误认为repeat是一个语句, until是另一个语句。

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

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

  var

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

  begin

   write('Input m,n=');

   readln(m,n);

   a:=m;b:=n;

   repeat

    r:=a mod b;

    a:=b;b:=r;

   until r=0;

   writeln('The greatest common divide is',a);

  end.

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

循环在大多数场合也能用whiel和repeat-until循环来代替。一般for循环用于有确定次数循环,而while和repeat-until循环用于未确定循环次数的循环。

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

  三、循环结构程序设计

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

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

  for n:=1 to 10 do

  begin

   ①N!的值àt

   ②累加N!的值t

  end

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

  t=1;

  for j:=1 to n do

   t:=t*j;

  因此,整个程序为:

  program ex4_5;

  var t,s:real;

    i,j,n:integer;

  begin

   S:=0;

   for n:=1 to 10 do

   begin

    t:=1;

    for j:=1 to n do

     t:=t*j;

    S:=S+t;

   end;

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

  end.

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

  程序可改为:

  program ex4_5;

  var t,s:real;

    i,j,n:integer;

  begin

   S:=0;t:=1;

   for n:=1 to 10 do

   begin

    t:=t*n;

    S:=S+t;

   end;

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

  end.

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

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

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

  源程序如下:

  programr ex4_6;

  var i,j,k:integer;

  begin

   for i:=1 to 5 do

   for j:=1 to 8 do

    begin

     k:=90-i-j;

     if 15*i+10*j+5*k=500 then writeln(i:5,j:5,k:5);

    end;

  end.

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

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

  源程序如下:

  var

    i : integer;

    x : integer;

  begin

   for i:=100 to 200 do

    begin

     x:=2;

     while (x<=trunc(sqrt(i)))and(i mod

x<>0)do

      begin

       x:=x+1;

      end;

     if x>trunc(sqrt(i)) then write(i:8);

    end;

  end.

练  习

  1、输入一个正整数n,将n分解成质因数幂的乘积形式。

     例如:36=22*32

  2、输出如下图形。

    

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

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

 

 

第八课一维数组

一、为什么要使用数组

  例1 输入50个学生的某门课程的成绩,打印出低于平均分的同学号数与成绩。

  分析:在解决这个问题时,虽然可以通过读入一个数就累加一个数的办法来求学生的总分,进而求出平均分。但因为只有读入最后一个学生的分数以后才能求得平均分,且要打印出低于平均分的同学,故必须把50个学生的成绩都保留下来, 然后逐个和平均分比较,把高于平均分的成绩打印出来。如果,用简单变量a1,a2,…,a50存放这些数据,可想而知程序要很长且繁。

  要想如数学中使用下标变量ai形式表示这50个数,则可以引入下标变量a[i]。这样问题的程序可写为:

  tot:=0;{tot表示总分}

  for i:=1 to 50 do {循环读入每一个学生的成绩,并累加它到总分}

   begin

    read(a[i]);

    tot:=tot+a[i];

   end;

  ave:=tot/50;{计算平均分}

  for i:=1 to 50 do

   if a[i]

  而要在程序中使用下标变量,则必须先说明这些下标变量的整体―数组,即数组是若干个同名(如上面的下标变量的名字都为a)下标变量的集合。

二、一维数组

  当数组中每个元素只带有一个下标时,我们称这样的数组为一维数组。

  1、一维数组的定义

  (1)类型定义

  要使用数组类型等构造类型以及第6章要学习的自定义类型(枚举类型与子界类型),应在说明部分进行类型说明。 这样定义的数据类型适用整个程序。

  类型定义一般格式为:

  type

   <标识符1>=<类型1>;

   <标识符2>=<类型2>;

   :

   <标识符n>=<类型n>;

  其中type是Pascal保留字,表示开始一个类型定义段。在其后可以定义若干个数据类型定义。<标识符>是为定义的类型取的名字, 称它为类型标识符。

  类型定义后,也就确定了该类型数据取值的范围,以及数据所能执行的运算。

  (2)一维数组类型的定义

  一维数组类型的一般格式:

    array[下标1..下标2] of <基类型>;

  说明:其中array和of是pascal保留字。下标1和下标2 是同一顺序类型,且下标2的序号大于下标1的序号。它给出了数组中每个元素(下标变量) 允许使用的下标类型,也决定了数组中元素的个数。基类型是指数组元素的类型,它可以是任何类型,如整型,实型,字符型等。同一个数组中的元素具有相同类型。因此我们可以说,数组是由固定数量的相同类型的元素组成的。

  再次提请注意:类型和变量是两个不同概念,不能混淆。就数组而言,程序的执行部分使用的不是数组类型(标识符)而是数组变量(标识符)。

  一般在定义数组类型标识符后定义相应的数组变量,如:

  type arraytype=array[1..8]of integer;

  var a1,a2:arraytype;

  其中arraytype为一个类型标识符,表示一个下标值可以是1到 8,数组元素类型为整型的一维数组;而a1,a2则是这种类型的数组变量。

  也可以将其合并起来:

  var a1,a2:array[1..8]of integer;

type

arraytype=array[1..8]of integer;

var a1,a2:arraytype;

相当于

var a1,a2:array[1..8]of integer;

一般我们使用第二种定义方法。

当在说明部分定义了一个数组变量之后,pascal 编译程序为所定义的数组在内存空间开辟一串连续的存储单元。

  例如,设程序中有如下说明:

  var a:array[1..8] of integer;

    则pascal编译程序就在内存中定义了如下一串变量:a[1]、a[2] a[3] a[4] a[5] a[6] a[7] a[8]这个数组变量。

  2、一维数组的引用

  当定义了一个数组,则数组中的各个元素就共用一个数组名( 即该数组变量名),它们之间是通过下标不同以示区别的。 对数组的操作归根到底就是对数组元素的操作。

一维数组元素的引用格式为:

  数组名[下标表达式]

  说明:①下标表达式值的类型, 必须与数组类型定义中下标类型完全一致,并且不允许超越所定义的下标下界和上界。

     ②数组是一个整体,数组名是一个整体的标识,要对数组进行操作,必须对其元素操作。数组元素可以象同类型的普通变量那样作用。如:a[3]:=34;是对数组a中第三个下标变量赋以34的值。read(a[4]);是从键盘读入一个数到数组a第4个元素中去。

例1的完整程序如下所示:

program ex;

var

  a:array[1..10] of integer;{定义a为含10个整型数组元素的一维数组}

  i,tot:integer;

  ave:real;

begin

    tot:=0;{tot表示总分}

  for i:=1 to 10 do {循环读入每一个学生的成绩,并累加它到总分}

   begin

    read(a[i]);

    tot:=tot+a[i];

   end;

  ave:=tot/10;{计算平均分}

  for i:=1 to 10 do

   if a[i]

  end.

  

  对于一维数组的输入与输出, 都只能对其中的元素逐个的输入与输出。在下面的应用示例中将详细介绍。

  三、一维数组应用示例

  例2 输入10个数,要求程序按输入时的逆序把这10个数打印出来。也就是说,请你按输入相反顺序打印这10个数。

  分析:我们可定义一个数组a用以存放输入的10个数, 然后将数组a内容逆序输出。

  源程序如下:

  program ex5_1;

  type arr=array[1..10]of integer;

{说明一数组类型arr}

  var

      a:arr;i:integer;{定义a是上面说明的arr类型,i是整型}

  或上面红色语句也可以用下面红色语句代替

    var

      a:array[1..10] of integer;

      i:integer;

    begin

   writeln('Enter 10 integer:');{提示要输入10个整数}

   for i:=1 to 10 do read(a[i]);{从键盘上输入10个整数,这是数组元素取数的方法}

   readln;{输入换行}

   for i:=10 downto 1 do {逆序输出这50个数,这是输出数组元素的值}

    write(a[i]:10);

  end.

  例3 输入任意十个正整数,统计数字5的个数。

    分析:将十个数字放到数组a中,并设置一个计数变量k,k的初值为0,将每个数字与5作比较,如与5相等,则k加1。最后输出k的值。

    程序如下:

    program ex5_3;

    var

     a:array [1..10] of integer;

     k,I:integer;

    begin

      for i:=1 to 10 do read(a[i]);{从键盘任意输入10个整数}

      k:=0;

      for i:=1 to 10 do

       if a[i]=5 then k:=k+1;{统计5的个数,放到变量k中}

      writeln(‘k’,=k);{输出k的值}

     end.

例4  输入一个不超过30000的正整数,按从低位到高位输出每一位上的数字。

     如:输入2645,输出5 4 6 2

     分析:对2645,先以2645 mod 10取出个位数,放到a[1]中,以2645 div 10 得到剩下的数264,依次类推,再以264 mod 10 得到十位数4,放到a[2]中,以264 div 10得到剩下的数26,再以26 mod 10 得到百位数6,放到a[3]中,以26 div 10得到剩下的数2,以2

mod 10得到千位数2,以2 div 10得到剩下的数为0。程序结束。

     程序如下:

     program ex5_4

     var

      a:array[1..10] of integer;

      n,i,k:integer;{n为输入的任意正整数,k为n的位数}

    begin

      readln(n);

      k:=0;

      while n>0 do{从低位向高位取出n的每一位数,放到数组a中}

       begin

         k:=k+1;

         a[k]:=n mod 10;

         n:=n div 10;

       end;

      for i:=1 to k  do{输出数组a中的每一个元素的值}

        write(a[i],’’);

     end.

例5  输入十个正整数,把这十个数按由小到大的顺序排列。

  将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序是一种较简单的方法。

  分析:要把十个数按从小到大顺序排列,则排完后,第一个数最小,第二个数次小,……。因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它小的,则与之交换,比较结束后,则第一个数已是最小的数(最小的泡往下冒)。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次小的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次大的数。于是十个数的顺序排列结束。

  例如下面对5个进行排序,这个五个数分别为8 2 9 10 5。按选择排序方法,过程如下:

  初始数据 :8 2 9 10 5

  第一次排序:8 2 9 10 5

        9 2 8 10 5

        10 2 8 9 5

        10 2 8 9 5

  第二次排序:10 8 2 9 5

        10 9 2 8 5

        10 9 2 8 5

  第三次排序:10 9 8 2 5

        10 9 8 2 5

  第四次排序:10 9 8 5 2

  对于十个数,则排序要进行9次。源程序如下:

  program ex5_5;

   var a:array[1..10]of integer;

      i,j,t:integer;

    begin

     writeln('Input 10 integers:');

     for i:=1 to 10 do read(a[i]);{读入10个初始数据}

     readln;

     for i:=1 to 9 do{进行9次排序}

      begin

       for j:=i+1 to 10 do{将第i个数与其后所有数比较}

         if a[i]

          begin

           t:=a[i];a[i]:=a[j];a[j]:=t;

          end;

       write(a[i]:5);

      end;

    end.

练习:

  1.输入10个正整数,输出偶数与奇数的个数。

2.输入10个数,输出大于6的个数。

3.输入一个不超过30000的正整数,输出所有位上数字的和。

     例:输入2546,输出17。即2+5+4+6=17

4.输入一串小写字母(以"."为结束标志),统计出每个字母在该字符串中出现的次数(若某字母不出现,则不要输出)。

  例:

  输入:aaaabbbccc.

  输出:a:4

     b:3

     c:3

  5.输入一个不大于32767的正整数N,将它转换成一个二进制数。

  例如:

  输入:100

  输出: 1100100

  6.输入一个由10个整数组成的序列,其中序列中任意连续三个整数都互不相同,求该序列中所有递增或递减子序列的个数。

  例如:

  输入:1 10 8 5 9 3 2 6 7 4

  输出:6

  对应的递增或递减子序列为:

  1 10 

  10 8 5 

  5 9

  9 3 2

  2 6 7

  7 4

 

 

第九课 多维数组

一、多维数组的定义

  当一维数组元素的类型也是一维数组时,便构成了二维数组。二维数组定义的一般格式:

    array[下标类型1] of array[下标类型2] of 元素类型;

  但我们一般这样定义二维数组:

    array[下标类型1,下标类型2] of 元素类型;

  说明:其中两个下标类型与一维数组定义一样,可以看成"下界1..上界1"和"下界2..上界2",给出二维数组中每个元素( 双下标变量)可以使用下标值的范围。of后面的元素类型就是基类型。

  一般地,n维数组的格式为:

    array[下标类型1,下标类型2,…,下标类型n] of 元素类型;

  其中,下标类型的个数即数组的维数,且说明了每个下标的类型及取值范围。

二、多维数组元素的引用

  多维数组的数组元素引用与一维数组元素引用类似,区别在于多维数组元素的引用必须给出多个下标。

  引用的格式为:

   <数组名>[下标1,下标2,…,下标n]

  说明:显然,每个下标表达式的类型应与对应的下标类型一致,且取值不超出下标类型所指定的范围。 

  例如,设有说明:

  type matrix=array[1..5,1..4]of integer;

  var a:matrix;

  则表示a是二维数组,共有5*4=20个元素,它们是:

  a[1,1]a[1,2]a[1,3]a[1,4]

  a[2,1]a[2,2]a[2,3]a[2,4]

  a[3,1]a[3,2]a[3,3]a[3,4]

  a[4,1]a[4,2]a[4,3]a[4,4]

  a[5,1]a[5,2]a[5,3]a[5,4]

  因此可以看成一个矩阵,a[4,2]即表示第4行、第2列的元素。由于计算机的存储器是一维的,要把二维数组的元素存放到存储器中,pascal是按行(第一个下标)的次序存放,即按a[1,1]a[1,2]a[1,3]a[1,4]a[2,1]…,a[5,4]的次序存放于存储器中某一组连续的存储单元之内。

  对于整个二维数组的元素引用时,大多采用二重循环来实现。如:给如上说明的二维数组a进行赋值:a[i,j]=i*j。

  for i:=1 to 5 do

   for j:=1 to 4 do

     a[i,j]:=i*j;

  对二维数组的输入与输出也同样可用二重循环来实现:

  for i:=1 to 5 do

  begin

   for j:=1 to 4 do

    read(a[i,j]);

   readln;

  end;

  for i:=1 to 5 do

   begin

    for j:=1 to 4 do

     write(a[i,j]:5);

    writeln;

   end;

三、多维数组的应用示例

  例1设有一程序:

  program ex5_3;

  const n=3;

  type matrix=array[1..n,1..n]of integer;

  var a:matrix;

   i,j:1..n;

  begin

   for i:=1 to n do

   begin

    for j:=1 to n do

     read(a[i,j]);

    readln;

   end;

  for i:=1 to n do

  begin

   for j:=1 to n do

    write(a[j,i]:5);

   writeln;

  end;

  end.

  且运行程序时的输入为:

  2□1□3←┘

  3□3□1←┘

  1□2□1←┘

  则程序的输出应是:

  2□3□1

  1□3□2

  3□1□1

  例2 输入4名学生数学、物理、英语、化学、pascal五门课的考试成绩,求出每名学生的平均分,打印出表格。

  分析:用二维数组a存放所给数据,第一下标表示学生的学号, 第二个下标表示该学生某科成绩,如a[i,1]、a[i,2]、a[i,3]、a[i,4]、a[i,5]分别存放第i号学生数学、物理、英语、化学、pascal 五门课的考试成绩,由于要求每个学生的总分和平均分, 所以第二下标可多开两列,分别存放每个学生5门成绩和总分、平均分。

  源程序如下:

  program ex5_4;

  var a:array[1..4,1..7]of real;

   i,j:integer;

  begin

   fillchar(a,sizeof(a),0);

   {函数fillchar用以将a中所有元素置为0}

   writeln('Enter 4 students score');

   for i:=1 to 4 do

   begin

    for j:=1 to 5 do {读入每个人5科成绩}

    begin

     read(a[i,j]);

     {读每科成绩时同时统计总分}

     a[i,6]:=a[i,6]+a[i,j];

    end;

    readln;

    a[i,7]:=a[i,6]/5;{求平均分}

   end;

   {输出成绩表}

   writeln( 'No. Mat. Phy. Eng. Che. Pas. Tot. Ave.');

   for i:=1 to 4 do

   begin

    write(i:2,' ');

    for j:=1 to 7 do

     write(a[i,j]:9:2);

    writeln;

   end;

  end.

四、数组类型的应用

  例3 输入一串字符,字符个数不超过100,且以"."结束。

判断它们是否构成回文。

  分析:所谓回文指从左到右和从右到左读一串字符的值是一样的,如12321,ABCBA,AA等。先读入要判断的一串字符(放入数组letter中),并记住这串字符的长度,然后首尾字符比较,并不断向中间靠拢,就可以判断出是否为回文。

  源程序如下:

  program ex5_5;

  var  

    letter  : array[1..100]of char;

    i,j   : 0..100;

    ch   : char;

  begin

    {读入一个字符串以'.'号结束}

   write('Input a string:');

   i:=0;read(ch);

   while ch<>'.' do

   begin

    i:=i+1;letter[i]:=ch;

    read(ch)

   end;

   {判断它是否是回文}

   j:=1;

   while (j

   begin

    i:=i-1;j:=j+1;

   end;

   if j>=i then

writeln('Yes.')

   else writeln('No.');

  end.

  例4 奇数阶魔阵

  魔阵是用自然数1,2,3…,n2填n阶方阵的各个元素位置,使方阵的每行的元素之和、每列元素之和及主对角线元素之和均相等。奇数阶魔阵的一个算法是将自然数数列从方阵的中间一行最后一个位置排起,每次总是向右下角排(即Aij的下一个是Ai+1,j+1)。但若遇以下四种情形,则应修正排数法。

  (1) 列排完(即j=n+1时),则转排第一列;

  (2) 行排完(即i=n+1时),则转排第一行;

  (3) 对An,n的下一个总是An,n-1;

  (4) 若Aij已排进一个自然数,则排Ai-1,j-2。

  例如3阶方阵,则按上述算法可排成:

          4 3 8

          9 5 1

          2 7 6

  有了以上的算法,解题主要思路可用伪代码描述如下:

  1 in div 2+1,yn /*排数的初始位置*/

  2 a[i,j]1;

  3 for k:=2 to nn do

  4 计算下一个排数位置(i,j);

  5 if a[i,j]<>0 then

  6 ii-1;

  7 jj-2;

  8 a[i,j]k;

  9 endfor

  对于计算下一个排数位置,按上述的四种情形进行,但我们应先处理第三处情况。算法描述如下:

  1 if (i=n)and(j=n) then

  2 jj-1; /*下一个位置为(n,n-1)*/;

  3 else

  4 ii mod n +1;

  5 jj mod n +1;

  6 endif;

  源程序如下:

  program ex5_7;

  var

   a : array[1..99,1..99]of integer;

   i,j,k,n : integer;

  begin

   fillchar(a,sizeof(a),0);

   write('n=');readln(n);

   i:=n div 2+1;j:=n;

   a[i,j]:=1;

   for k:=2 to n*n do

    begin

     if (i=n)and(j=n) then

      j:=j-1

     else

      begin

       i:=i mod n +1;

       j:=j mod n +1;

      end;

     if a[i,j]<>0 then

      begin

       i:=i-1;

       j:=j-2;

      end;

     a[i,j]:=k;

    end;

   for i:=1 to n do

    begin

     for j:=1 to n do

      write(a[i,j]:5);

     writeln;

    end;

  end.

练习:

  1、 输入N个同学的语、数、英三科成绩,计算他们的总分与平均分,并统计出每个同学的名次,最后以表格的形式输出。

  2、 输出杨辉三角的前N行(N<10)。

      1

      1 1

      1 2 1

      1 3 3 1

      1 4 6 4 1

 

 

 

第十课 字符与字符串处理

一、字符、字符串类型的使用

  (一)字符类型

  字符类型为由一个字符组成的字符常量或字符变量 。

  字符常量定义:

  const                                      

   字符常量='字符'

  字符变量定义:Ⅱ

  Var

   字符变量:char;

  字符类型是一个有序类型, 字符的大小顺序按其ASCⅡ代码的大小而定。函数succ、pred、ord适用于字符类型。

  例如:后继函数:succ('a')='b'

     前继函数:pred('B')='A'

     序号函数:ord('A')=65

  例1 按字母表顺序和逆序每隔一个字母打印。即打印出:

    a c e g I k m o q s u w y

    z x r v t p n l j h f d b

  程序如下:

  program ex8_1;

   var letter:char;

   begin

    for letter:='a' to 'z' do

    if (ord(letter)-ord('a'))mod 2=0 then

write(letter:3);

    writeln;

    for letter:='z' downto 'a' do

    if (ord(letter)-ord('z'))mod 2 =0 then

write(letter:3);

   writeln;

  end.

  分析:程序中,我们利用了字符类型是顺序类型这一特性,直接将字符类型变量作为循环变量,使程序处理起来比较直观。

  (二)字符串类型

  字符串是由字符组成的有穷序列。

  字符串类型定义:

  type <字符串类型标识符>=string[n];

  var

   字符串变量: 字符串类型标识符;

  其中:n是定义的字符串长度,必须是0~255之间的自然整数,第0号单元中存放串的实际长度,程序运行时由系统自动提供,第1~n号单元中存放串的字符。若将string[n]写成string,则默认n值为255。

  例如:type

      man=string[8];

       line=string;

      var

       name:man;

       screenline:line;

  另一种字符类型的定义方式为把类型说明的变量定义合并在一起。

  例如:VAR

       name:STRING[8];

       screenline:STRING;

  Turbo Pascal中,一个字符串中的字符可以通过其对应的下标灵活使用。

  例如:var

      name:string;

     begin

      readln(nsme);

      for i:=1 to ord(name[0])do

       writeln(name[i]);

     end.

  语句writeln(name[i])输出name串中第i个字符。

  例2 求输入英文句子单词的平均长度.

  程序如下:

  program ex8_2;

   var

    ch:string;

    s,count,j:integer;

   begin

    write('The sentence is :');

    readln(ch);

    s:=0;

    count:=0;

    j:=0;

    repeat

     inc(j);

     if not (ch[j] in [':',',',';','''','!','?','.','

']) then inc(s);

     if ch[j] in[' ','.','!','?'] then inc(count);

    until (j=ord(ch[0])) or

(ch[j] in ['.','!','?']);

    if ch[j]<>'.' then writeln('It is not a

sentence.')

    else writeln('Average length is ',s/count:10:4);

   end.

  分析:程序中,变量s用于存句子中英文字母的总数,变量count用于存放句子中单词的个数,ch[j]表示ch串中的第j个位置上的字符,ord(ch[0])为ch串的串长度。程序充分利用Turbo Pascal允许直接通过字符串下标得到串中的字符这一特点,使程序比较简捷。

二、字符串的操作

  (一)字符串的运算和比较

  由字符串的常量、变量和运算符组成的表达式称为字符串表达式。

  字符串运算符包括:

  1.+:连接运算符

  例如:'Turbo '+'PASCAL'的结果是'Turbo

PASCAL'。

  若连接的结果字符串长度超过255,则被截成255个字符。若连接后的字符串存放在定义的字符串变量中,当其长度超过定义的字符串长度时,超过部份字符串被截断。

  例如:var

      str1,str2,str3:string[8];

     begin

      str1:='Turbo ';

      str2:='PASCAL';

      str3:=str1+str2;

     end.

  则str3的值为:'Turbo PA'。

  2.=、〈〉、〈、〈=、〉、〉=:关系运算符

  两个字符串的比较规则为,从左到右按照ASCⅡ码值逐个比较,遇到ASCⅡ码不等时,规定ASCⅡ码值大的字符所在的字符串为大。

  例如:'AB'〈'AC' 结果为真;

     '12'〈'2' 结果为真;

     'PASCAL '='PASCAL' 结果为假;

  例3 对给定的10个国家名,按其字母的顺序输出。

  程序如下:

  program ex8_3;

   var i,j,k:integer;

     t:string[20];

     cname:array[1..10] of string[20];

   begin

    for i:=1 to 10 do readln(cname[i]);

    for i:=1 to 9 do

     begin

      k:=i;

      for j:=i+1 to 10 do

       if cname[k]>cname[j] then k:=j;

      t:=cname[i];cname[i]:=cname[k];cname[k]:=t;

     end;

    for i:=1 to 10 do writeln(cname[i]);

   end.

  分析:程序中,当执行到if cname[k]>cname[j]时,自动将cname[k]串与cname[j]串中的每一个字符逐个比较,直至遇到不等而决定其大小。这种比较方式是计算机中字符串比较的一般方式。

三、字符串的函数和过程

Turbo Pascal提供了八个标准函数和标准过程,见下表,利用这些标准函数与标准过程,一些涉及到字符串的问题可以灵活解决。

 

 

函数和过程名

copy(s,m,n)

取s中第m个字符开始的n个字符

若m大于s的长度,则返回空串;否则,若m+n大于s的长度,则截断

length(s)

求s的动态的长度

返回值为整数

pos(sub,s)

在s中找子串sub

返回值为sub在s中的位置,为byte型

insert(sour,s,m)

在s的第m个字符位置处插入子串sour

若返回串超过255,则截断

delete(s,m,n)

删除s中第m个字符开始的n个字符串

若m大于s的长度,则不删除;否则,若m+n大于s的长度,则删除到结尾

Str(x[:w[:d]],s)

将整数或实数x转换成字符串s

w 和 d是整型表达式,意义同带字宽的write语句

val(s,x,code)

将字符串S 转换成整数或实数x

若S中有非法字符,则code存放非法字符在S中的下标;否则,code为零。code为整型

upcase(ch)

将字母ch转换成大写字母

若ch不为小写字母,则不转换

 

  例4 校对输入日期(以标准英语日期,月/日/年)的正确性,若输入正确则以年.月.日的方式输出。

  程序如下:

  program ex8_4;

   const

    max:array[1..12] of byte

      =(31,29,31,30,31,30,31,31,30,31,30,31);

   var

    st:string;

    p,w,y,m,d:integer;

   procedure err;

    begin

     write('Input Error!');

     readln;

     halt;

    end;

   procedure init(var x:integer);

    begin

     p:=pos('/',st);

     if (p=0) or (p=1) or (p>3) then err;

     val(copy(st,1,p-1),x,w);

     if w<>0 then err;

     delete(st,1,p);

    end;

   begin

    write('The Date is :');

    readln(st);

    init(m);

    init(d);

    val(st,y,w);

    if not (length(st)<>4) or (w<>0) or

(m>12) or (d>max[m]) then err;

    if (m=2) and (d=29)

     then if y mod 100=0

        then begin

            if y mod 400<>0 then err;

           end

     else if y mod 4<>0 then err;

    write('Date : ',y,'.',m,'.',d);

    readln;

   end.

  分析:此题的题意很简单,但在程序处理时还需考虑以下几方面的问题。

  1.判定输入的月和日应是1位或2位的数字,程序中用了一个过程inst,利用串函数pos,求得分隔符/所在的位置而判定输入的月和日是否为1位或2位,利用标准过程val判定输入的月和日是否为数字;

  2.判定月和日是否规定的日期范围及输入的年是否正确;

  3.若输入的月是2月份,则还需考虑闰年的情况。

  例5 对输入的一句子实现查找且置换的功能。

  程序如下:

  program ex8_5;

  var

   s1,s,o:string;

   i:integer;

  begin

   write('The text:');

   readln(s1);

   write('Find:');readln(s);

   write('Replace:');readln(o);

   i:=pos(s,s1);

   while i<>0 do begin

    delete(s1,i,length(s));

    insert(o,s1,i);

    i:=pos(s,s1);

   end;

   writeln(s1);

   readln;

  end.

分析:程序中,输入要查找的字符串及要置换的字符串,充分用上了字符串处理的标准过程delete、insert及标准函数pos。

 

 

第十一课 枚举、子界、集合及记录类型

在前面几章中我们用到了整型、实型、布尔型、字符型的数据。以上数据类型是由pascal规定的标准数据类型,只要写integer,real,boolean,

char, pascal 编译系统就能识别并按这些类型来处理。pascal还允许用户定义一些类型,这是其它一些语言所没有的,这就使得pascal使用灵活、功能丰富。

一、枚举类型

  随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。例如,性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。

  在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。

  枚举类型是一种很有实用价值的数据类型,它是pascal一项重要创新。

  (一)枚举类型的定义

  枚举类型是一种自定义类型,要使用枚举类型当然也要先说明枚举类型。

  枚举类型的一般格式:

   (标识符1,标识符2,…,标识符n)

  说明:①括号中的每一个标识符都称为枚举元素或枚举常量。

     ②定义枚举类型时列出的所有枚举元素构成了这种枚举类型的值域(取值范围),也就是说,该类型的变量所有可能的取值都列出了。

  例如,下列类型定义是合法的:

  type days=(sun,mon,tue,wed,thu,fri,sat);

  colors=(red,yellow,blue,white,black,green);

  而下列类型定义是错误的(因为枚举元素非标识符):

  type colortype=('red','yellow','blue','white');

  numbers=(1,3,5,7,9);

  ty=(for,do,while);

  (二)枚举类型变量

  定义了枚举类型,就可以把某些变量说明成该类型。如:

  var holiday,workday:day;

   incolor:colors;

  也可以把变量的说明与类型的定义合并在一起,如:

  var holiday,workday:(sun,mon,tue,wed,thu,fri,sat);

   incolor:(red,yellow,blue,white,black,green);

  (三)枚举类型的性质

  ⒈枚举类型属于顺序类型

  根据定义类型时各枚举元素的排列顺序确定它们的序号,第一个枚举元素的序号为0。例如:设有定义:

  type days=(sun,mon,tue,wed,thu,fri,sat);

  则:

  ord(sun)=0,ord(mon)=1,ord(sat)=6;succ(sun)=mon,succ(mon)=tue,

  succ(fri)=sat;pred(mon)=sun,pred(tue)=mon,pred(sat)=fri。

  应注意的是:枚举类型中的第一个元素无前趋,最后一个元素无后继。

  ⒉对枚举类型只能进行赋值运算和关系运算

  一旦定义了枚举类型及这种类型的变量,则在语句部分只能对枚举类型变量赋值,或进行关系运算,不能进行算术运算和逻辑运算。

  在枚举元素比较时,实际上是对其序号的比较。当然,赋值或比较时,应注意类型一致。

  例如,设程序有如下说明:

  type days=(sun,mon,tue,wed,thu,fri,sat);

    colors=(red,yellow,blue,white,black,green);

  var color:colors;

    weekday:days;

  则下列比较或语句是合法的:

  weekday:=mon;

  if weekday=sun then write('rest');

  weekday<>sun

  而下面比较或语句是不合法的:

  mon:=weekday;

  mon:=1;

  if weekday=sun or sat then write('rest');

  sun>red

  weekday<>color

  ⒊枚举变量的值只能用赋值语句来获得

  也就是说,不能用read(或readln)读一个枚举型的值。同样,也不能用write(或writeln)输出一个枚举型的值。如write(red)是非法的,会发生编译错误。千万不要误认为,该语句的结果是输出"red"三个字符。

  但对枚举数据的输入与输出可通过间接方式进行。输入时,一般可输入一个代码,通过程序进行转换,输出时,也只是打印出与枚举元素相对应的字符串。这在后面的例题中将有使用示例。

  ⒋同一个枚举元素不能出现在两个或两个以上的枚举类型定义中。

  如:

  type color1=(red,yellow,white);

     color2=(blue,red,black);

  是不允许的,因为red属于两个枚举类型。

  (四)、枚举类型应用举例

  例1 一周七天用sun,mon,tue,wed,thu,fri,sat表示, 要求利用枚举类型编程:当输入星期几的数字,能输出它的后一天是星期几(也用英文表示)。

  源程序如下:

  program ex6_1;

  type week=(sun,mon,tue,wed,thu,fri,sat);

  var

    i : integer;

    day,sucday : week;

  begin

   write('What date is it');readln(i);

   case i of {根据输入i转换成枚举型}

    1:day:=mon;

    2:day:=tue;

    3:day:=wed;

    4:day:=thu;

    5:day:=fri;

    6:day:=sat;

    7:day:=sun;

   end;

   {计算明天sucday}

   if (day=sat) then sucday:=sun

   else sucday:=succ(day);

   {输出明天是星期几}

   write('The next day is ');

   case sucday of

    sun:writeln('sunday');

    mon:writeln('monday');

    tue:writeln('tuesday');

    wed:writeln('wednesay');

    thu:writeln('thursday');

    fri:writeln('friday');

    sat:writeln('saturday');

   end;

   end.

  评注:程序中变量day、sucday分别表示今天、明天。

二、子界类型

  如果我们定义一个变量i为integer类型,那么i的值在微型机系统的pascal中,使用2字节的定义表示法,取值范围为-32768~32767。而事实上,每个程序中所用的变量的值都有一个确定的范围。

  例如,人的年龄一般不超过150,一个班级的学生不超过100人,一年中的月数不超过12,一月中的天数不超过31,等等。

  如果我们能在程序中对所用的变量的值域作具体规定的话,就便于检查出那些不合法的数据,这就能更好地保证程序运行的正确性。而且在一定程度上还会节省内存空间。

  子界类型就很好解决如上问题。此外,在数组的定义中,常用到子界类型,以规定数组下标的范围,上一章有关数组知识中我们已用到。

  (一)子界类型定义

  子界类型的一般格式:

    <常量1>..<常量2>

  说明: ①其中常量1称为子界的下界,常量2称为子界的上界。

     ②下界和上界必须是同一顺序类型(该类型称为子界类型的基类型),且上界的序号必须大于下界的序号。例如,下列说明:

  type age=0.5..150;

   letter=0..'z';

   let1='z'..'a';

  都是错误的。

  ③可以直接在变量说明中定义子界类型。如:

  type letter='a'..'d';

     var ch1,ch2:letter;

  可以合并成:

  var ch1,ch2:'a'..'d';

  当然,将类型定义和变量定义分开,则更为清晰。

  (二)子界类型数据的运算规则

  ⒈凡可使用基类型的运算规则同样适用该类型的子界类型。

  例如,可以使用整型变量的地方,也可以使用以整型为基类型的子界类型数据。

  ⒉对基类型的运算规则同样适用于该类型的子界类型。

  例如,div,mod要求参加运算的数据为整, 因而也可以为整型的任何子界类型数据。

  ⒊基类型相同的不同子界类型数据可以进行混合运算。

  例如:设有如下说明:

  type a=1..100;

     b=1.1000;

     c=1..500;

  var  

     x:a;

     y:b;

     t:c;

     z:integer;

  则下列语句也是合法的:

  Z:=Sqr(x)+y+t;

  下列语句:

   t:=x+y+z;

  当X+Y+Z的值在1~500范围内时是合法的,否则会出错。

  (三)子界类型应用举例

  例2 利用子界类型作为情况语句标号,编一个对数字,

大小写字母和特殊字符进行判别的程序。

  源程序如下:

  program cas;

  var c:char;

  begin

   readln(c);

  case c of

   '0'..'9':writeln('digits');

   'A'..'Z':writeln('UPPER-CASELETTERS');

   'a'..'z':writeln('lower-caseletters');

   esle writeln('special charactors');

  end;

 end.

  例3 使用子界型情况语句,当输入月、日、年(10 30 1986),输出30 Oct 1986。

  源程序如下:

  program ex6_3;

   var month:1..12;

     date:1..31;

     year:1900..1999;

   begin

    write('Enter date(mm-dd-yy):');

    readln(month,date,year);

    write(date);

    case month of

     1:write('Jan':5);

     2:write('Feb':5);

     3:write('Mar':5);

     4:write('Apr':5);

     5:write('May':5);

     6:write('Jun':5);

     7:write('Jul':5);

     8:write('Aug':5);

     9:write('Sep':5);

     10:write('Oct':5);

     11:write('Nov':5);

     12:write('Dec':5);

    end;

    writeln(year:7);

   end.

  枚举类型和子界类型均是顺序类型,在前面一章数组的定义时,实际上我们已经用到了子界类型,数组中的下标类型确切地讲可以是和枚举类型或子界类型,大多数情况下用子界类型。

  如有如下说明:

  type color=(red,yellow,blue,white,black);

  var

    a:array[color]of integer;

    b:array[1..100]of color;

  都是允许的。

三、集合类型

  集合是由具有某些共同特征的元素构成的一个整体。在pascal中,一个集合是由具有同一有序类型的一组数据元素所组成,这一有序类型称为该集合的基类型。

  (一)集合类型的定义和变量的说明

  集合类型的一般形式为:

    set of <基类型>;

  说明: ①基类型可以是任意顺序类型, 而不能是实型或其它构造类型。同时,基类型的数据的序号不得超过255。例如下列说明是合法的:

  type letters=set of 'A'..'Z';

  numbers=set of 0..9;

  s1=set of char;

  ss=(sun,mon,tue,wed,thu,fri,sat);

  s2=set of ss;

  ②与其它自定义类型一样, 可以将类型说明与变量说明合并在一起.如:

  type numbers=set of 0..9;

  var s:numbers;

  与 var s:set of 0..9;等价。

  (二)集合的值

  集合的值是用"["和"]"括起来,中间为用逗号隔开的若干个集合的元素。如:

  [] 空集

  [1,2,3]

  ['a','e','i','o','u']

  都是集合。

  说明:

  ①集合的值放在一对方括号中,各元素之间用逗号隔开。

  ②在集合中可以没有任何元素,这样的集合称为空集。

  ③在集合中,如果元素的值是连续的,则可用子界型的表示方法表示。例如:  

    [1,2,3,4,5,7,8,9,10,15]

  可以表示成:

     [1..5,7..10,15]

  ④集合的值与方括号内元素出现的次序无关。例如,[1,5,8 ]和[5,1,8]的值相等。

  ⑤在集合中同一元素的重复出现对集合的值没有影响。例如,[1,8,5,1,8]与[1,5,8]的值相等。

  ⑥每个元素可用基类型所允许的表达式来表示。如[1,1+2,4]、[ch]、[succ(ch)]。

  (三)集合的运算

  ⒈赋值运算

  只能通过赋值语句给集合变量赋值,不能通过读语句赋值,也不能通过write(或writeln)语句直接输出集合变量的值。

  ⒉集合的并、交、差运算

  可以对集合进行并、交、差三种运算,每种运算都只能有一个运算符、两个运算对象,所得结果仍为集合。三种运算符分别用"+"、"*"、"-"表示。注意它们与算术运算的区别。

  ⒊集合的关系运算

  集合可以进行相等或不相等、包含或被包含的关系运算,还能测试一个元素是否在集合中。所用的运算符分别是:=、<>、>=、<=、in

  它们都是二目运算,且前4个运算符的运算对象都是相容的集合类型,最后一个运算符的右边为集合,左边为与集合基类型相同的表达式。

  例4 设有如下说明:

  type weekday=(sun,mon,tue,wed,thu,fri,sat);

     week=set of weekday;

     subnum=set of 1..50;

  写出下列表达式的值:

  ⑴[sun,sat]+[sun,tue,fri]

  ⑵[sun,fri]*[mon,tue]

  ⑶[wun,sat]*[sun..sat]

  ⑷[sun]-[mon,tue]

  ⑸[mon]-[mon,tue]

  ⑹[sun..sat]-[mon,sun,sat]

  ⑺[1,2,3,5]=[1,5,3,2]

  ⑻[1,2,3,4]<>[1..4]

  ⑼[1,2,3,5]>=[1..3]

  ⑽[1..5]<=[1..4]

  ⑾[1,2,3]<=[1..3]

  ⑿ 2 in[1..10]

  答: 表达式的值分别是:

  ⑴ [sun,sat,tue,fri]

  ⑵ [ ]

  ⑶ [sun,sat]

  ⑷ [ ]

  ⑸ [ ]

  ⑹ [tue..fri]

  ⑺ TRUE

  ⑻ FALSE

  ⑼ TRUE

  ⑽ FALSE

  ⑾ TRUE

  ⑿ TRUE

  例5 输入一系列字符,对其中的数字字符、字母字符和其它字符分别计数。输入'?'后结束。

  源程序如下:

  program ex10_2;

  var id,il,io:integer;

    ch:char;

    letter:set of char;

    digit:set of '0'..'9';

  begin

    letter=['a'..'z','A'..'Z'];

    digit:=['0'..'9'];

    id:=0;il:=0;io:=0;

    repeat

     read(ch);

     if ch in letter

     then il:=il+1

     else if ch in digit

      then id:=id+1

      else io:=io+1;

   until ch='?';

   writeln('letter:',il,'digit:',id,'Other:',io);

  end.

四、记录类型

  在程序中对于组织和处理大批量的数据来说,数组是一种十分方便而又灵活的工具,但是数组在使用中有一个基本限制,这就是:一个数组中的所有元素都必须具有相同的类型。但在实际问题中可能会遇到另一类数据,它是由性质各不相同的成份组成的,即它的各个成

份可能具有不同的类型。例如,有关一个学生的数据包含下列项目:

    学号  字符串类型

    姓名  字符串类型

    年龄  整型

    性别  字符型

    成绩  实型数组

  Pascal给我们提供了一种叫做记录的结构类型。在一个记录中,可以包含不同类型的并且互相相关的一些数据。

  (一)记录类型的定义

  在pascal中,记录由一组称为"域"的分量组成,每个域可以具有不同的类型。

  记录类型定义的一般形式:

  record

   <域名1>:<类型1>;

   <域名2>:<类型2>;

   : :

   : :

   <域名n>:<类型n>;

  end;

  说明:①域名也称域变量标识符, 应符合标识符的语法规则。在同一个记录中类型中,各个域不能取相同的名,但在不同的记录类型中,两个类型中的域名要以相同。

  ②记录类型的定义和记录变量可以合并为一个定义,如:

  type date=record

      year:1900..1999;

      month:1..12;

      day:1..31

     end;

  var x:date;

  可以合并成:

  var x: record

      year:1900..1999;

      month:1..12;

      day:1..31

     end;

  ③对记录的操作,除了可以进行整体赋值, 只能对记录的分量──域变量进行。

  ④域变量的表示方法如下:

  记录变量名.域名

  如前面定义的记录X,其3个分量分别为:x.year ,x.month ,x.day。

  ⑤域变量的使用和一般的变量一样, 即域变量是属于什么数据类型,便可以进行那种数据类型所允许的操作。

  (二)记录的嵌套

  当一个记录类型的某一个域类型也是记录类型的时候,我们说发生了记录的嵌套,看下面的例子:

  例6 某人事登记表可用一个记录表示, 其中各项数据具有不同的类型,分别命名一个标识符。而其中的"出生年月日"又包括三项数据,还可以用一个嵌套在内层的记录表示。

  具体定义如下:

  type sexs=(male,female);

     date=record

      year:1900..1999;

      month:1..12;

      day:1..31;

     end;

  personal=record

      name:string[15];

      sex:sexs;

      birthdate:date;

      home:string[40];

     end;

  例7 设计一个函数比较两个dates日期类型记录变量的迟早。

  设函数名、形参及函数类型定义为:

  AearlyB(A,B:dates):boolean;

  函数的形参为两个dates类型的值参数。当函数值为true

时表示日期A早于日期B,否则日期A迟于日期B或等于日期B。显然不能对A、B两个记录变量直接进行比较,而要依具体的意义逐域处理。

  源程序如下:

  program ex6_7;

  type dates=record

      year:1900.1999;

      month:1..12;

      day:1..31

     end;

  var x,y:dates;

  function AearlyB(A,B:dates):boolean;

  var earln:boolean;

  begin

   early:=false;

   if (A.year

   if (A.year=B.year)and(A.month

   then early:=true;

   if

(A.year=B.year)and(A.month=B.month)and(A.day

   then early:=true;

   AearlyB:=early;

   end;{of AearlyB}

  begin

   write('Input DATE

X(mm-dd-yy):')readln(X.month,X.day,X.year);

   write('Input DATE Y(mm-dd-yy):')readln(Y.month,Y.day,Y.year);

   if AearlyB(X,Y) then writeln(Date X early!') else

writeln('Date X not    early!');

  end.

  (三)开域语句

  在程序中对记录进行处理时,经常要引用同一记录中不同的域,每次都按6.4.1节所述的格式引用,非常乏味。为此Pascal提供了一个with语句,可以提供引用域的简单形式。

  开域语句一般形式:

  with <记录变量名表> do

  <语句>

  功能: 在do后的语句中使用with后的记录的域时, 只要直接写出域名即可,即可以省略图10.2.2中的记录变量名和"."。

  说明: ①一般在with后只使用一个记录变量名。如:

  write('Input year:');

  readln(x.year);

  write('Input month:');

  readln(x.month);

  write('Input day:');

  readln(x.day);

  可以改写成:

  with x do

   begin

    write('Input year:');readln(year);

    write('Input month:');readln(month);

    write('Input day:');readln(day);

   end;

  ②设x,y是相同类型的记录变量,下列语句是非法的:

    with x,y do...;

  ③with后接若干个记录名时,应是嵌套的关系。如有记录说明:

    var x:record

      i:integer;

      y:record

        j:0..5;

        k:real;

       end;

      m:real

     end;

  可以使用:

  with x do

  begin

    read(i);

    with y do

      read(j,k);

    readln(m);

  end;

  或简写为:

  with x,y do

  readln(i,j,k,m);

  例8 读入10个日期,再对每个日期输出第二天的日期。输入日期的格式是月、日、年,如9□30□1993,输出的格式为10/1/1993。

  分析: 可用一个记录变量today表示日期。

知道一个日期后要更新为第二天的日期,应判断输入的日期是否为当月的最后一天,或当年的最后一天。

  源程序如下:

  program ex6_8;

   type date=record

        month:1..12;

        day:1..31;

        year:1900..1999;

       end;

   var today:array[1..10]of date;

      i:integer;

      maxdays:28..31;

   begin

    for i:=1 to 10 do {输入10个日期}

     with today[i] do

      readln(month,day,year);

    for i:=1 to 10 do

     with today[i] do{求第i个日期中月份最后一天maxdays}

      begin  

       case month of

        1,3,5,7,8,10,12:maxdays:=31;

        4,6,9,11 :maxdays:=30;

        2     :if(year mod

400=0) or( year mod 4=0)

              and(year mod 100<>0)

             then maxdays:=29

             else maxdays:=28;

       end;

       if day=maxdays

        then begin

          day:=1;  

          if month=12

           then begin

                month:=1;year:=year+1;

              end

            else month:=month+1;

          end

         else day:=day+1;

       writeln(month,'/',day,'/',year);

     end;

  end.

五、应用实例

  例9 编制用筛法求1-n(n≤200)以内素数的程序。

  分析: 由希腊著名数学家埃拉托色尼提出的所谓"筛法",步骤如下:

     ①将所有候选数放入筛中;

     ②找筛中最小数(必为素数)next,放入集合primes中;

     ③将next的所有倍数从筛中筛去;

     ④重复②~④直到筛空。

  编程时,用集合变量sieve表示筛子,用集合primes存放所有素数。

  源程序如下:

  program ex10_3;

  const n=200;

  var sieve,primes:set of 2..n;

    next,j:integer;

  begin

    sieve:=[2..n];{将所有候选数放入筛中}

    primes:=[];{素数集合置空}

    next:=2;

    repeat

     {找筛sieve中最小一个数}

     while not(next in sieve) and(next<=n)do

      next:=succ(next);

     primes:=primes+[next];{将最小数放入素数集合中}

     {将这个素数的倍数从筛中删去}

    j:=next;

    while j<=n do

     begin

      sieve:=sieve-[j];

      j:=j+next;

     end

    until sieve=[];

    j:=0;

    for next:=2 to n do{打印出所有素数}

     if next in primes then

     begin

      write(next:5);

      j:=j+1;

      if j mod 10=0 then writeln;

     end;

    writeln;

  end.

 

练习

  1.一家水果店出售四种水果,每公斤的价格是:苹果1.50元,桔子1.80元,香蕉2.0,菠萝1.60元。编一个程序,使售货员只要从键盘输入货物的代码及重量,计算机便能显示货物的名称、单价、重量及总价。

  2.输入一个英语句子,以句号.为结束标志, 统计句子中元音字母出现的次数,把句子所有辅音字母组成一个集合,并把这些辅音字母打印出来。

  3.编程序建立某班25人的数学课程成绩表,要求用数组类型和记录类型,其成绩表格式如下:

    姓名  性别  平时成绩  期中考试  期终考试  总评成绩

    张良  男     90     85     92      ?

    王心  男     70     82     71      ?

    ……

    李英  女     82     84     75      ?

  其中总评成绩=平时成绩×20%+期中考试×30%+期终考试×%50。

4. 输入五个学生的出生日期(月/日/年)和当天的日期,然后用计算机计算出每个人到当天为止的年龄各是多少?(如某人1975年10月1日出生,今天是94年12月1日,则他的年龄应为19岁,而另一人的出生日期为76年12月30日,则他的年龄为17岁。)

 

 

第十二课过程与函数

 

前面我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。用它们可以组成任何程序。但在应用中,还经常用到子程序结构。

  通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复出现,此时可以将这些程序段作为相对独立的整体,用一个标识符给它起一个名字,凡是程序中出现该程序段的地方,只要简单地写上其标识符即可。这样的程序段,我们称之为子程序。

  子程序的使用不仅缩短了程序,节省了内存空间及减少了程序的编译时间,而且有利于结构化程序设计。因为一个复杂的问题总可将其分解成若干个子问题来解决,如果子问题依然很复杂,还可以将它继续分解,直到每个子问题都是一个具有独立任务的模块。这样编制的程序结构清晰,逻辑关系明确,无论是编写、阅读、调试还是修改,都会带来极大的好处。

  在一个程序中可以只有主程序而没有子程序(本章以前都是如此),但不能没有主程序,也就是说不能单独执行子程序。pascal中子程序有两种形式:函数和过程。

一、函数

  在此之前,我们曾经介绍并使用了pascal提供的各种标准函数,如ABS,SUCC等等,这些函数为我们编写程序提供了很大的方便。但这些函数只是常用的基本函数,编程时经常需要自定义一些函数。

  (一)函数的说明

  在pascal中,函数也遵循先说明后使用的规则,在程序中,函数的说明放在调用该函数的程序(主程序或其它子程序)的说明部分。函数的结构主程序的结构很相似。

  函数定义的一般格式:

  function <函数名>

(<形式参数表>):<类型>; {函数首部}

  

  说明:

  ①函数由首部与函数体两部分组成。

  ②函数首部以关键字function开头。

  ③函数名是用户自定义的标识符。

  ④函数的类型也就是函数值的类型,所求得的函数值通过函数名传回调用它的程序。可见,函数的作用一般是为了求得一个值。

  ⑤形式参数简称形参,形参即函数的自变量。自变量的初值来源于函数调用。在函数中,形参一般格式如下:

  变量名表1:类型标识符1;变量名表2:类型标识符2;…;变量名表n:类型标识符n

  可见形参表相当于变量说明,对函数自变量进行说明,但应特别注意:此处只能使用类型标识符,而不能直接使用类型。

  ⑥当缺省形参表(当然要同时省去一对括号)时,称为无参函数。

  ⑦函数体与程序体基本相似,由说明部分和执行部分组成。

  ⑧函数体中的说明部分用来对本函数使用的标号、常量、类型、变量、子程序加以说明,这些量只在本函数内有效。

  ⑨函数体的执行部分由begin开头,end结束,中间有若干用分号隔开的语句,只是end后应跟分号,不能像程序那样用句号"."。

  ⑩在函数体的执行部分,至少应该给函数名赋一次值,以使在函数执行结束后把函数值带回调用程序。

  (二)函数的调用

  我们可以在任何与函数值类型兼容的表达式中调用函数,或者说,函数调用只能出现在允许表达式出现的地方,或作为表达式的一个因子。

  函数调用方式与标准函数的调用方式相同。

  函数调用的一般格式:

    <函数名>

    或

    <函数名>(实在参数表)

 

  说明:①实在参数简称实参。实参的个数必须与函数说明中形参的个数一致,实参的类型与形参的类型应当一一对应。

  ②调用函数时,一般的,实参必须有确定的值。

  ③函数调用的步骤为:计算实参的值,"赋给"对应的形参;

  (三)函数的应用举例

  例1 求正整数A和B之间的完全数(A

  分析:所谓完全数是指它的小于该数本身的因子之和等于它本身,如6=1+2+3,6即是一个完全数。因此我们可定义一个布尔型函数perfect(x),若x是完全数,其值为TURE,否则为FALSE。整个程序算法如下:

  1 for i:=A to B do

  2 if perfect(i) then writeln(i);

  源程序如下:

  program ex7_1;

  var

    i,a,b : integer;

  function perfect(x:integer):boolean;

  var

    k,sum : integer;

  begin

   {累加x所有小于本身的因数}

   sum:=1;

   for k:=2 to x div 2 do

    if x mod k=0 then sum:=sum+k;

   {判断x是否是完全数}

   perfect:=x=sum; {将结果赋值给函数名}

  end;{end of perfect}

  begin{主程序开始}

   write('Input a,b:');

   repeat {输入0

    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