Delphi(ObjectPascal)基础语法

 
一个程序分为两个部分:
1、程序首部:
program 来标识这是一个pascal程序  后面的是可执行文件的名称
程序名称
2、程序体:
说明部分:数据先定义后使用
执行部分:以begin开始,以end结束 之后一个.表示整个程序的结束
uses 项目引用的其他文件,系统创建的单元文件或是用户创建的的单元文件
接口部分不能相互引用,实现部分可以
所有单元隐式引用system.pas
{$R *.res}是编译器指令,告诉编译器去链接一个资源文件,在项目同名、后缀为
.res的文件查找windows资源信息
单元文件.pas:
应用程序的源代码
自定义单元:
unit 单元名;一定要与pas文件一致
interface
<公共说明部分>
用于声明对其他单元该部分是可以访问的—即可以从该单元中访问哪些东西,没有运行代码
uses引用了系统预先定义的单元文件
接口部分包括了类型声明、变量声明、常数
implementation
<私有说明部分>
包括了代码实现部分和隐含部分
uses引用了程序实现部分引用的单元文件,在用户当前项目中创建的
实现部分包括了类型声明、变量声明、常数和过程—只能在单元内使用
定义在实现部分的过程和函数如果接口部分没有相应的声明,则只能在单元内部使用
{$R *.dfm} 范围检查打开  定义资源文件
begin/initialization
<初始化部分>
在所有其他代码运行前运行
Finalization
执行程序终止功能
在所有其他代码运行后运行
end.
Sender:Tobject   代表调用所在过程的控件
用法:1、可以直接当作那个控件用
2、(Sender as 控件名).控件属性  调用属性
窗体文件.dfm
中间编译单元.dcu
资源文件.res
配置与选项文件.dof
定义常量:
CONST
        <常量标识符>=<常量>
定义变量:
VAR
         <变量标识符>:<类型>;
定义属性Property:
Property是一个很有意思的语法特性,它使得方法具有了字段的调用特征,并赋予字段执行动作的能力。
如果你使用过C++ Builder来写基于VCL的程序,我想很多人都会注意到这样一点,比如:
edt.Text = "test"; 这个时候edt文本框的内容会随之改变,但是“理论”上Text应该只是改变了Text所在的内存数据而已,为什么会导致窗口更新界面着一些列动作?
这就是因为Property这一特性,Property是Borland为C++扩展的语法特性,目的在于使C++ Builder能够方便的使用VCL库,毕竟VCL是使用Object Pascal写的。
有些扯远了,言归正传,这里还是总结一下在Delphi中如何使用Poperty这一语法特性。
如果学习过C#的朋友应该会很容易理解,因为C#的属性就是学习自Delphi,毕竟C#和Delphi是同一个设计者。
定义一个属性Property的基本格式如下:
property 属性名 : 属性值类型 read 属性读函数/属性值变量 write 属性写函数/属性值变量
这里简单解释一下:
1。Property是属性定义关键字。
2。属性的特征类似于字段,所以属性名就像字段名,属性值类型就像字段的值类型
3。属性读函数,是属性被“读取”时所执行的操作,这样在执行“取值”操作时,具备了执行其他动作的可能。
另外,属性值变量,可以是Property所在类能够访问的任何变量,如果使用了属性值变量,则相当于属性值直接从值变量中获取,这和直接赋值是没有什么差别的
4。属性写函数,是属性被“写入”时所执行的操作,这样在执行属性“赋值”操作时,具备了执行其他动作的可能。比如:写入edt的Text属性时,窗口会同时执行界面更新操作。
另外,属性值变量和3中所述类似,如果使用了,就相当于将传来的属性值直接赋值到对应的属性值变量
这里的函数是真正的函数,不像C#中那样的getter和setter,所以会有些难以理解。
5。属性读函数的函数声明:
function 读函数名: 属性值类型;
其中读函数名可以自定义,只要和属性声明中一样即可,该函数的返回值就是读属性操作时实际获取的值。
6。属性写函数声明(其实是一个子函数):
procedure 写函数名(value : 属性值类型)
其中写函数名可以自定义,只要和属性声明中一样即可,该函数参数value,就是对属性赋值时传递过来的实际值。
7。读函数和写函数必须设置一个,如果只设置读函数,而没有设置写函数(同时去掉write关键字),这样的属性就是只读属性,同理也可以设置只写属性
8。为了保证属性公开性的同时掩盖读写函数的可见性,可以将读写函数设置为私有,而将属性设置为共有,这样可以避免将读写函数本身暴露给调用者,否则就不太拉风了。
举例:
TxKernelSearchThread = class(TThread)
   private
    keyword_list: TStringList;
     procedure SetKeyword(value: UnicodeString);
   public
    property Kerword:UnicodeString write SetKeyword;
    。。。
