如何將C 程式轉為Pascal語法:(下集)
原文出處: by Paul Fulford of Komodo Software
翻譯:http://delphi.ktop.com.tw 將C 轉為 Pascal/Delphi
==============================
目錄
part I(上集)
概論
資料型態
關鍵字
敘述結尾
變數宣告
字串
陣列
數值的指定與比較
常數宣告
函數與程序
with ... do敘述
註解
流程控制
part II(下集)
物件導向結構
Containers
例外處理
資料流(Streaming)
專案檔的設計
如何轉換
結論 =================================
物件導向結構 C 與OP都可稱為是物件導向式的語言.
C 可以用多重繼承(multiple inheritance),OP只能單一繼承(single inheritance) 讓我們來看看建立物件的基本語法:
C
Classes必須定義在header檔中...
class LoanC // 未有繼承時
{
private: // 內定為private
...
protected: // 要有冒號
...
public:
...
}; //分號結尾
在C 中單一繼承的語法如下:
class B: A
{...};
在C 中多重繼承的語法如下:
class D: A, B, C
{...};
classes繼承物件時可標明public, protected, 或 private.
內定是為 private
class D: public A, public B, private C
{...};
OP
Classes是在unit/file中的 "type" 結構中宣告...
type
LoanC = class(TObject)
{這表是從TObject繼承下來. }
{此處不用 "begin" 指令}
private
...
protected {此處不用冒號}
...
public
...
published
...
end;
關鍵字 private, protected, public, 及 published (只有OP有) 指明了
每一個資料元素的資料範圍寬廣.
private:只能給在Class內部使用
protected:只能給這個Class或演生的Class使用
public:可以在程式所有的地方使用
Published:Delphi專用,用來建立介面 每一個Class需要一個建立者(constructor) 在C 理,建立者與class同名. 建立者可加參數:
ie:
LoanC(); // 無參數
LoanC(double &dCurrentBal); // 一個參數
LoanC(double &dBalOne, double &dBalTwo); // 兩個參數
在OP理,建立者與class不同名.
ie:
constructor MyLoanOne; {no parameters}
constructor MyLoanTwo(var dCurrentBal: double);
constructor MyLoanThree(var dBalOne, dBalTwo: double); C 與OP都提供解構者(destructors),也可稱為釋放記憶體(free memory) 在C 理, 解構者與建構者一樣,與class同名.
如:
~LoanC(); // C destructor
在OP理, 解構者與class不同名.
如:
destructor LoanC.Destroy;
begin
oLoanDate.Free;
...
inherited Destroy; {"inherited" is a keyword}
end; 建立一個新物件,宣告一個變數:
double dAmount = 1515.75;
LoanC oMyLoan(dAmount);
如此做會配置一塊記憶體,
如果用只標方式可以如下宣告:
double dAmount = 1515.75;
LoanC * poMyLoan = new LoanC(dAmount); 在OP理則不同,每一個都是指標.
var
dAmount: double;
oMyLoan: LoanC;
begin
{oMyLoan does not yet exist!}
dAmount := 1515.75;
oMyLoan := LoanC.MyLoanTwo(dAmount); {now it does} 在OP理也可也 Override.
type
LoanC = class
...
constructor Create; {overrides TObject's Create}
...
end;
... and call the inherited Create constructor in the LoanC definition...
constructor LoanC.Create;
begin
inherited Create; {calls TObject's Create}
...
end;
C 與OP理引用內部元素採用如下語法:
oMyLoan.dPrincipal;
在C 中,使用指標引用內部元素採用如下語法:
poMyLoan->dPrincipal; 在C 中有三個運算子:
1. & 取位址
2. * 取指標
3. -> 印用元素
在OP中都用.(逗點號) =================================
Containers C :Containers
typedef TISetAsVector tdCompanySet;
typedef TISetAsVectorIterator tdCSetIter;
...
int OwlMain(int, char*[])
{...
tdCompanySet oCompColl;
...
}
...
void MainForm::AddNewCompany()
{
CompanyC * poC = new CompanyC;
oCompColl.Add(new CompanyC(poC));
...
// now iterate
tdCSetIter oCIter(oCompColl);
while(oCIter)
{
poC = oCIter ;
// now use poC
...
}
} OP:Containers
TMainForm = class(TForm)
...
public
oCompColl: TList;
...
end;
...
procedure TMainForm.AddNewCompany;
var
poC: CompanyC;
iCount: integer;
begin
poC := CompanyC.Create;
...
oCompColl.Add(poC);
...
{now iterate}
for iCount := 0 to oCompColl.Count - 1 do
begin
poC := oCompColl.Items[iCount];
{now use poC}
...
end;
=================================
例外處理 C :例外處理
try
{
...
}
catch()
{
...
}
catch(...)
{
...
}
OP:例外處理
try
{不用 begin ... end; 指令}
...
finally
{例外處理}
...
end;
取得Run Time 錯誤訊息時:
try
...
except
on do ... ;
end;
=================================
資料流(Streaming) C :資料流
class CompanyC
{
...
friend ofstream & operator <<(ofstream &oS, CompanyC * poC);
...
};
...
friend ofstream & operator <<(ofstream &oS, CompanyC * poC)
{
oS << poC->dVersion
<< poC->dLastDivPerShare
<< poC->enIndustry
...
<< poC->sName;
return oS;
} friend ofstream & operator <<(ofstream &oS, CompanyC * poC)
{
oS.write( (char*) & (*poC), sizeof(*poC));
return oS;
} // 打開 a stream
ofstream ofS("gamedata.gam");
if(!ofS)
return;
...
// 存檔
tdCSetIter oCIter(oCompColl); // see container section
while(oCIter)
{
poC = oCIter;
ofS << poC;
}
ofS.close();
OP:資料流
type
CompanyC = class
public
procedure Read(var f:file);
procedure Write(var f:file);
...
end;
...
procedure CompanyC.Write(var f:file);
begin
BlockWrite(f, dVersion, sizeof(dVersion));
BlockWrite(f, dLastDivPerShare, sizeof(dLastDivPerShare));
BlockWrite(f, enIndustry, sizeof(enIndustry));
...
BlockWrite(f, sName, sizeof(sName));
end;
開檔:
procedure TMainForm.FileSaveItemClick(Sender: TObject);
var
oGameFile: file;
iCount: integer;
poC: CompanyC;
sNameFile: string[13];
begin
...
sNameFile := 'gamedata.gam';
AssignFile(oGameFile, sFileName);
Rewrite(oGameFile, 1); {the 1 means 1 byte at a time}
...
for iCount := 0 to oCompColl.Count - 1 do
begin
poC := oCompColl.Items[iCount];
poC.Write(oGameFile);
end;
CloseFile(oGameFile);
end;
=================================
專案檔的設計 在 C 中,常數定義放在.h檔中,程式放在.cpp中(會用#include .h檔) 在 Delphi中,常數定義與程式都在一個檔.pas中
不同的.pas可用uses指令引用別的.pas宣告個變數 =================================
如何轉換 如果要轉有畫面的C 程式要比轉無畫面的C 程式困難的多. 如果要轉有畫面的C 程式,要先在Dlephi開一Form,再將c 的程式碼轉入. 要將程式copy 至delphi中再來改. 1) 先整體性的轉換 ,將 C 的{...} 改為 begin...end;
double CompanyC::NewAnnualReport_v(Economy & oE)
{ ... // delimiter starts on a new line
}
...versus this...
double CompanyC::NewAnnualReport_v(Economy & oE){ // delimiter at end of line
...
}
2) a) 將 C 的 || 轉為 "or"
b) 將 C 的 && 轉為 "and"
c) (1)將 C 的 == 轉為 =
(2)將 C 的 = 轉為 :=
d) 將 C 的 /* */ 轉為 { }
e) C 的 // 不用轉
f) 將 雙引號轉為單引號 " -> '
3) C 的每個if要加 then
如:
C
if(oE.enDirection == Up &&
oE.uNumMosUpYr >= oE.uNumMosDownYr)
{
...
}
OP
if (oE.enDirection = Up) and
(oE.iNumMosUpYr >= oE.iNumMosDownYr) then
begin
...
end;
4) 將控制指令修改
5) C 的 overloaded 運算可 re-written,那就看您在OP中要如何處理. 6) 將 C 的 :: 轉為 .
procedure TForm1.Memo1Change(Sender: TObject); {要加上分號}
begin
...
end; 7) 將 C 的 和 decrement -- 改為inc(x) 與dec( 8) 將C 在區塊 中宣告的變數全部移到var區中. 9) 將C 的函數名稱前加上 "function" 或 "procedure" 10) 將 C 的 -> 轉為 . (句點)
DateC oBirthDate;
var
oBirthDate: DateC;
begin
oBirthDate := DateC.Create; 11) 將 C 的strcpy(...) 與 strcat(...) 轉為 := 與
12) 那多重繼承呢?( multiple inheritance).
用Class B繼承Class A,再用class C繼承 B的方式 . =================================
結論 C 是簡短的語言, 而 OP 比較像英文. 然而C 較緊密,但不易閱讀. ============完結=============
~~~Delphi K.Top討論區站長~~~