如何將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 與Object Pascal的不同
也讓您能夠有能力將C 轉為Object Pascal(以下稱為OP) =================================
資料型態 這一章可學到如何將 C 的資料型態 轉成 OP 的資料型態.
變數宣告時可參考下列對照表 C OP 大小 (bytes) 值範圍
================ ========== ============== ==========================
char ---- 1 -128 to 127
---- char 1 1 ASCII character
int integer 2 -32,768 to 32,767
short ---- 2 -32,768 to 32,767
---- shortint 1 -128 to 127
long longint 4 -2,147,483,647 to 2,147,483,647
unsigned char byte 1 0 to 255
unsigned int word 2 0 to 65,535
unsigned short word 2 0 to 65,535
unsigned long ---- 4 0 to 4,294,967,295
float single 4 3.4E-38 TO 3.4E 38
double double 8 1.7E-308 TO 1.7E 308
long double extended 10 3.4E-4932 TO 3.4E 4932
---- comp 8 1.7E-308 TO 1.7E 308
---- real (for backwards compatibility only -- use double)
void pointer 8 n/a -- an untyped pointer
---- boolean 1 True or False
(C may soon have a boolean type)
String ---- a C standard object
---- string an array of up to 255 ASCII characters
---- PChar pointer to a null-terminated string
================ ========== ============== ==========================
=================================
關鍵字 C 有 59 個關鍵字, OP 有 60 個關鍵字. This does not include the many vendor
C 大小寫有分 OP 大小寫不分
C 的關鍵字
asm auto break case catch cdecl char class const const_cast continue
default delete do double dynamic_cast else enum extern far float for
friend goto huge if inline interrupt int near new operator pascal private
protected public register reinterpret_cast return short signed sizeof
static static_cast struct switch template this throw try typedef typeid
union unsigned virtual void volatile wchar_t while OP的關鍵字
and as asm array begin case class const constructor destructor div do
downto else end except exports file finally for function goto if implementation
in inherited inline initialization interface is label library mod nil not
object of or packed procedure program property raise record repeat set shl
shr string then to try type unit until uses var while with xor =================================
敘述結尾 C 敘述結尾
大部份的敘述都用 ; 號結尾
有一些例外如:
#include
#define MAXNAMELENGTH 35
OP敘述結尾
所有的敘述都用 ; 號結尾 =================================
變數宣告 C 變數宣告
變數名稱只有前32個字有效
變數名稱宣告可在程式的任何地方宣告(當然,宣告後才可用)
// ... 如在程式中宣告
{
char i;
for (i=0;i<10;i )
{
char sName[10]; // 在區塊中也可宣告變數
int iCount, iLoop, iValToReach;
double dMaxLoan, dTotal;
float fMaxRate = 123.875;
}
}
OP變數宣告
變數名稱只有前63個字有效
變數名稱要宣告在var之後,且要在function或procedure開始時宣告
不可在區塊內宣告變數
如:
function PayBack_d(var dAmount: double): double;
var
iCount, iLoop, iValToReach: integer;
dMaxLoan, dTotal, dMaxRate: double;
begin
dMaxRate := 123.875;
{...}
=================================
字串 C 字串
在C 現在也有了字串物件,但並不和以"\0"結束的char相容.
大部份的字串就是char陣列,可以無限長度.
下面是一些char陣列宣告的例子:
char sName[26]; // 25 個chars長
char psDemo[] = "Hello, there!";
char * psDemo = new char[26];
對字串變數最常做的事就是strcpy與strcat
您要確定strcat或strcpy後的長度夠不夠存放.
以下是strcpy/strcat的例子.
class Ticker
{
...
public:
char sBuf[10],
sLatestTrade[TRADELENGTHBUF],
saTradeRecords[50] [TRADELENGTHBUF];
...
void OptnFormat2_v(unsigned long & ulQuantity,
CompanyC * poC,
int & iSeries);
...
};
...
void TickerC::OptnFormat2_v(unsigned long & ulQuantity,
CompanyC * poC,
int & iSeries)
{
ultoa(ulQuantity, sBuf, 10);
strcpy(sLatestTrade, sBuf);
AddMosToString_v(sLatestTrade,
poC->oSOS.oSeries[iSeries].oExpDate.enMonth);
itoa(poC->oSOS.oSeries[iSeries].oExpDate.iDay, sBuf, 10);
strcat(sLatestTrade, sBuf);
strcat(sLatestTrade, poC->oS.sTicker);
double dStrike = poC->oSOS.oSeries[iSeries].dStrike;
gcvt(dStrike, 3, sBuf);
strcat(sLatestTrade, sBuf);
if(poC->oSOS.oSeries[iSeries].enCallPut == Call)
strcat(sLatestTrade, "Calls");
else strcat(sLatestTrade, "Puts");
}
OP字串
Delphi 1.0字串最多255bytes,Delphi 2.0以後無此限.
在OP內的String所佔的記憶空間會比您宣告的大小大.
因為字串為陣列,在陣列[0]放長度.
例:
var
sMyName: string[25]; {最大25字元}
sYourName: string;
begin
sMyName := 'Paul Fulford'; {單引號表字串} 在OP中,您可用:=和 處理字串運算,例:
TickerC = class
...
public
sLatestTrade: string[TRADELENGTHBUF];
saTradeRecords: TStringList;
...
procedure TickerC.OptnFormat2(var lQuantity: longint;
poC: CompanyC;
var iSeries: integer);
...
end;
...
procedure TickerC.OptnFormat2(var lQuantity: longint;
poC: CompanyC;
var iSeries: integer);
begin
sLatestTrade := IntToStr(lQuantity);
AddMosToString(sLatestTrade,
poC.oSOS.oSeries[iSeries].oExpDate.enMonth);
sLatestTrade := sLatestTrade
IntToStr(poC.oSOS.oSeries[iSeries].oExpDate.iDay)
poC.oS.sTicker
FloatToStr(poC.oSOS.oSeries[iSeries].dStrike);
if poC.oSOS.oSeries[iSeries].enCallPut = Call then
sLatestTrade := sLatestTrade 'Calls'
else sLatestTrade := sLatestTrade 'Puts';
end; {OptnFormat2}
您會發現OP處理字串容易得多.
C 中字串以"\0"結尾,OP中陣列[0]放字串長度. =================================
陣列 陣列是資料的一序列排列.
C 與OP的陣列宣告很不同.
但取用方式很像.
C 陣列
陣列從0開始,第一個元素為 [0], 第二個為[1]...類推,初學者要小心
// 宣告 陣列...
DateC aoCANHolidays[SIZE_HOLIDAYARRAY];
double dAverageLast31Days[31];
// 取用陣列
for(int i = 30, j = 29; i > 0; i--,j--)
dAverageLast31Days[i] = dAverageLast31Days[j];
OP陣列
陣列通常從[1]開始,但也不全然.
在Delphi中您也可以發現某些物件也是從[0]開始的.
像TList就是從TList[0]開始,我們要小心看物件的說明文件.
例子:
var
aoCANHolidays: array[1..SIZE_HOLIDAYARRAY] of DateC;
dAverageLast31Days: array[1..31] of double;
i,j: integer;
begin
j := 30;
for i := 31 downto 2 do
begin
dAverageLast31Days[i] = dAverageLast31Days[j];
Dec(j); { or j := j-1; }
end;
兩個語言都可用多維陣列,見下例:
C
double dMatrix[50] [20];
OP
var
dMatrix: array[1..50, 1..20] of double;
=================================
數值的指定與比較 C 數值的指定與比較
比較相等時用 == 號
給定值時用 = 號
如:
if (dMaxRate == 15.75)
{ ...
dMaxRate = 12.5;
...
}
OP數值的指定與比較
比較相等時用 = 號
給定值時用 := 號
如:
if dMaxRate = 15.75 then
begin
...
dMaxRate := 12.5;
...
end; 有一個例外就是OP在Const的值的給定是用=號,如:
const max=100; =================================
常數宣告 常數是無法改變值的,所以一定要在宣告時給值. C 常數宣告
const int iMax = 2000;
const double dMaxValue = 1234.75;
也可用巨集定義常數
#define nMAXAMOUNT 1000
OP常數宣告
function PayBack_d(var dAmount: double): double;
const
iMAX = 2000; {notice value assigned with single equal sign this time}
dMAXVALUE = 1234.75;
var
iCount, iLoop, iValToReach: integer;
dMaxLoan, dTotal, dMaxRate: double;
begin
dMaxRate := dMAXVALUE;
{...} =================================
函數與程序
在C 中所有的Function一定會傳回值.
在OP中function要傳回值,procedure不用
在C 中所有的function一定要()號,就算無參數
在OP中function無參數不用()號 C 函數與程序
例:
double IntSinceLastAddDate_d(double &dAvailCash); // prototype
void SetNewIntRate(); // no parameters or return value
...
double LoanC::IntSinceLastAddDate_d(double &dAvailCash)
{
double dSomething;
...
return dSomething;
}
void LoanC::SetNewIntRate()
{ ... }
OP函數與程序
例:
function IntSinceLastAddDate_d(var dAvailCash: double): double;
procedure SetNewIntRate; {無參數也無傳回值}
...
function LoanC.IntSinceLastAddDate_d(var dAvailCash: double): double;
var
dSomething: double;
begin
...
result := dSomething;
{the global variable "result" is assigned the return value!}
end;
procedure LoanC.SetNewIntRate;
begin
...
end;
兩個語言可以在參數傳遞時採用 pass by valye 或 pass by reference:
C pass by value ... double IntSinceLastAddDate_d(double dAvailCash);
OP pass by value ... function IntSinceLastAddDate_d(dAvailCash: double): double; C pass by reference ... double IntSinceLastAddDate_d(double &dAvailCash);
OP pass by reference ... function IntSinceLastAddDate_d(var dAvailCash: double): double; C pass constant ... double IntSinceLastAddDate_d(const double dAvailCash);
OP pass constant ... function IntSinceLastAddDate_d(const dAvailCash: double): double; =================================
with ... do敘述 C 無 with .. DO敘述 在C 中當您要取用資料時:
poC.oStock.aoTradesLast130Days[0].lVol = 0;
poC.oStock.aoTradesLast130Days[0].dHigh = 0;
poC.oStock.aoTradesLast130Days[0].dLow = 0;
poC.oStock.aoTradesLast130Days[0].dClose = 0; 但在OP中可以簡化成:
with poC.oStock.aoTradesLast130Days[0] do
begin
lVol := 0;
dHigh := 0;
dLow := 0;
dClose := 0;
end;
=================================
註解 C
有兩種
// 雙斜線後為註解
/* 註解 */
OP
有三種
// 雙斜線後為註解
{ 註解 }
(* 註解 *) =================================
流程控制 有五種流程控制指令,C 與OP都有,用法滿像的. ~~~~~~~~~~~~~~~~~~~~~~~~~
1) if ... else 指令
C
if(<邏輯運算式>) // 一定要有()號
{ ...
}
else if(<邏輯運算式>)
{...
}
else
{...
}
OP
if <邏輯運算式> then // 不一定要有()號,因有then
begin
...
end
else if <邏輯運算式> then
begin
....
end
else
begin
...
end; {最後一個end才要加;分號}
~~~~~~~~~~~~~~~~~~~~~~~~~
2) switch/case ... 指令 C
switch()
{
case iX: ... break;
case iY: ... break;
default: ...
}
OP
case of
{no "begin" here}
iX:
begin
...
end; {每個end都要;分號}
iY:
begin
...
end;
else {此處不用;號}
begin
...
end;
end; {這個end要;分號}
~~~~~~~~~~~~~~~~~~~~~~~~~
3) for ... loop 指令 C
for(iCount = 0; iCount <= 10; iCount )
{
// iCount , 每次迴圈值加一
...
break; // 中斷迴圈
continue; // 跳到下一個迴圈
...
}
OP
for iCount := 1 to 10 do
begin
... {iCount每次自動加 1}
break; { 中斷迴圈 }
continue; { 跳至下一個迴圈 }
...
end;
~~~~~~~~~~~~~~~~~~~~~~~~~
4) while ... loop 指令 C
while(<邏輯運算式>)
{
...
break; // 中斷迴圈
continue; // 跳到下一個迴圈
...
}
OP
while <邏輯運算式> do
begin
...
break; { 中斷迴圈 }
continue; { 跳至下一個迴圈 }
...
end; ~~~~~~~~~~~~~~~~~~~~~~~~~
5) do/repeat ... 指令 C
do
{
// 邏輯運算式 False迴圈終止
...
break; // 中斷迴圈
continue; // 跳到下一個迴圈
...
}while(<邏輯運算式>);
OP
repeat
// 邏輯運算式 True迴圈終止
...
break; { 中斷迴圈 }
continue; { 跳至下一個迴圈 }
...
until <邏輯運算式>; =================================
(上集)...待續...