end;
procedure TxKernelSearchThread.SetKeyword(value: UnicodeString);
begin
if value = '' then Exit;
ExtractStrings([' '],[' '],PWideChar(value),Self.keyword_list);
end;
上面是一个只写属性的例子。
属性的一个很重要的应用就是VCL中的控件属性,以及事件属性等,这也就解释了为什么向文本框的Text属性赋值,会更新界面操作,这正是因为属性将字段和函数的特征结合了起来。
算术运算符:
/(实数除)结果为实型
DIV(整除)
mod(求余)整数运算
赋值:
变量名:=表达式;
输出语句:
write(表达式1,表达式2,...);
writeln('数据':场宽:场宽);
输入语句:
read(<变量名表>);可以继续读下一个read语句
readln[(<变量名表>)];必须换行,可以无输入,作为暂停。
布尔类型:
是顺序类型:false为0 true为1 布尔不能直接读语句提供值
IF语句:
IF <布尔表达式> THEN 语句;
IF <布尔表达式> THEN 语句1 ELSE 语句2;
case语句:
case<表达式>of
 <情况表号1>:语句1;
 <情况表号2>:语句2;
 <情况表号3>:语句3;
end;
for<控制变量>:=<表达式1>to<表达式2>do<语句>;递增
for<控制变量>:=<表达式1>downto<表达式2>do<语句>;递减
不能为实型
while<布尔表达式>do<语句>;
repeat
      <语句1>;
           .
           .
      <语句n>;
until<布尔表达式>;
type
      <标识符1>=<类型1>;
 .
 .
      <标识符n>=<类型n>;
使用数组类型等构造类型应在说明部分进行类型说明。
type标识开始一个类型定义段
数组:
分为静态和动态
一维数组的格式:
array[下标1..下标2]of<基本型>;
动态定义:
arrayof<基类型>;setlength过程设置大小
type arrartype=array[1..8]of integer;
var a1,a2:arraytype;
多维数组:
array[下标类型1]of array[下标类型2]of 元素类型
array[下标类型 1,下标类型 2] of 元素类型;
字符类型:
const 字符常量='字符'
var 字符变量:char;
后继函数: succ('a')='b'
前继函数: pred('B') ='A'
序号函数: ord('A') =65
字符串类型:
type<字符串类型标识符>=string[n];n是字符串长度,
必须是0~255之间,0中存放的是字符串的实际长度,
将 string[n]写成 string,则默认 n 值为 255
var 字符串变量:字符串类型标识符
另一种定义:
var name:string[8];
连接:
连接的结果字符串长度超过 255, 则被截成 255 个字符。 若连接后的
字符串存放在定义的字符串变量中, 当其长度超过定义的字符串长度时, 超过部
份字符串被截
字符串的函数:
copy(s,m,n)
length(s)
pos(sub,s)
insert(sour,s,m)
delete(s,m,n)
str(x[:w[:d]]),s]
枚举类型:
格式:(标识符1,标识符2..标识符n)
type days=(sun,mon,tue,wed,thu,fri,sat);
子界类型:
格式:<常量1>..<常量2>  下界和上界必须是同一顺序类型,并且上界序号大于下界
type letter='a'..'b';
      var ch1,ch2:letter;
表号声明语句和goto语句:
label Aa;
var I:integer;
begin
…                  //语句
      if(I=0) then goto Aa;
         …               //语句
Aa:begin
         …               //语句
         end;
end;
集合:
set of<基类型>基类型可以是任意顺序类型,但不能是整型、实型或其他构造类型
值:[1,2,3]可以为空,次序无关、可重复、可为基类型允许的表达式、不能超过256个
集合只能通过赋值语句
+并 *交 -差 in
记录类型:
包含不同类型相互相关的数据
定义:
 record
  <域名1>:<类型1>;
  <域名n>:<类型n>;
 end;
开域语句:
                with<记录变量名表>do
 <语句>可直接用域名
