FOR 语句基础篇:把循环控制流从根上拆明白(基础篇)
(1/2)· 很多人以为 FOR 是第三种循环就多记一套语法,其实它和 WHILE 同宗不同用
FOR 循环在 MT5 里的真实跑法
MQL5 里 FOR 语句是批量处理 K 线或订单的最直接结构,语法和 C 语言一致:初始化、条件判断、迭代三步写在同一行。对做价格行为回测的交易者来说,它比 while 更不容易写出死循环。 下面这段是最小可运行骨架,用来遍历最近 100 根柱体并打印它们的收盘价。你在 MT5 里新建脚本粘进去,编译后拖到图表就能在专家日志看到输出。 外汇与贵金属杠杆高、滑点随机,回测结论只代表历史概率,实盘可能偏离。 循环上限写死 100 只是示例;真做策略时建议用 Bars() 或 iBars() 动态取可用柱数,避免越界报错 4806。
for(class="type">int i=class="num">0; i<class="num">100; i++) Print(Close[i]);
「为什么先把基础嚼碎再碰 FOR」
这部分内容定位在教育培训,除了搞懂思路和写法,不建议直接拿去实盘跑任何样例程序。外汇和贵金属杠杆高、滑点大,光会语法不等于能赚钱,这点先说在前头。 上篇讲了 SWITCH 的最简用法,重点不是背结构,而是想清楚它和 IF、WHILE 之间怎么替、怎么选。基础不牢,后面看复杂框架会一直卡壳。 有人觉得目前材料太浅,想直接上高阶。以多年写 MQL5 的经验看,概念在最根本那一层通了,复杂主题往往一眼就透。这也是拆开逐篇讲的原因。 控制执行流的语句里,现在只剩 FOR 没聊。它确实是 MQL5 里这类操作符的最后一环,但我会单开一节慢慢拆,不跟前面混着讲。
◍ 为什么 MQL5 里还要多一个 FOR
控制流命令在任一门语言里都极少,MQL5 同样如此:WHILE、DO WHILE 加上 FOR 就覆盖了绝大多数循环需求,而库函数与保留字的数量却能以千计。多数交易者写 EA 时卡住的从不是语句种类,而是没吃透这几条基础控制流。 FOR 之所以和 WHILE、DO WHILE 并存,是因为在某些场景里后两者并不顺手。典型差异在 CONTINUE 的使用:当循环控制要素需要集中声明时,FOR 把初值、条件和步进都收在头部,WHILE 的控制逻辑却常散落在循环体某行,改起来要翻完整段。 统计社区代码风格可见,FOR 是程序员偏好最高的循环写法,原因就是可读性——只看声明就能修控制逻辑,不必进循环体找边界。外汇与贵金属杠杆高、滑点突发,EA 逻辑若因循环混乱出错,实盘可能瞬间回撤,验证代码前务必在 MT5 策略测试器跑历史段。 我们先从最基础的 FOR 形式切入,假设你已用过 WHILE 和 DO WHILE,理解头部三要素会快很多;后面谈运算符优先级时再回头看,会发现 FOR 某些写法藏着坑。
用 FOR 改写 while 时 info 的值去哪了
把一段 while 循环原样翻译成 FOR,最常踩的坑不是语法,而是变量生命周期和打印时机。下面这段是原始 while 版:循环前 info 被赋为 10,每次迭代先自减再打印,跑完 10 到 1,循环结束后 info 实际值为 0。
[CODE]
//+------------------------------------------------------------------+
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
void OnStart(void)
{
char info = 10;
Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway...");
while (info)
{
info = info - 1;
Print(__FUNCTION__, " : ", info);
}
Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway...");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
void OnStart(void)
{
char info = 10;
Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway...");
for( ; info; )
{
info = info - 1;
Print(__FUNCTION__, " : ", info);
}
}
[/CODE]
第一行 OnStart 里 char info = 10; 是局部变量,仅在函数栈内活;while (info) 靠 info 非零做条件;循环体先 info = info - 1 再打印,所以首行打出 9。
改写成 for( ; info; ) 只动第 10 行,条件段留空、迭代段也留空,完全复用 while 的判断逻辑。MT5 里跑出来和图 01 一致:打印 9 到 1,循环后 info 同为 0。
别把空段当摆设
FOR 的三个括号段(初始化、条件、迭代)任一段都能空着,但空着不代表不执行——条件段每次迭代前仍被求值。若你把自减挪进迭代段写成 for( ; info; info = info - 1) 却在循环体内又打印 info,首行就会是 10 而非 9,因为自减发生在打印之后。
另一个易错版是把 char info = 10 保留、循环体内不碰 info 而靠别处改,结果可能直接死循环或只打一次 10。想验证的话,把第 6 行改成 9 再跑,会看到打印从 8 开始——这证明输出完全绑在 info 的初始值与自减次序上,不关 FOR 本身什么事。外汇与贵金属脚本里这种计数错一位,可能导致 K 线遍历漏根,实盘前务必在策略测试器单步核对。
class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Daniel Jose" class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart(class="type">void) { class="type">char info = class="num">10; Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); while (info) { info = info - class="num">1; Print(__FUNCTION__, " : ", info); } Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); } class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Daniel Jose" class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart(class="type">void) { class="type">char info = class="num">10; Print(__FUNCTION__, " ", __LINE__, " It will be executed anyway..."); for( ; info; ) { info = info - class="num">1; Print(__FUNCTION__, " : ", info); } }