Delphi学习第四天

时间:2021-07-21 16:23:00

今天开始碰到一些坎,一个以前都没越过的坎。或许说是自己内心的一种的恐惧。

从基本语法到实际应用的过渡,感觉很吃力。

下午效率很低,一直在这个节点纠结。

要想有所突破,这坎必须得迈。沉下心来,慢慢地去思考。一切都会好。

首先,一道递归的题让我纠结了很久,晚上终于把它解决。

1、递归函数的使用

先附上代码:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
Alpha:Integer;
procedure Test2(var A:Integer);forward
//Test2被说明为前置过程
procedure Test1(var A:Integer);
begin
A:=A-1;
if A>0 then
Test2(A); //经前置说明,调用未执行的过程Test2
writeln(A);
end;
procedure Test2(var A:Integer); //经前置说明的Test2的执行部分
begin
A:=A div 2;
if A>0 then
Test1(A); //在Test2中调用已执行的过程Test1
end;

begin
{ TODO -oUser -cConsole Main : Insert code here }
Alpha:=15; //给Alpha赋初值
Test1(Alpha); //第一次调用Test1,递归开始
end.

输出结果为:

0

0

0

0


当时对这一结果一直不理解,想结果为什么不是一个0。

后来查阅了很多资料,终于弄明白了,也加深了对递归的理解。

先附上有用的资料来源:递归详解

 从函数 Test1(15) ,经过判断语句,产生Test1(7),Test1(3),Test(1),这时Test1(15)的递归调用结束,输出结果0.此时,并没有结束。接着控制权返回到Test1(7),

同样上面的过程输出结果0.以此类推,就得到4个0.


补充递归的基本原理:

1 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递归继续执行.

2 递归函数中,位于递归调用前的语句和各级被调函数具有相同的顺序.

3 每一级的函数调用都有自己的私有变量.

4 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.

5 虽然每一级递归有自己的变量,但是函数代码并不会得到复制.

6 递归函数中必须包含可以终止递归调用的语句.

2、类的定义与使用方法

类的使用步骤:
(1)声明类的一个变量----这时可以将类作为一种数据类型来看待。(声明了类的变量后,并没有实际创建该类的对象,只是定义了一个纸箱该类对象的指针,称为类的引用)
(2)调用类的一个特殊函数---构造函数来进行一些初始化工作,比如按照类的结构来分配内存资源,完成对象的创建。
(3)对类的实例---对象进行操作、使用。可以修改对象的属性或调用对象的方法。
(4)使用完毕,调用类的另一个特殊函数---析构函数,删除创建的对象,同时释放相应的内存资源。此外,还可以调用Free过程释放对象占用的资源。

类的定义形式:

type ClassName=Class(AncestorClass)

                Memberlist

end;

类的继承形式:

type

         TForm1=Class(TForm)

end;

program UseClass;

{$APPTYPE CONSOLE}

uses
SysUtils;

type
TPerson=class
public
Name:string;
function GetAge:Integer;
procedure SetAge(A:Integer);
private
Age:Integer;
end;
TEmployee=class(TPerson)
public
Salary:integer;
DeptName:string;
procedure Infor;
procedure SetSalary(A:Integer);
end;
TCustomer=class(TPerson)
public
AddressName:string;
procedure Infor;
constructor Create(Str:string);
destructor Destroy;override;//方法的覆盖
end;
function TPerson.GetAge:Integer;
begin
Result:=Age;
end;
procedure TPerson.SetAge(A:Integer);
begin
Age:=A;
end;
procedure TEmployee.SetSalary(A:Integer);
begin
Salary:=A;
end;
procedure TEmployee.Infor;
begin
writeln('姓名: ',Name,'年龄: ',GetAge,' 部门: ',DeptName,'薪水: ',Salary);
end;
procedure TCustomer.Infor;
begin
writeln('姓名: ',Name,'年龄: ',GetAge,' 住址: ',AddressName);
end;
constructor TCustomer.Create(Str:string);
begin
inherited Create;
writeln('调用顾客类的构造函数。');
AddressName:=Str;
end;
destructor TCustomer.Destroy;
begin
writeln('姓名为: ',Name,'的顾客类对象被删除。');
inherited Destroy;
end;
var
E1:TEmployee;
C1:TCustomer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
E1:=TEmployee.Create; //调用默认的构造函数创建对象
E1.Name:=' 李兵 ';
E1.SetAge(23); //既有SetAge,又有GetAge?
E1.SetSalary(2000); //只有一个SetSalary?
E1.DeptName:='贷款部 ';
E1.Infor; //显示职员信息
E1.Destroy; //调用默认的析构函数
C1:=TCustomer.Create('北一路'); //调用构造函数创建对象(类的构造函数)
C1.Name:='张力 ';
C1.Age:=45;
// 显示顾客信息
C1.Infor; //显示顾客信息
C1.Destroy; //调用自定义的析构函数(对象的析构函数)
readln;
end.


输出结果:

姓名:  李兵 年龄: 23 部门: 贷款部 薪水: 2000
调用顾客类的构造函数。
姓名: 张力 年龄: 45 住址: 北一路
姓名为: 张力 的顾客类对象被删除。

关于上面的例程的几点说明:

  • TPerson类默认从TObject类派生,然后又派生了两个子类:TEmployee、TCustomer.TEmployee、TCustomer这两个类继承了TPerson类的Age、Name属性、GetAge函数和SetAge过程。
  • TEmployee对TPerson功能进行了扩展,增加了Salary、DeptName属性,Info、SetSalary过程。
  • TCustomer类对TPerson类进行了扩展,增加了Address属性、Info过程。另外,还自定义 了构造函数和析构函数。
  • 调用构造函数的方法与调用析构函数的方法不同,前者使用的是“类的构造函数”,后者使用的是“对象的析构函数”。

3、静态方法的使用

program Project1; 
{$APPTYPE CONSOLE}
type
TPerson = class //人类
procedure Infor; //显示信息
end;
TEmployee = class(TPerson) //职员类
procedure Infor; //显示职员信息
end;
procedure TPerson.Infor; //显示调用的是TPerson类的Infor
begin
Writeln ('TPerson.Infor');
end;
procedure TEmployee.Infor; //显示调用的是TEmployee类的Infor
begin
Writeln('TEmployee.Infor');
end;
var
P1: TPerson; //声明一个人类的变量
E1: TEmployee; //声明一个职员类的变量
begin
P1:=TPerson.Create;
P1.Infor; //调用的是TPerson类的Infor
P1.Destroy;
P1:=TEmployee.Create;
P1.Infor; //调用的是TPerson类的Infor
TEmployee(P1).Infor; //调用的是TEmployee的Infor
P1.Destroy;
E1:=TEmployee.Create;
E1.Infor; //调用的是TEmployee类的Infor
E1.Destroy;
end.

运行结果如下:
TPerson.Infor
TPerson.Infor
TEmployee.Infor
TEmployee.Infor

--------------------------------------------------------------------------------

傻傻分不清,网上查阅:

函数与过程的区别:过程无返回值,函数有返回值。

参数传递的顺序:Pascal语言按照从左到右的顺序。

构造函数和析构函数,我首先想到的是create,destroy,至于具体区别,用了才知道。

先码到这,晚安。

调整心情,明天GO ON.