函数:
函数也遵循先说明后使用的规则,
函数的说明放在调用该函数的程序说明部分
定义:
function<函数名>(<形式参数表>):<类型>;
过程:
分为标准过程(系统内部定义号的)、自定义过程、事件过程
需要先定义后调用。函数一般用于求值,而过程一般实现某些操作
procedure <过程名> (<形式参数表>);
形参表格式形式如下:
[var] 变量名表:类型; …; [var] 变量名表:类型。
其中带 var 的称为变量形参,不带 var 的称为值形参。在函数中,形参
一般都是值形参,很少用变量形参(但可以使用)。
函数中使用形参,值传递    过程中使用变参,地址传递
子程序的调用规则:
向内层调用,不能隔层调,只能调相邻层
内层可以调外层,并且可以隔层调用
同层后定义可以调用先定义,调后定义需要forward
全程量:
全程量是指在主程序的说明部分中说明的量。全程量的作用域分两种情况:
①当全程量和局部量不同名时, 其作用域是整个程序范围(自定义起直
到主程序结束)。
②当全程量和局部量同名时,全程量的作用域不包含局部量的作用域
动态数据类型:
指针类型:可以方便高效地增加或删除数据
指针变量(也称动态变量)存放某个存储单元的地址; 也就是说指针变量指示某个存储单元
格式:^基类型  类型可以是除指针、文件外的所有类型
type pointer=^Integer;
var p1,p2:pointer;
③pascal 规定所有类型都必须先定义后使用, 但只有在定义指针类型时
可以例外,如下列定义是合法的:
type pointer=^rec;
 rec=record
  a:integer;
  b:char
 end
指针变量的赋值:
<指针变量名>:=@<标识符> @用于获取操作数的内存地址,@后面的操作数可以是变量、过程和函数等。
无类型指针:<指针变量名>:Pointer;无类型的指针的作用是它可以指向任何类型 ,对于无类型指针,不能用指针变量符号后加^的形式来引用它的动态变量。

开辟动态存储单元:
new(指针变量)   系统自动开辟存储单元把地址赋给指针变量
dispose(指针变量) 释放所指向的存储单元
引用动态存储单元  <指针变量>^
对指针变量的操作:
相互赋值
p1:=ni1 指针的值为空
比较运算
GetMem(<指针变量名>,<区域大小>);
FreeMem(<指针变量名>);
利用指针构建链表结构:
type pointer=^ rec;
 rec=record
  data: integer;
  next:pointer;
 end;
