pascal语言基础(二)

article/2025/10/3 14:07:13

该内容为学习 《PASCAL程序设计 第2版》郑启华编著  的笔记,部分与c语言对比学习,方便记忆。

pascal语言基础(一)

 

函数与过程程序设计

函数

1. 定义

FUNCTION <函数名>(<参数表>):<函数类型>;<说明部分>;BEGIN<函数体>END;
  • 函数体由给函数名赋值的语句构成,函数类型即函数的返回值类型,返回的是函数名的最终结果。
  • 如果没有参数,则括号也不需要。
  • 如果有多种类型的参数,相同参数之间用逗号,不同参数之间用分号。
  • 如果函数中需要用到变量,需在说明部分定义,为局部变量

2. 调用

<函数名>(<实在参数表>)

如果没有实在参数,则括号也略去。

3. 例子

定义函数rand产生随机数,使得生成一些两位整数x两位整数的式子,作答后判断正误。

PROGRAM game(input, ouput);VARx, y, z, answer: integer;seed: real;{产生一个[0,1)的随机数}FUNCTION rand(VAR seed:real):real;CONSTa= 93.0;m = 8192.0;c = 1.0;BEGINseed := a*seed+c;{seed/m - trunc(seed/m)获取了seed/m的小数部分,其再乘以m,获得一个[0,m)的数}seed := round( (seed/m - trunc(seed/m)) * m );{seed的范围为[0,m),计算得出的rand为[0,1)}rand := seed/m;END;{主程序}BEGINseed := 0.7823;REPEAT{产生2个两位的随机整数x, y}x := trunc(rand(seed)*100);y := trunc(rand(seed)*100);writeln(x:2, '*', y:2, '=?');read(answer); {输入算式答案}{判断正确与否}z := x*y;if answer=zthen writeln('yes!')else writeln('no! it is ', z)UNTIL answer=-1END.
  • 函数定义中,参数表中的VAR表明形式参数seed为变量参数,若没有VAR则为值参数
  • 变量参数的改变会影响是实在参数的值,值参数的改变不影响实在参数的值。

上述例子中,rand函数为产生随机数的某种方法,可得到一个[0,1)之间的数。为了使每次获得的随机数不同,需定义函数中的参数seed为变量参数,随着函数的调用而改变参数的值。

输出结果:

 0*84=?
0
yes!
13*98=?
4567
no! it is 1274
83*26=?
543
no! it is 2158
69*34=?
435
no! it is 2346
20*27=?
345
no! it is 540

 

过程

1. 定义

PROCEDURE <过程名>(<形式参数表>);<说明部分>;BEGIN<过程体>END;
  • 参数表中包括值参数和变量参数,过程的结果由变量参数送回,可以包括多个结果或无结果。
  • 过程体的通常任务是对值参数进行计算,计算结果赋值给变量参数。
  • 无参数时,形式参数表和括号都应略去。

2.  调用

<过程名>(<实在参数表>)

过程的调用必须作为一个单独的语句。 

3. 例子

打印表头。

PROGRAM table(input, ouput);{打印表头}PROCEDURE printhead;VARi: integer;BEGINfor i:=1 to 21 dowrite('*');writeln;writeln('* this is the table *');for i:=1 to 21 dowrite('*');writeln;END;{主程序}BEGINprinthead;END.

该过程既无结果也无参数,输出:

*********************
* this is the table *
*********************

 

对比

  • 函数通过函数名回送一个结果值,需说明返回值的类型;过程的结果由参数送回,可以包括多个结果或结果。
  • 函数体中必须要有给函数名赋值的语句,过程体不需要也不能有。
  • 函数的调用可以出现在表达式中,过程的调用必须作为一个单独的语句。

例:输入x值,计算y。有  y = \frac{sh(1+shx))}{sh2x+sh3x} , sh(t) = \frac{e^{t}-e^{-t}}{2} 。

函数实现:

PROGRAM ysh1(input, ouput);VARx, y: real;{函数}	FUNCTION sh(t:real):real;BEGINsh := (exp(t)-exp(-t))/2;END;{主程序}BEGINread(x);y := sh(1+sh(x))/(sh(2*x)+sh(3*x));writeln('x=', x, ', y=', y);END.

过程实现:

PROGRAM ysh2(input, ouput);VARx, y, s1, s2, s3: real;{过程}	PROCEDURE sh(t:real; VAR s:real);BEGINs := (exp(t)-exp(-t))/2;END;{主程序}BEGINread(x);sh(x, s1);sh(1+s1, s1);sh(2*x, s2);sh(3*x, s3);y := s1/(s2+s3);writeln('x=', x, ', y=', y);END.

输入输出结果:

5
x= 5.0000000000000000E+000, y= 1.3899708997173883E+026

 

函数与过程作为参数

作为参数的函数或过程本身只能有值参数。使用:

PROGRAM test(input, output);VARs1, s2: real;FUNCTION f1(p1:real):real;BEGIN...END;FUNCTION f2(function f(p:real):real; a:real):real;BEGIN...END;BEGINread(s1);s2 := f2(f1, s1);END.

 

嵌套与递归

1. 嵌套

形式1:定义2个并列的函数,主程序可以调用2个函数,函数2能调用函数1,函数1不能调用函数2。

PROGRAM test(input, ouput);VARx1, x2, y1, y2: real;FUNCTION fun1(p1:real):real;BEGIN...END;FUNCTION fun2(p2:real):real;BEGIN...fun2 := fun1(p2);END;BEGINread(x1, x2);y1 := fun1(x1);y2 := fun2(x2);writeln(y1, y2);END.

形式2:在函数1中定义函数2,则函数1能调用函数2,函数2不能调用函数1,主程序只能调用函数1。

PROGRAM test(input, ouput);VARx1, y1: real;FUNCTION fun1(p1:real):real;FUNCTION fun2(p2:real):real;BEGIN...END;BEGINfun1 := fun2(p1);END;BEGINread(x1);y1 := fun1(x1);writeln(y1);END.

形式3:第一种情况中加上向前引用说明和保留字FORWARD,则函数1和2能互相调用。

PROGRAM test(input, ouput);VARx1, x2, y1, y2: real;FUNCTION fun2(p2:real):real;forward;FUNCTION fun1(p1:real):real;BEGIN...fun1 := fun2(p1);END;FUNCTION fun2;BEGIN...fun2 := fun1(p2);END;BEGINread(x1, x2);y1 := fun1(x1);y2 := fun2(x2);writeln(y1, y2);END.

类似于c的声明,不过一般很少有函数要互相调来调去,按顺序写就好了,或者干脆所有函数都声明。

2. 递归

  • 直接递归:函数1直接调用其本身。
  • 间接递归:函数1调用函数2,函数2又调用函数1。

例:递归计算 n!  。

PROGRAM facn(input, ouput);VARx, y: integer;FUNCTION fac(n:integer):integer;BEGINif n=0then fac := 1else fac := n*fac(n-1)END;{主程序}BEGINread(x);y := fac(x);writeln(x, '!=', y);END.

输出结果:

3
3!=6

 

枚举与子界 

枚举

1. 定义

TYPE<枚举类型标识符> = (<标识符>, ..., <标识符>);
VAR<枚举类型变量表>: <枚举类型标识符>;

枚举值只能是标识符(以字母开头的字母数字组合),每个枚举值只能出现在一个枚举类型定义中,并且只能在该定义中出现一次。

例:

TYPEday = (sunday, monday, tuesday);month = (jan, feb, mar);
VARpayday, firstday: day;yearend, curmonth: month;

2. 运算

可以将枚举值直接赋值给枚举变量,或者同类型的枚举变量赋值给另一个枚举变量,例:

{枚举值赋给枚举变量}
curmonth := mar;
firstday := monday;
{枚举变量赋给同类型枚举变量}
payday := firstday; 

枚举变量可进行ord,pred,succ和关系运算,例:

{序号从0开始}
ord(jan) = 0
{第一个枚举值无前导,最后一个枚举值无后继}
pred(monday) = sunday 
succ(monday) = tuesday

3. 使用

枚举类型不能直接read和write,可用其序号与CASE结合使用。

 

子界

1. 定义

TYPE<子界类型标识符> = <常量1>..<常量2>;
VAR<子界类型变量表>: <子界类型标识符>;
  • 子界只能是有序类型(整型,字符型,布尔型,枚举型),不能为实型。
  • 程序执行时会先检查存储在子界类型变量中的值是否符合其定义要求,若错误,会停止程序打出错误信息。

枚举型的子界:

TYPEday = (sun, mon, tue, wed, thu, fri, sat);schoolday = mon..fri;

2. 运算

和其基类型运算一样,只是限制了自身的值的范围。


 

数组类型

一维数组

1. 定义

TYPE<数组类型标识符> = array[<下标类型> of <基类型>];
VAR<数组变量表>: <数组类型标识符>;
  • 与c不同,下标从1开始。
  • 值的表示和c语言相同,a[1]表示数组a的第1个元素值。
  • 下标类型可为:布尔,字符,枚举,子界(1..10属于子界类型而不是整型)。
  • 基类型可以是任何标准类型或用户定义类型,包括数组类型(字符串数组)。

例:day为枚举类型,数组类型art1由7个整型元素组成,art2由24个布尔类型元素组成。

TYPEday = (sun, mon, tue, wed, thu, fri, sat);art1 = array[day]of integer;art2 = array['a'..'z']of boolean;
VARc: art1;d: art2;

2. 使用

上述实例中数组类型art1值可能的对应关系如下:

c[sun]c[mon]c[tue]c[wed]c[thu]c[fri]c[sat]
2353454335724543

基本与c语言相同,以下2句效果等价:

{a, b为同类型的数组,下标1-10}
b := a;for i:=1 to 10 dob[i] := a[i];

 

多维数组

1. 定义

TYPE <数组类型标识符> = array[<下标类型1>, ..., <下标类型n>]of <基类型>;例:
TYPEmat = array[1..5, 1..10]of real;
VARa, b: mat;

2. 使用

和c相同,a[i][j] 表示上述二维数组的某一元素。

 

紧缩字符数组

当数组元素为字符型布尔型时,按上述定义方式每个字节占用一个存储单元,假设每个存储单元由32个二进位构成,则会造成空间浪费。因为字符型仅需8个二进位,布尔型为1个二进位。

1. 定义:

VARa: array[1..10]of char;b: packed array[1..10]of char;

a为一般字符数组,b为紧缩字符数组。

2. 紧缩字符数组相当于一个字符串,可以执行整体读语句:

readln(b);输入:abcdefg
结果:b为(abcdefg   ),结尾补3个空格输入:abcdefghijk
结果:b为(abcdefghij),超出定义长度,多余部分去除

3. 对b进行整体赋值和比较操作要求长度相同:

b := 'abcdefj';    {错误}
b := 'abcdefg   '; {正确}

4. 通常在存储字符数组和处理字符串时用b的形式以节约存储空间,而在处理每个字符时用a的形式以节约访问时间。pascal提供了2个标准过程用于a和b之间的转换:

{将非紧缩数组a的第n个下标开始的元素存储到紧缩数组b中,存储的元素个数为b的长度}
pack(a, n, b);
{将b的所有元素存储到a中,存储从a的第n个位置开始}
unpack(b, a, n);

通常上述的 n 写为 1。

 

保形数组参数

在数组作为参数时,实在参数和形式参数的下标的上下界可以不一致,实在参数不得超过形式参数所允许的下标界限。

