zoukankan      html  css  js  c++  java
  • Delphi / Pascal 语法知识干货

    ********************************************
    * Pascal、Delph干货 *
    ********************************************

    一、Pascal与Delphi
    Delphi 中是使用的是面向对象的Pascal编程语言

    二、Pascal编码
    1.注释:
    Pascal中的代码注释:{content}、(* content *)
    Delphi中也支持C++注释: //content

    2.大小写问题:
    Pascal中不区分大小写

    3.Pascal运算符
    @ 取变量地址(返回一个指针)
    not 逻辑取反或按位取反
    / 浮点数相除
    div 整数相除
    shl 按位左移
    shr 按位右移
    = 判断是否相等
    <> 判断是否不相等
    in 判断是否是集合成员
    is 判断对象是否类型兼容(又一个RTTI运算符)

    4.变量(Pascal中变量是先声明在使用,和C系列语系一致)
    变量声明:
    var
    Value: Integer;
    i,j: Char;
    IsCorrect: Boolean;

    变量简单赋值:
    Value := 10;
    IsCorrect := True;

    Delphi语法:
    全程变量://下面这种只能用于全程变量,不能用于过程或方法的变量。
    var
    Value: Integer = 10;
    Correct: Boolean = True;
    5.常量
    Pascal语法:
    const
    Thousand = 1000;
    Pi = 3.14;
    AuthorName = 'Marco Canto';
    (* 上面这些常量编译器会做一个隐式转换 *)
    Delphi语法:
    const
    Thousand: Integer = 1000;
    6.资源串(字符串)常量
    Delphi 3 之前:
    const
    AuthorName = 'Marco canto'

    Delphi 3 之后:
    resourcestring
    AuthorName = 'Marco Canto';
    BookName = 'Essential Pascal';
    7.数据类型
    Pascal:有序数据、实数、字符串类型
    Delphi:在Pascal之上多一种 无类型可变数据类型(variant)

    三、自定义数据类型
    1.命名及不命名的类型
    type //type代码区
    ……
    end
    2.子界类型(subRange)
    type
    Ten = 1..10;
    OverHundred = 100..1000;
    Uppercase = 'A'..'Z';
    3.枚举类型
    type
    Color = (Red,Yello,Green,Cyan,Blue,Violet);
    4.集合类型
    type
    Letters = set of Uppercase;

    用上面定义的类型定义变量
    var
    Letters1,Letters2,Letters3: Letters;
    begin
    Letters1 := ['A','B','C'];
    Letters2 := ['K'];
    Letters3 := [];
    5.数组类型
    type
    DayTemperatures = array [1..24] of Integer;
    var
    DayTemp1: Daytemperatures;
    procedure AssignTemp;
    begin
    DayTemp1 [1] := 54;
    DayTemp1 [2] := 52;
    ...
    DayTemp1 [23] := 64;
    DayTemp1 [24] := 60;//这里不要越界哟!语法和C/C++ 语法差不多,不是不能访问编译器不允许我们这么做,这是非法访问内存

    多维数组:
    type
    MonthTemps = array [1..24,1..31] of Integer;
    YearTemps = array[1..24,1..31,Jan..Dec] of Integer;
    var
    ThisYear: YearTemps;
    begin
    ...
    ThisYear[Feb] := ThisYear[Jan];
    6.记录类型(这个类型就和C语言体系中Struct 是一致的)
    type
    Date = record
    Year: Integer;
    Month: Byte;
    Day: Byte;
    end;
    var
    BirthDay: Date;
    begin
    BirthDay.Year := 1997;
    BirthDay.Month := 2;
    BirthDay.Day := 14;

    7.指针(C(C++)中*(指针),&(取地址) Pascal(Delphi)中 ^(指针),@(取地址))
    type
    PointerToInt = ^Integer;
    var
    P: ^Integer;
    X: Integer;
    begin
    P := @X; //P->X 指针P指向X 这块儿内存
    X := 10;
    P^ := 20;//注意,这里的和C中解地址的书写方式不一样,C(C++)语言中*在变量名之前,Pascal(Delphi)中^在变量名之后
    8.文件类型
    type
    IntFile = file of Integer;//这里就是C语言中的文件描述符(int) 只是方便文件的查找,文件的管理
    注意:
    Pascal 文件类型的使用很直观,而且Delphi 中也定义了一些控件用于文件保存和装载,以及对数据流和数据库的支持。

    四、语句
    1.简单语句与复合语句
    X := Y + Z;
    A := B;
    2.赋值语句
    A := 10;
    3.条件语句
    if 语句 -> if 语句可以嵌套
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    if CheckBox1.Checked then
    ShowMessage ('CheckBox1 is checked')
    else
    ShowMessage ('CheckBox2 is not checked');
    end;

    case语句
    case Number of
    1: Text := 'One';
    2: Text := 'Two';
    3: Text := 'Three';
    end;

    case MyChar of
    '+' : Text := 'Plus sign';
    '-' : Text := 'Minus sign';
    '*','/' : Text := 'Multiplication or division';
    '0'..'9' : Text := 'Number';
    'a'..'z' : Text := 'Lowercase character';
    'A'..'Z' : Text := 'Uppercase character';
    else
    Text := 'Unknown character';
    end;

    五、循环语句
    1.for 循环
    for ... to ... do 语句
    var
    K,I:Integer;
    begin
    K := 0;
    for I := 1 to 10 do
    K := K + I;

    for ... downto ... do 语句
    var
    K, I: Integer;
    begin
    K := 0;
    for I := 10 downto 1 do
    K := K + I;

    2.while 和 repeat-until(C 语言中 do{} while) 语句(这两者差别不大)
    while (I <= 100) and (J <= 100) do
    begin
    // use I and J to compute something...
    I := I + 1;
    J := J + 1;
    end;

    repeat //该语句至少做一次操作
    // use I and J to compute something ...
    I := I + 1;
    J := J + 1;
    until (I > 100) or (J > 100);

    3.with 语句
    With语句是一种用于简化代码的语句。 如你要访问一个记录类型变量(或一个对象),用With语句就不必每次重复变量的名字。例如对于以下的记录类型代码:

    type
    Date = record
    Year: Integer;
    Month: Byte;
    Day: Byte;
    end;

    var
    BirthDay: Date;

    begin
    BirthDay.Year := 1997;
    BirthDay.Month := 2;
    BirthDay.Day := 14;

    可以用with语句改进后半部分代码,如下:

    begin
    with BirthDay do
    begin
    Year := 1995;
    Month := 2;
    Day := 14;
    end;

    六、Pascal 过程与函数
    1.过程与函数:
    Pascal中的例程有两种形式:过程和函数。理论上说,过程是你要求计算机执行的操作,函数是能返回值的计算。两者突出的不同点在于:函数能返回计算结果,即有一个返回值,而过程没有。两种类型的例程都可以带多个给定类型的参数。

    不过实际上函数和过程差别不大,因为你可以调用函数完成一系列操作,跳过其返回值(用可选的出错代码或类似的东西代替返回值);也可以通过过程的参数传递计算结果(这种参数称为引用,下一部分会讲到)。

    下例定义了一个过程、两个函数,两个函数的语法略有不同,结果是完全相同的。

    procedure Hello;
    begin
    ShowMessage ('Hello world!');
    end;

    function Double (Value: Integer) : Integer;
    begin
    Double := Value * 2;
    end;

    // or, as an alternative
    function Double2 (Value: Integer) : Integer;
    begin
    Result := Value * 2;
    end;
    流行的做法是用Result 给函数赋返回值,而不是用函数名,我认为这样的代码更易读。

    一旦定义了这些例程,你就可以多次调用,其中调用过程可执行操作;调用函数能计算返回值。如下:

    procedure TForm1.Button1Click (Sender: TObject);
    begin
    Hello;
    end;

    procedure TForm1.Button2Click (Sender: TObject);
    var
    X, Y: Integer;
    begin
    X := Double (StrToInt (Edit1.Text));
    Y := Double (X);
    ShowMessage (IntToStr (Y));
    end;

    2.引用参数
    Pascal 例程的传递参数可以是值参也可以是引用参数。值参传递是缺省的参数传递方式:即将值参的拷贝压入栈中,例程使用、操纵的是栈中的拷贝值,不是原始值。

    当通过引用传递参数时,没有按正常方式把参数值的拷贝压栈(避免拷贝值压栈一般能加快程序执行速度),而是直接引用参数原始值,例程中的代码也同样访问原始值,这样就能在过程或函数中改变参数的值。引用参数用关键字var 标示。

    参数引用技术在大多数编程语言中都有,C语言中虽没有,但C++中引入了该技术。在C++中,用符号 &表示引用;在VB中,没有ByVal 标示的参数都为引用。

    下面是利用引用传递参数的例子,引用参数用var关键字标示:

    procedure DoubleTheValue (var Value: Integer);
    begin
    Value := Value * 2;
    end;
    在这种情况下,参数既把一个值传递给过程,又把新值返回给调用过程的代码。当你执行完以下代码时:

    var
    X: Integer;
    begin
    X := 10;
    DoubleTheValue (X);
    x变量的值变成了20,因为过程通过引用访问了X的原始存储单元,由此改变了X的初始值。

    3.常量参数
    除了引用参数外,还有一种参数叫常量参数。由于不允许在例程中给常量参数赋新值,因此编译器能优化常参的传递过程。编译器会选用一种与引用参数相似的方法编译常参(C++术语中的常量引用),但是从表面上看常参又与值参相似,因为常参初始值不受例程的影响。

    事实上,如果编译下面有点可笑的代码,Delphi将出现错误:

    function DoubleTheValue (const Value: Integer): Integer;
    begin
    Value := Value * 2; // compiler error,const 修饰Value 该变量就不能再被修改
    Result := Value;
    end;


    4.开放数组参数
    与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;

    上面通过High(A)获取数组的大小,注意其中函数返回值 Result的应用, Result用来存储临时值。你可通过一个整数表达式组成的数组来调用该函数:

    X := Sum ([10, Y, 27*I]);

    5.Delphi 调用协定
    32位的Delphi 中增加了新的参数传递方法,这里的调用协定 和Win32 中stdcall或者callback 类似

    6.Forward 声明(函数声明)

    当使用一个标识符(任何类型)时,编译器必须已经知道该标识符指的是什么。为此,你通常需要在例程使用之前提供一个完整的声明。然而在某些情况下可能做不到这一点,例如过程A调用过程B,而过程B又调用过程A,那么你写过程代码时,不得不调用编译器尚未看到其声明的例程。

    欲声明一个过程或函数,而且只给出它的名字和参数,不列出其实现代码,需要在句尾加forward 关键字:

    procedure Hello; forward;

    7. 方法(类中的过程或函数)

    8. 函数重载
    重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同。实际上,编译器是通过检测参数来确定需要调用的例程。

    下面是从VCL的数学单元(Math Unit)中摘录的一系列函数:

    function Min (A,B: Integer): Integer; overload;
    function Min (A,B: Int64): Int64; overload;
    function Min (A,B: Single): Single; overload;
    function Min (A,B: Double): Double; overload;
    function Min (A,B: Extended): Extended; overload;
    当调用方式为Min (10, 20)时,编译器很容易就能判定你调用的是上列第一个函数,因此返回值也是个整数。

    声明重载函数有两条原则:

    每个例程声明后面必须添加overload 关键字。
    例程间的参数个数或(和)参数类型必须不同,返回值不能用于区分各例程。

    9.缺省参数
    Delphi 4 中添加了一个新功能,即允许你给函数的参数设定确省值,这样调用函数时该参数可以加上,也可以省略。下例把应用程序全程对象的MessageBox 方法重新包装了一下,用PChar 替代字符串,并设定两个确省值:

    procedure MessBox (Msg: string;
    Caption: string = 'Warning';
    Flags: LongInt = mb_OK or mb_IconHand);
    begin
    Application.MessageBox (PChar (Msg),
    PChar (Caption), Flags);
    end;
    使用这一定义,你就可以用下面任一种方式调用过程:

    MessBox ('Something wrong here!');
    MessBox ('Something wrong here!', 'Attention');
    MessBox ('Hello', 'Message', mb_OK);


    七、字符串操作

    1.字符串有char、string 和 wchar、String(长字符串)
    2.格式化字符串
    Format('First %d,Second %d',[n1,n2]); //占位符%d
    Format('%8d',[n1]); //该句把数字你n1转换成有8个字符的字符串,并通过填充空白使文本右对齐(+),左对齐(-)
    Pascal 中 Format函数的占位符
    d,x,s,g ...

    八、内存

    1.Delphi 4 动态数组
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Array1: array of Integer;
    begin
    Array1 [1] := 100; // error
    SetLength (Array1, 100);
    Array1 [99] := 100; // OK
    ...
    end;


    九、Windows 编程
    在此模块采用Window(窗口化)编程可以避免一些VCL库一些错误,所以当有必要的时候可以采用 此模块进行绕开技术

    十、程序和单元
    1.单元(unit)
    unit Unit1;

    interface

    implementation

    end.
    单元的概念比较简单,单元名与文件名相同,而且必须唯一。单元包括界面区(interface)及实现区(implementation),界面区用于声明其它单元能看到的部分;实现区存放界面的实现代码及外部不可见的声明。此外还有两个可选的区,即初始化区及结束区,其中初始化区存放初始化代码,当程序加载到内存时执行;结束区存放程序终止时执行的代码。

    单元总体结构如下:

    unit unitName;

    interface

    // other units we need to refer to
    uses //需要访问的外部单元
    A, B, C;

    // exported type definition
    type
    newType = TypeDefinition;

    // exported constants
    const
    Zero = 0;

    // global variables
    var
    Total: Integer;

    // list of exported functions and procedures
    procedure MyProc;

    implementation

    uses
    D, E;

    // hidden global variable
    var
    PartialTotal: Integer;

    // all the exported functions must be coded
    procedure MyProc;
    begin
    // ... code of procedure MyProc
    end;

    initialization
    // optional initialization part

    finalization
    // optional clean-up code

    end.

  • 相关阅读:
    宏任务、微任务
    类和模块
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
  • 原文地址:https://www.cnblogs.com/Kernel001/p/8253052.html
Copyright © 2011-2022 走看看