Delphi复习(四)ObjectPascal语句,过程和函数
在程序语言的学习中,数据类型之后的就是语句学习了,我们用语句关键字和操作指令来控制程序。
Pascal中的语句分为两大类:简单语句和构造语句,其中简单语句是不包括其他语句的语句,而构造语句则是简单语句按照一定规则构造而成的。构造语句又称为复合语句,复杂语句,反正随便它咯,我们只要知道,在begin和end中将简单语句括起来的话,那就是复合语句。
一:简单语句
1:赋值语句。
形式为:变量 := 表达式;
类似于C++中的“=”咯。而“=”号,在Pascal中是等于号的判断,等同于“==”咯。
2:流程控制语句之条件判断语句
1)if+条件 then+执行一段程序
2)if+条件 then+执行一段程序 else+另一段程序
其中if后的条件判断结果当然应当是布尔类型,then中实现的是true时的语句,else中实现是false时的语句。其他和C++中的if()else差不多了,值得注意的是,我们可以用begin,end这样的复合语句辅以控制,某志很喜欢这么做,感觉可读性强,呵呵。实际上,在Delphi中,只要打出ifeb再按下Ctrl+J就可以实现了,没必要慢慢打代码,呵呵。
值得注意的是:if,then,else是个完整的语句,我们不可以在他们之间打分号,除非其中的复合语句使用,在该句本身不可用分号打断。
3)情况判断语句case,实现如下
case 表达式或变量 of
情况可能1:执行程序;
……
情况可能n:执行程序;
else 执行程序;
end ;
和C++也没什么区别,所以不多做赘述。被判断的变量或属性可以是整型,字符型,枚举型或子界型。
3:循环语句。
OTL,没什么创意,repeat语句和while语句和C++的do..while,while没什么区别,下面简单说下。
1)repeat“直到”循环语句格式如下
repeat 执行一段程序; until 循环结束条件;
和do..while一样,此循环至少会执行一次。
2)while“当”循环语句格式如下
while 布尔表达式 do 执行一段程序;
和C中的while一样,布尔表达式结果为真则执行do后的程序,否则就跳出循环执行while语句后的程序。
值得注意的是:
1:repeat语句中有分号隔离,while语句中没有分号自身分割。
2:repeat,while语句的条件判断结果给程序造成的影响是相反的。一个是终止条件,一个是循环进行条件。
3)for循环语句两种格式
for 变量:=表达式1 to 表达式2 do 一段程序
for 变量:=表达式1 downto 表达式2 do 一段程序
这是点很可怜的设定,for的功能在OP中受到了极大的限制,它的循环控制仅仅被计数器限制成i++或i–这两种情况了,它的步长被限制为1。当然我们也可以在循环体最后再花上一段代码来处理它,然而确实不如C中好用了。遗憾哦>_<
4:With语句
With语句是Pascal编程语言独有的语句,不过最近JavaScript 和Visual Basic也添加了这种语句。他存在的意义,仅仅是简化代码而已,虽然有大师极力推崇它,但某志经常被它害的陷入逻辑陷阱中,所以索性不使用它。大家有兴趣的可以看看它的说明,某志这里不再细说了。
5:Break语句Continue语句
和C++中一样,是完全的跳出循环。
如果想仅跳过本次循环,那么就使用Continue跳过该句后的代码段,直接进入下一次的循环。
JAVA中称方法,C/C++中称函数,这里又分为过程和函数,甚至连关键字都不同,>_<
真折腾人。
一:过程与函数的概念,定义
首先,如果我们一组语句能够完成某种功能,我们就称之为过程。若它们完成了某功能后又返回了一个数值,那么我们就称之为函数。过程以保留字procedure开始,函数以保留字function开始,他们的参数都是以分号分隔的,例如:
procedure SetDate( Year: Integer; Month: Integer; Day: Integer );
也可以将其相同类型的参数写在一起,但是某志不推荐>_<
procedure SetDate( Year, Month, Day: Integer );
函数的话就比过程多了一个返回值,换个关键字而已
function GetAverage( Num: Integer; Total: Double ):Double;
过程和函数的实现过程都以begin,end封装起来,函数的返回值可以给函数名或者result变量,它默认是返回值,例如
function GetAverage( Num: Integer; Total: Double ):Double;
begin
GetAverage := Total / Num;
// 或者使用下句 Result := Total / Num;
end
二:过程和函数的参数
过程和函数是封装起来的代码段,他们与外界的交互就靠的是参数。
而参数在OP中是分为三大类的,值参数,变量参数,常量参数。
系统默认的是使用值参数,也就是说,我们函数使用的是形参,并不影响外界实参的值,在声明时就如上面的例子中参数一样,给出形参名和数据类型就OK了。
而变量参数,声明时需要增加var标识,如我们下例:
procedure DoubleTheValue (var Value: Integer);
begin
Value := Value * 2;
end;
其中的Value就是变量参数,它传到过程中的不再仅仅是一个形参值,而是此变量本身的地址,所以在该过程被调用一次的话,Value就发生一次变化。
常量参数比较好理解,就是参数前加个const,告诉我们过程函数执行时不改变参数值。 参数的生命周期和作用域和C++一致,因为不好解释,也不再多说了。
三:比较特别的参数
- 开放数组参数。
和C语言不同,Pascal中函数以及过程的参数个数是预定的,若参数个数我们之前没有想好规划好,我们就需要通过开放数组来实现参数传递。
例如:
function Sum (const A: array of Integer): Integer;
var
I: Integer;
begin
Result := 0;
for I := Low(A) to High(A) do
Result := Result + A[I];
end;
此时我们调用此函数,传参随意给定一个整形的数组就行。长度是不受限制的。
- 类型变化的开放数组参数
我们上面的开放数组参数还是有限制的,那就是我们必须使用整形的参数,而实际上,Delphi还允许定义类型变化甚至无类型的开放数组,这种特殊的数组元素类型可随意变化,能很方便的作传递型参数。因为过于复杂,这里不再详细讲述。
四:Forward声明
当我们使用一个标识符时,编译器必须知道该标识符到底是什么。然而我们有些时候无法去提前声明,例如,我们函数A调用B,B又调用A,那么哪个标识符该在前面呢?所以我们不得不先告诉系统,现在我们存在这个一个函数,具体是什么样子,你先别管,只要知道它存在且合法就足够了,这微是forward声明。
在此声明时,仅需要给出该声明对象的名字和参数,不需要给出它的代码。
例如:
procedure Hello; forward;
procedure DoubleHello; forward;
procedure Hello;
begin
if MessageDlg ('Do you want a double message?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
DoubleHello
else
ShowMessage ('Hello');
end;
procedure DoubleHello;
begin
Hello;
Hello;
end;
这样我们就实现了A与B的递归调用。
五:函数重载
和C++/JAVA完全一样啦,函数名相同,仅是函数参数不同。或者是函数参数个数,或者是参数类型,但是返回值不能做为区别标准。
但Pascal中麻烦的一点是,重载的函数声明后面都必须加上overload关键字。- -挺麻烦的。
六:参数缺省
这是个很有趣的东西,按道理来说,参数个数应该是严格限定的,可是pascal中参数可以进行缺省0 0,呼,支持重载又可以参数缺省,还真敢充强。。
某志这里给出个封装MessageBox的方法,大家可以看看。
procedure MessBox (Msg: string;
Caption: string = 'Warning';
Flags: LongInt = mb_OK or mb_IconHand);
begin
Application.MessageBox (PChar (Msg),
PChar (Caption), Flags);
end;
其中Msg,Caption都可以缺省,也就是说,我们调用此函数时,可以仅传一个Flags参数就OK了,例如
MessBox ('Something wrong here!');
MessBox ('Something wrong here!', 'Attention');
MessBox ('Hello', 'Message', mb_OK);
这三种都是合法的。
但是值得注意的是,我们不可以隔单进行缺省,也就是说,我们不可以缺省第一个参数,再不缺省第二个参数,又缺省第三个参数。。
其实,了解汇编内部的朋友应该清楚,跳跃缺省的数据判断读取会是很痛苦的。还是别折腾Borland工程师咯^ ^