VARa: array[1..4, 1..4]of real;b: array[1..6, 1..6]of real;
PROCEDURE pro(var a:array[l1..u1:integer; l2..u2:integer]of real);...

过程pro可以以数组a, b为实际参数进行运行,即使a, b的下标界限不相同。


http://chatgpt.dhexx.cn/article/4ISy6C1x.shtml

相关文章

pascal语言基础(一)

该内容为学习 《PASCAL程序设计 第2版》郑启华编著 的笔记&#xff0c;部分与c语言对比学习&#xff0c;方便记忆。 pascal语言基础&#xff08;二&#xff09; 基本介绍 保留字&#xff08;35个&#xff09; AND、ARRAY、BEGIN、CASE、CONST、DIV、DO、DOWNTO、ELSE、END、…

PASCAL语言的基本知识

Pascal是一种计算机通用的高级程序设计语言。它由瑞士Niklaus Wirth教授于六十年代末设计并创立。 以法国数学家命名的Pascal语言。现已成为使用最广泛的基于DOS的语言之一。其主要特点有&#xff1a;严格的结构化形式&#xff1b;丰富完备的数据类型&#xff1b;运行效率高&am…

C语言assert()函数用法总结

&#xfeff;&#xfeff; assert宏的原型定义在<assert.h>中&#xff0c;其作用是如果它的条件返回错误&#xff0c;则终止程序执行&#xff0c;原型定义&#xff1a; #include <assert.h> void assert( int expression ); assert的作用是现计算表达式 expression…

C语言assert函数完全攻略

断言assert函数&#xff0c;C语言assert函数完全攻略 对于断言&#xff0c;相信大家都不陌生&#xff0c;大多数编程语言也都有断言这一特性。简单地讲&#xff0c;断言就是对某种假设条件进行检查。在 C 语言中&#xff0c;断言被定义为宏的形式&#xff08;assert(expressio…

python assert函数解析(最清晰的解释)

欢迎关注WX公众号&#xff1a;【程序员管小亮】 python assert的作用&#xff1a; assert函数用于程序调试 Python 官方文档解释https://docs.python.org/3/reference/simple_stmts.html#assert “Assert statements are a convenient way to insert debugging assertions …

C++中的assert用法

assert用法 void assert(int expression);C中assert&#xff0c;即断言&#xff0c;可以在程序调试阶段检查错误&#xff0c;常用的就比如函数传参时&#xff0c;若是整型&#xff0c;是否超出范围&#xff1b;若是字符串型&#xff0c;地址是否为空等。 在正常时&#xff0c;…

assert()函数(断言函数)

assert()函数&#xff08;断言函数&#xff09; 一&#xff0c;快速了解一下assert函数 void assert (int expression);//括号里面是一个表达式。assert函数是一个宏。 括号里面的表达式如果为真&#xff0c;程序正常执行。 如果函数形式的宏的参数表达式比较等于零&#x…

c语言中assert函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询 1、assert将通过检查表达式expresion的值来决定是否需要终止执行程序。 2、如果表达式expresion的值是假的(即0)&#xff0c;它将首先向标准错误流stderr打印错误信息。 通过调用abort函数终止程序运行。否则&#xff0c;assert没有…

assert()函数

今天&#xff0c;遇到一个函数返回值时引用&#xff0c;但是返回值存在为NULL的情况。下面是搜到的解决方案 然后&#xff0c;就搜了搜assert()函数的用法&#xff0c;找到一篇&#xff0c;贴在下面assert()函数用法总结 assert宏的原型定义在<assert.h>中&#xff0c;其…

assert()函数用法总结

assert宏的原型定义在<assert.h>中&#xff0c;其作用是如果它的条件返回错误&#xff0c;则终止程序执行&#xff0c;原型定义&#xff1a; #include <assert.h> void assert( int expression ); assert的作用是现计算表达式 expression &#xff0c;如果其值为假…

assert断言函数简介

