控制語句
語句描述了完成一項任務(wù)的算法操作規(guī)則。程序本身就是由這樣的語句序列組成。各條語句之間以分號(;)分隔開。
一條語句能占一行或多行。二個或更多語句也能書寫于同一行上。控制執(zhí)行順序的語句(if, if-else, switch, while和for)可以相互嵌套。
示例:
if(Month()==12)
if(Day()==31)]
Print("新年快樂!");
語句塊
一個復(fù)合語句(一個語句塊)可以由一條語句組成,也可以由大括弧{}括起來的一條或多條任意類型的語句組成。大括弧{}后而不必跟著分號(;)。
示例:
if(x==0){
Print("無效位置 x=",x);
return;
表達式操作符
任何以分號(;)結(jié)束的表達式都被視為是一個操作符。這里羅列了一些表達式操作符的范例:
賦值運算符:
標(biāo)識符= 表達式;
賦值運算符在表達式操作符中只限一次使用。
示例:
x=3;
y=x=3; // 這是錯誤的
調(diào)用子函數(shù)操作符:
被調(diào)函數(shù)子(形參1,形參2,…,形參N);
示例:
FileClose(文件名)
空操作符
只有一個分號組成(;).我們用它來表示沒有任何表達式的空操作符.
break 語句
該語句可以終止最鄰近的switch, while或for語句的執(zhí)行。 Break語句放在嵌套內(nèi)的指定位置,由上方最近的終止條件語句控制。
目的是 當(dāng)滿足達到一定條件時 完成循環(huán)的執(zhí)行而跳出。
示例:
//--從0開始搜索數(shù)組
for(i=0; i<ARRAY_SIZE; i++)
if((array[i]==0)
break;
continue 語句
該語句放在嵌套內(nèi)的指定位置,continue語句控制最鄰近的循環(huán)語句while或for返回循環(huán)開始,當(dāng)指定條件下跳過接下來的運算,直接跳入下一次的循環(huán)。
(continue 語句與break 語句作用相反。)
示例:
//--統(tǒng)計數(shù)組中非零元素個數(shù)
int func(int array[]){
int array_size= ArraySize(array);
int sum= 0;
for(int i=0; i<array_size; i++){
if(a[i]==0)
continue;
sum += a[i];
}
return(sum);
}
return 語句
return;
結(jié)束當(dāng)前函數(shù)的執(zhí)行,返回到調(diào)用程序。
return(表達式或計算結(jié)果值):
執(zhí)行完當(dāng)前函數(shù)的并帶回函數(shù)的結(jié)果值。其中的表達式必須放在圓括號內(nèi),不能使用賦值號。
示例:
int 求和子(int x, int y){
return(x+y);
}
在函數(shù)值的類型定義為void類型時,return 語句后面不能使用表達式:
void SomeFunction() {
Print("Hello!");
return; // 該句無存在的必要
}
if-else 語句
如果條件表達式為true,語句序列operator1執(zhí)行,語句序列operator2將不執(zhí)行; 如果表達式為false,語句序列operator2執(zhí)行,而語句序列operator1不執(zhí)行。
else后還可以跟進多個if執(zhí)行多項選擇。
格式:
if(條件)
結(jié)果1;
else
結(jié)果2;
語句中的else部分可能被省略。如果本語句省略了else部分,if語句在嵌套時可能會出現(xiàn)歧義。在這種情況下,該else會匹配前而最近的不帶else部分的if語句。
示例:
//--以下的else部分匹配第二個if操作符:
if(x>1)
if(y==2)
z= 5;
else
z= 6;
//--以下else 部分匹配第一個if操作符:
if(x>l){
if(y==2)
z= 5;
}
else
z= 6;
//--以下為if語句嵌套
if(x=='a'){
y= 1;
}
else
if(x=='b'){
y= 2;
z= 3;
}
else
if(x=='c'){
y = 4;
}
else
Print("出錯!");
switch 語句
該語句比較 expression表達式值 和 case中的constant常量值,如果相等,就執(zhí)行相應(yīng)的語句塊。每個case中constant值必須是一個整數(shù)、字符串常量或常量表達式。常量表達式中不能包含變量和函數(shù)調(diào)用。Switch后而的表達式(expression)必須是整型。
格式:
switch(expression){
case constant: operators
case constant: operators
...
default: operators
}
如果沒有一個case表達式值等于expression表達式值,將執(zhí)行default后面的語句塊。此處default語句并不是必需的。
如果沒有一個case常量和expression值一致,而default語句也不沒有,那么不會執(zhí)行任何動作。
關(guān)鍵字case及其常量就像標(biāo)簽,即使switch語句帶有數(shù)個case語句,程序都會按序執(zhí)行后而所有的語句塊,直至遇到break語句為止。
在編譯期間,編譯程序?qū)⒂嬎愠A勘磉_式的值,不允許在一個switch語句內(nèi)同時存在兩個相同的常量值。
示例:
switch(x){
case 'A':
Print("CASE A \n");
break;
case 'B':
case 'C':
Print("CASE B or C\n");
break;
default:
Print("NOT A, B or C\n");
}
while 循環(huán)語句
如果條件表達式expression值為true,while語句一直執(zhí)行直至條件表達式變成false。如果條件表達式為false,將跳到下一條語句。
格式:
while(expression)
operator;
while語句執(zhí)行前,表達式expression必須事先定義過。因此,如果表達式值一開始就為false,while語句根本不會執(zhí)行。
示例:
while(k<N)
{
y= y*x;
k++;
}
for 循環(huán)語句
表達式1 (Expression1)定義循環(huán)的初始變量,表達式2(Expression2)是循環(huán)終止條件。當(dāng)表達式2 (Expression2)為真(true)的時候,循環(huán)體重復(fù)執(zhí)行直至Expression2變?yōu)榧?false)。如果Expression2變?yōu)閒alse,循環(huán)將會被中斷,并繼續(xù)執(zhí)行循環(huán)語句的下一條語句。每次循環(huán)結(jié)束后都會計算表達式3(Expression3),用于改變循環(huán)條件。
格式:
for (Expression1; Expression2; Expression3)
operator;
for 語句與下面while語句等價:
Expression1;
while(Expression2){
operator;
Expression3;
}
for 語句中我們可以省略三個表達式中任一部分或全部,但是其中分號(;)卻不能省略。如果省略了表達式2(expression2),則被視作真值。
示例:
for(x=1; x<=7; x++)
Print( MathPower(x,2) );
for(; ;)語句是一個死循環(huán),它相當(dāng)于while(true)語句。
示例:
for(;;){
Print(MathPower(x, 2));
x++;
if(x>10)
break;
}
表達式1和表達式3都可以內(nèi)嵌多個逗號(,)分隔的表達式。
示例:
for(i=0, j=n-l; i<N; I++, J--)
a[i]= a[j];
函數(shù)
函數(shù)定義
函數(shù)是一段已命名的程序,它可以從程序任一部分多次調(diào)用。它是由函數(shù)返回值的類型說明、函數(shù)名稱、形式參數(shù)和語句塊組成。
傳遞參數(shù)的個數(shù)被限定在64個之內(nèi)。
函數(shù)名稱 (x1, x2,..., xn) // xn<64
示例:
double // 返回值類型
linfunc (double x, double a, double b) { // 函數(shù)名和形參
..... // 內(nèi)嵌的語句塊
return (a*x + b); // 返回值
}
return語句可以返回函數(shù)內(nèi)表達式的值。
如果沒有返回值那么返回值的,函數(shù)類型可以寫為void,表示是一個過程。
示例:
void 打印錯誤子(string 內(nèi)容){
Print("錯誤: "+ 內(nèi)容 );
}
函數(shù)的參數(shù)可能存在默認值,這些默認值是用相應(yīng)類型常量定義的。
示例:
int 測試函函數(shù)值子(double a, double d=0.0001, int n=5, bool b=true, string s="passed string"){
Print("需求參量 a=",a);
Print("下列參量被傳送: d=",d," n=",n," b=",b," s=",s);
return (0);
}
函數(shù)調(diào)用
函數(shù)的形參按值的方式傳遞。即 先算出每個表達式xl,…,xn的值,再將其值傳遞給函數(shù)。表達式計算順序及其值的傳遞要確保無誤。在函數(shù)執(zhí)行時,系統(tǒng)將檢查那些提供給函數(shù)的值和參數(shù)的類型。這種形式的函數(shù)調(diào)用被稱為“值傳遞”。
調(diào)用函數(shù)是為了獲得函數(shù)返回的表達式值。函數(shù)的定義類型必須符合函數(shù)返回值的類型。
在全局層次,我們可以在程序的任何位置定義和說明函數(shù),即 要在其他函數(shù)之外定義,在函數(shù)之內(nèi),不能定義或說明另一個函數(shù)。
例如:
函數(shù)名(形參A,形參B,...) function_name (x1,x2,...,xn)
示例:
double 數(shù)組[4]= {0.3, 1.4, 2.5, 3.6};
//----------被調(diào)用的子函數(shù)------------+
double 如果真子(double 形參a, double 形參b, double 形參c){
if(形參a>形參b){
return(形參a);
}
else
return(形參c);
}
//--------------主函數(shù)----------------+
int start()
{
double AA= 計算函數(shù)子(數(shù)組, 10.5, 8);
double 某B= 如果真子(9.7, 10.5, 10);
//...
}
//----------被調(diào)用的子函數(shù)------------+
double 計算函數(shù)子(double 形參數(shù)組名x, double 形參a, double 形參b)
{
return (形參a*形參數(shù)組名x[0] + 形參b);
}
使用默認參數(shù)調(diào)用函數(shù)時,參數(shù)列表使用規(guī)則是有要求的。參數(shù)列表中無默認值的參數(shù)必須指定值,且不可以省略。有默認值的參數(shù)要么全省略掉,要么指定值,不可只省略其中部分參數(shù)。
當(dāng)調(diào)用一個函數(shù)時,如果有多個默認值的形參 如果后部的形參要重新賦值則不可以忽略不寫前面的形參值。
例如:
//--函數(shù)原型
//--函數(shù)原型
void somefunc(double nit, double sec=0.0001, int level=10){
.....
}
//--調(diào)用情況
somefunc(); // 錯誤調(diào)用: 因第一請求參量未賦值!
somefunc(3.14); // 正確調(diào)用
somefunc(3.14, 0.0002); // 正確調(diào)用
somefunc(3.14, 0.0002, 10); // 正確調(diào)用
somefunc(3.14, , 10); // 錯誤調(diào)用。因第二參量被忽略。
特殊函數(shù) init()、deinit()和start()
在MQL4中存在三種預(yù)定義名稱函數(shù):
init() 是一個在模塊初始化時調(diào)用的函數(shù),可以用此函數(shù)在開始自定義指標(biāo)或者自動交易之前做初始化操作。如果這個函數(shù)不可用,初始化時就不會調(diào)用任何函數(shù)。
因初始化只在程序開始前只運行一次, 所有些只運算一次的變量在此間確定.
datetime 最后開倉時= 0;
int 再開時隔數(shù);
//---------------初始化----------------+
int init()
{
//--1 在初始化中確定再開時隔數(shù)的間隔值
再開時隔數(shù)= 再開時隔數(shù)(Time[0]-Time[1]);
//--五位平臺改四位
小數(shù)位= Digits;
if(小數(shù)位==3 || 小數(shù)位==5){
點= 10.0Point;
改四系數(shù)= 10;
}
else{
點= Point;
改四系數(shù)= 1;
}
return(0);
}
start() 是主函數(shù)。對于智能交易,它在收到下一跳數(shù)據(jù)后調(diào)用該函數(shù);
對于自定義指標(biāo),在指標(biāo)添加到圖表之后,或在客戶端開始運行之時,也可在收到下一跳數(shù)據(jù)之后,該函數(shù)被調(diào)用;
對于腳本,在腳本被添加到圖表之后立即執(zhí)行并初始化。
主函數(shù)在當(dāng)數(shù)據(jù)變動時觸發(fā),對于自定義指標(biāo)或者自動交易的編程主要圍繞此函數(shù)進行。如果模塊中不存在start()函數(shù),模塊(智能交易、腳本或自定義指標(biāo))就不能執(zhí)行。
deinit() 卸載時調(diào)用,是一個模塊的析構(gòu)函數(shù)(注:借用C++概念),執(zhí)行一與init()函數(shù)相反的操作。deinit()函數(shù)往往用來做“清理善后”的工作,例如,創(chuàng)建對象時開辟了一片內(nèi)存空問,退出模塊前需要釋放。如果用戶沒有編寫該函數(shù),它也不會執(zhí)行任何操作。
預(yù)定義函數(shù)可以帶參數(shù)。不過,當(dāng)客戶端調(diào)用這些函數(shù)時,并不能從外部向它傳遞參數(shù),只能采用默認值。
start(), init()和deinit()函數(shù)可從模塊任何一點按照常規(guī)函數(shù)規(guī)則調(diào)用,等同于其他函數(shù)。
不推薦從init()函數(shù)調(diào)用start ()函數(shù)或是執(zhí)行交易操作。對于圖表數(shù)據(jù)、市價等,在模塊初始化期間,數(shù)據(jù)可能殘缺不全,這時,init()和deinit()函數(shù)須盡快地完成任務(wù)。 在調(diào)用start()函數(shù)之前,千萬不要開始嘗試交易操作。