var head:pointer;
插入:
New(m);
read(m^.data);
m^.next:=q;
p^.next:=m;
删除:
q^.next:=p^.next;
dispose(p);
文件:
分为:文本文件、有类型文件、无类型文件
适用于各种文件的操作:
1、文件变量与外部文件建立联系
procedure AssignFile(var F;FileName:string);
2、文件变量与外部文件中断联系
procedure ClsoeFile(var F);
3、以读方式打开文件(Reset)
procedure Reset(var F[:File;RecSize:Word]);文件不存在会报错
4、以写方式打开文件(Rewrite)
procedure Rewrite(var F:File[;Recsize:Word]);创建并打开新文件
5、删除文件procedure Erase(var F);
适用于文本文件的操作:
本文件由若干行组成, 行与行之间用行结束标记隔开, 文件末尾有一个文件结束标记
只能顺序地处理文本文件, 而且不能对一文本文件同时进行输入和输出
自动转换功能
文本文件的每一个元素均为字符型,但在将文件元素读入到一个变量
(整型, 实型或字符串型) 中时, Pascal 会自动将其转换为与变量相同的数据类
型。与此相反在将一个变量写入文本文件时,也会自动转移为字符型
1、以添加方式打开文件(Append)
Procedure Append(var F:Text);打开已存在的文件
2、用Read过程读取数据
procedure Read([var F:Text;]V1[,V2,…,Vn]);
3、用Readln过程读取数据。
procedure Readln([var F:Text;]V1[,V2,…,Vn]);
4、用Write过程写入数据。
procedure Write([var F:Text;]P1[,P2,…,Pn]);
5、用Writeln过程写入数据
procedure Writeln([var F:Text;]P1[,P2,…,Pn]);
有类型文件:
有类型文件是一种具有一定数据类型的文件,它是由指定数据组成,读写过程所操作对象的单位是一个指定类型的数据
二进制格式存贮
访问既可以顺序方式也可以用随机方式
声明:
Type fileTypeName=file of  type
1、有类型文件的读取和写入方法
允许同时为读和写打开
procedure  Read(F,V1[,V2,…,Vn]);
procedure  Write(F,V1,…,Vn);
无类型文件:
数据直接在磁盘文件和变量之间传输, 省去了文件缓解区, 因此比其它文件少占内存,主要用来直接访问固定长元素的任意磁盘文件
无类型文件无固定的数据结构,可由使用者决定每个数据记录的长度
Var DataFiel:file;
在对无类型文件用Reset和Rewrite过程打开时,可带有第二个参数,用来说明数据记录的长度,如果默认则为128B
读写:
procdure BlockRead(var F:File;var Buf;Count:Integer[;var AmtTransferred:Integer]);
procdure BlockWrite(var F:File;var Buf;Count:Integer[;var AmtTransferred:Integer]);
buf:存储数据  count:每次读写记录个数 amttransferred:实际读写的记录个数
文本文件的定义:
var F1,F2:text;
和外部文件建立联系:
ASSIGN(F1,`FILEIN.DAT`)
打开文件
REWRITE(f);创建并打开新文件
Append(f);打开已存在的文件
对文件进行写操作:
WRITE(f, <项目名>)
WRITELN(f, <项目名>)
关闭文件:
CLOSE(f);
读文本文件:
READ(f, <变量名表>) READLN(f, <变量名表>);
EOLN(f):回送行结束符
EOF(f):回送文件结束符
面向对象基础:
单元:
一个可供使用的各种标准程序、子程序、文件以及它们的目录等信息的有序集合
引用单元 uses+单元
{$}
@运算符放在变量前面将获取变量的地址
b:byte(c);强制转换  当两个变量数据长度一样时才能强制类型转换
类的定义:
构建类的实例:Worker:= Tworker.Create;
释放对象:Worker.Free;
类成员有三类:Field(字段)、Method(方法)、property(特性)
方法的声明:
Procedure  (方法名)([<参数表>]);
Function  (方法名)([<参数表>]):<返回值类型>;
方法可分为4种类型,分别是构造、析构、过程和函数,它们分别用Constuctor、Destructor、Procedure、Function这4个符号来声明。
构造:
Constructor<构造名>([<参数表>]);
构造名可以是任何合法的标识符,不过按照Delphi的习惯,构造名常使用Create
一般方法只能在对象实例中引用,而构造既可以由一个对象实例引用,也可以直接由类来引用。
析构的声明格式为:
Destructor<析构名>([<参数表>]);
按照习惯,析构名常使用Destroy
析构的作用跟构造正相反,它用于删除对象并指定删除对象时的动作,通常是释放对象所占用的堆和先前占用的其他资源

type
  TForm1 = class//T开头表示类
    Name: String;
    Age: Integer;
    Constructor Create();
    procedure Button1Click(Sender: TObject);
  end;
