传递函数

有两类函数,计算机语言可以用其传送自变量到子程序(函数)。第一类函数是通过值发送参数。这个函数将自变量值复制到形式函数参数。因此,函数中这个参数的任何改变都不会对自变量的相应调用产生影响。

//+------------------------------------------------------------------+
//| 通过值传递参数                                                     |
//+------------------------------------------------------------------+
double FirstMethod(int i,int j)
  {
   double res;
//---
   i*=2;
   j/=2;
   res=i+j;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| 脚本程序启动函数                                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int a=14,b=8;
   Print("a and b before call:",a," ",b);
   double d=FirstMethod(a,b);
   Print("a and b after call:",a," ",b);
  }
//--- 执行脚本结果
//  调用前a 和 b : 14 8
//  调用后a 和 b : 14 8

第二类函数是通过引用传送。在这种情况下,参数引用(不是它的值)被传送到函数参数。函数内,被用来连接调用指定的实际参数。这意味着参数的改变将会影响用来调用函数的自变量。

//+------------------------------------------------------------------+
//| 通过引用传递参数                                                   |
//+------------------------------------------------------------------+
double SecondMethod(int &i,int &j)
  {
   double res;
//---
   i*=2;
   j/=2;
   res=i+j;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| 脚本程序启动函数                                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int a=14,b=8;
   Print("a and b before call:",a," ",b);
   double d=SecondMethod(a,b);
   Print("a and b after call:",a," ",b);
  }
//+------------------------------------------------------------------+
//--- 执行脚本结果
//  调用前a 和 b: 14 8
//  调用后a 和 b: 28 4

MQL5使用这两种函数,有一个例外就是:数组和结构类型变量(类的对象)总是通过引用传送。为了在真实参数中排除改变(函数调用传送的自变量)使用常数 访问说明符。若尝试改变说明常量说明符的变量,编译程序会生成错误。

注解

注意用倒序传送参数到函数,例如,首先是最近的函数被计算和传送,然后倒数第二。最后计算和传送的参数是括号后的第一个。

示例:

void OnStart()
  {
//---
   int a[]={0,1,2};
   int i=0;
 
   func(a[i],a[i++],"First call (i = "+string(i)+")");
   func(a[i++],a[i],"Second call (i = "+string(i)+")");
// 结果:
// 首先调用 (i = 0) : par1 = 1     par2 = 0
// 第二调用 (i = 1) : par1 = 1     par2 = 1
 
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void func(int par1,int par2,string comment)
  {
   Print(comment,": par1 = ",par1,"    par2 = ",par2);
  }

  首先上面的示例中先调用变量i参与合并字符串。

  "First call (i = "+string(i)+")"

这里值不可更改。变量 i 加入a[i++]数组的运算,例如加入数组元素i,变量i就会增加。之后,仅计算变量 i 改变值第一个参数

第二步,计算所有三个参数,使用调用函数第一步计算的和i的同值,仅计算第一参数后变量i会再次更改。

另见

可见范围和变量使用期重载虚拟函数多态