跳至内容

Passing Parameters

传递参数

有两种方法,机器语言可以通过这两种方法将参数传递给子程序(函数)。第一种方法是按值传递参数。这种方法将参数值复制到形式函数参数中。因此,在函数内部对参数进行的任何更改都不会影响相应的调用参数。

//+------------------------------------------------------------------+
//| Passing parameters by value                                      |
//+------------------------------------------------------------------+
double FirstMethod(int i,int j)
  {
   double res;
//---
   i*=2;
   j/=2;
   res=i+j;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
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);
  }
//--- Result of script execution
//  a and b before call: 14 8
//  a and b after call: 14 8

第二种方法是按引用传递。在这种情况下,将参数的引用(而不是其值)传递给函数参数。在函数内部,它用于引用调用中指定的实际参数。这意味着参数的更改会影响用于调用函数的参数。

//+------------------------------------------------------------------+
//| Passing parameters by reference                                  |
//+------------------------------------------------------------------+
double SecondMethod(int &i,int &j)
  {
   double res;
//---
   i*=2;
   j/=2;
   res=i+j;
//---
   return(res);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//--- result of script execution
//  a and b before call: 14 8
//  a and b after call: 28 4

MQL4 使用这两种方法,有一个例外:数组、结构类型变量和类对象总是按引用传递。为了避免实际参数(在函数调用时传递的参数)发生更改,可以使用const访问说明符。当尝试更改用 const 说明符声明的变量的内容时,编译器将生成错误。

注意

需要注意的是,参数按相反顺序传递给函数,即首先计算并传递最后一个参数,然后是倒数第二个参数,依此类推。最后一个被计算并传递的参数是在打开括号后第一个出现的参数。

示例:

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)+")");
// Result:
// First call (i = 0) : par1 = 1     par2 = 0
// Second call (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 变量才会再次改变。

另请参阅

变量的可见性范围与生命周期重载虚函数多态性

最后更新于