Constructor Create();
begin
Name:='myself';
Age:=20;
End;
Aman:=Tmember.Create();//为对象分配内存并初始化
Aman.Free;//释放资源  不要直接调用Destroy() Free()首选进行检查保证这个对象实例不为NIL,然后调用对象的析构方法Destroy()。
所有定义的类派生自Tobject类
TForm1 = class(TForm)//括号后面是父类  继承的写法
存取控制符:
public:关键字public后面声明全是公有类型,直到遇到另一种存取控制符
private
protected
published:设计和运行期间都可以访问,权限最高
automated:和public基本相同,区别在会生成OLE自动化操作的类型信息
静态方法:
除非特别指明,否则声明的方法都是静态方法,好处是启动速度快,派生类访问同一个静态方法的地址,不能重载
如果你在派生类定义一个与祖先类相同名的静态方法,派生类的静态方法只是替换祖先类的静态方法
虚拟方法:地址在允许其由定义方法的对象来寻址
在声明后面加virtual,派生类修改父类仍可以使用,VMT虚拟方法表:保存着类类型的所有虚拟方法地址。
声明结尾加overide重写
动态方法:不进VMT,由编译器给它一个索引号  加Dynamic
消息句柄方法:在方法定义时加上一个message指令字,就可以定义一个消息句柄方法。消息句柄方法主要用于响应并处理某个特定的事件
抽象方法:
首先必须是虚拟的或动态的,其次它只有声明而没有定义,只能在派生类中定义它(重载)
Procedure <方法名>([<参数表>]);Virtual/dyname;abstract;
Function <方法名)([<参数表>]);Virtual/dyname;abstract;
重载方法:override
只有在祖先类中定义对象方法为虚拟后,才能进行重载。否则,对于静态对象方法,没有办法激活滞后联编,只有改变祖先类的代码
重载虚拟方法,必须指定相同的参数并使用保留字override。
重定义方法:overload
对象可以有多个同名的方法,这些方法被称为重新定义的方法(Overload)。
为重新定义静态对象方法,用户只需向子类添加该对象方法,它的参数可以与原来方法的参数相同或不同,而不需要其他特殊的标志。
重载override和重定义overload区别:
静态不能重载   可以重定义
抽象才能重载
重载参数相同   重定义参数可以相同或不同
需要保留字override 不需要其他特殊标志
抽象类Abstract:派生类必须实现抽象方法,否则也是抽象类无法实例化
类的特性:
声明特性:特性名、特性的数据类型、读写特性值的方法
Property <特性名>:<类型>read<字段名>/<方法名> Write<字段名>/<方法名>;
特性限定符:Read,write,Stored和Default
Read限定符:
Read <字段名>/<方法名>
Wrire限定符:
Write <字段名>/<方法名>
Stored限定符:
Storetrue true/false[default<属性缺省值>][nodefault]
特性重载,就是在祖先类中声明的特性,可以在派生类中重新声明,包括改变特性的可见性,重新指定访问方法和存储限定符以及缺省限定符等
Property<特性名>;
类中可以重新定义一个与祖先类具有相同名称的属性,重定义相当于声明了一个新的属性,该属性隐藏了从祖先类中继承的同名属性。属性声明中是否声明了属性类型是区别覆盖与重定义的唯一途径。如果后代类中声明的属性带有类型,那就是重定义。重定义一个属性必需给出完整的定义。
不管在后代类中是通过重定义隐藏还是覆盖祖先类中的属性,属性的调用总是静态的。
VCL:
可视化组件库
该组件库是一个类库,包含了在Delphi程序设计中所用到的几乎所有的组件类结构
Tobject类是所有其他类的祖先
TPersistent是Tobject类的直接派生类,该类是一个抽象类,主要为它的继承者提供对流的读写能力
TPersistent类的直接派生类,该类是VCL中所有组件类的祖先类。该类定义了所有组件最基本的属性、方法和事件。该组件类中包含可视的和不可视的组件
TControl直接派生于TComponent类,该类是所有在运行时可见的组件类的祖先类,该类中封装了可见组件的运行位置等信息
异常基类:Exception  Exception类则继承自TObject类,它们全都定义于【Sysutils】
异常类其标识符的第一个字母都是“E”
有两个基本属性:
1、Exception.HelpContext
Type ThelpContext= -MaxLongint..MaxLongint;
Property HelpContext:ThelpContext;
它提供了与异常对象联系在一起的上下文相关帮助信息的序列号。该序列号决定当发生异常时用户按F1键显示的一个异常错误的帮助信息。
2、Exception.Message
property Message: string
该属性存储异常发生时的错误信息。可以通过该属性在提示错误对话框中显示错误信息字符串。
方法:
1、Exception.Create方法
Constructor Create(Const Msg: String);
2、Exception.CreateFmt
Constructor CreateFmt(Const Msg:String;Const Args:Array of Const)
带有格式化字符串提示信息的对话框
3、Exception.CreatHelp
Constructor CreateHelp(Const Msg:String; AhelpContsxt:Integer) ;
该方法产生一个带有一条简单提示信息和上下文帮助序列号的提示对话框

异常控制语句:
try
    语句1;
except
on   异常情况1 do 处理语句1;
on   异常情况n do 处理语句n;
else
处理语句;
end;
try
语句块1
finally
语句块2
end.
串口通信:
常用的PC机都配置了RS-232C标准接口
串行通信接口基本功能是:在发送时,把CPU送来的并行码转换成串行码,逐位地依次发送出去;在接收时,把发送过来的串行码逐位地接收,组装成并行码,并行地发送给CPU去处理。这种串行到并行转换的功能,常用硬件电路来实现,这种硬件电路叫做串行通信接口。
普通的Modem通常都是通过RS-232C串行口信号线与计算机连接
个人计算机的RS-232C接口名称有多个:RS-232C口、串口、通信口、COM口、异步口等

猜你喜欢

转载自www.cnblogs.com/jungledove/p/11947358.html