目录 &#x1f38d;1.整体介绍 &#x1f38d;2.assert() 的用法和机制 &#x1f38d;3.关于NDEBUG 宏 &#x1f38d;4.使用assert()注意事项 &#x1f38d;4.1使用 assert() 时&#xff0c;被检测的表达式最好不要太复杂 &#x1f38d;4.2不要用会改变环境的语句作为断言…

第十二章 C语言调试_assert断言函数

在我们的实际开发过程之中&#xff0c;常常会出现一些隐藏得很深的BUG&#xff0c;或者是一些概率性发生的BUG&#xff0c;通常这些BUG在我们调试的过程中不会出现很明显的问题&#xff0c;但是如果我们将其发布&#xff0c;在用户的各种运行环境下&#xff0c;这些程序可能就会…

c语言之assert()函数用法总结

1.assert宏的原型定义在<assert.h>中&#xff0c;其作用是如果它的条件返回错误&#xff0c;则终止程序执行。 库函数&#xff1a; assert.h 原型定义&#xff1a; void assert( int expression ); assert的作用是现计算表达式 expression &#xff0c;如果其值为假&…

接私活必备!国外5个顶级程序员接私活网站

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 人生交契无老少&#xff0c;论交何必先同调。 文章目录 PeoplePerHour&#xff1a;薪酬最高的专业自由职业者网站GuruFreeLancerUpworkFiverr 话说程序员这个职业有…

关于网上程序员接私活的问题

点击上方“程序人生”&#xff0c;选择“置顶公众号” 第一时间关注程序猿&#xff08;媛&#xff09;身边的故事 文丨eachfeel 很多人都谈网上接私活这件事&#xff0c;其实大家想法都差不多&#xff0c;现在做软件的那么多&#xff0c;工资也不是那么高了&#xff0c;不像以前…

程序员兼职可以从什么平台接私活?

之前有一项调查&#xff0c;结果显示&#xff1a;想通过副业赚钱的朋友&#xff0c;其中60%的人找不到门路。今天这篇文章就给大家一批可以接私活的平台。不过&#xff0c;再次强调一下&#xff0c;副业并不等于接私活儿。 私活类型与价格区间 程序员兼职的项目大致可分为三类…

10个程序员可以接私活的平台和一些建议!

来源&#xff1a;http://mrw.so/5isQLi 什么样的私活不能接 1、没有第三方担保的个人对个人的尽量不要接&#xff0c;双方都没保障&#xff0c;出了问题很大的可能撕破脸皮不了了之。 2、一上来就直接说给我开发一个什么软件&#xff0c;不说具体需求&#xff0c;没有需求文档的…

程序员接私活常用平台汇总

作者&#xff1a;镇上宝塔 素材来源&#xff1a;今日头条 今天分享一些接私活的常用平台。 ▍前 言 关于程序员接私活&#xff0c;社会各界说法不一。按照作者的观点来说如果你确实急用钱&#xff0c;价格又合适&#xff0c;那就去做。如果不怎么缺钱&#xff0c;那就接私活之前…

程序员接私活的几个平台和建议,避免掉坑!

大家对于程序员接私活这件事的看法&#xff0c;褒贬不一。但是你如果确实用钱&#xff0c;价格又合适&#xff0c;那就大胆去接。 如果不那么缺钱&#xff0c;那么接私活之前先考虑清楚&#xff0c;如果自己将空余时间用在接私活所产生的价值是不是大于提升自己。如果是的话&a…

程序员接私活月入2万?分享10个接私活的网站快收藏~

最近&#xff0c;在和身边的程序员聊天中&#xff0c;听不少朋友分享了自己接私活的经历&#xff0c;那收入真是让我“瞠目结舌” … 程序员A&#xff1a;我Java程序员&#xff0c;工作两年&#xff0c;月薪13K&#xff0c;私活20K。 程序员B&#xff1a;之前在单位上班&#…