自增、自减和逻辑运算(指标编程教程第十篇:运算符和优先级)

提示

这是 2011 年写的一个系列教程。

在表达式求值时,按运算符的优先级的高低次序进行结合,如先乘除后加减,a + b * c 相当于 a + (b * c)。如果优先级相同,则按规定的“结合方向”处理。

数学课上算术式的结合方向大部分都是由坐至右的,但是 EA 和指标编程中,有部分运算符是由右向左结合的,比如 a = b;,是把 b 的值赋给 a,如果初始值是 a 为 1,b 为 2,那么执行后 a 和 b 都等于 2。再比如 a+++b; 相当于 a + (++b); 而非 (a++) + b;

两个加号(++)是自增运算符,++a 相当于 a = a + 1;,而 ++aa++ 的区别看一下下面的示例:

// 声明变量。
int a, b, x, y;
// 赋值。
a = 0;
x = 0;
b = 1;
y = 1;
a = b++;
x = ++y;

最后,a = 1、b = 2、x = 2、y = 2。

其中

a = b++;
x = ++y;

可以展开为

// a = b++;
t = b;
b = b + 1;
a = t;
// x = ++y;
y = y + 1;
x = y;

一定要注意,a = 1 不是因为 (a = b)++;,首先自增和自减运算符只能用于变量a = b 是个表达式,不能用 ++ 计算(在 MQL 中赋值只能是“语句”,但你只要知道 a = b 不能参与计算就好);其次这个表达式的优先级还是先结合自增运算:a = (b++);。但是当两个加号在变量后面的时候,会先把变量的值复制一份出去,再自己加 1,然后用赋值出去的原始值代入表达式。而当自增或自减运算符在变量左边时,就会先自增或自减,然后代入表达式。

如果我写 a = a+++++b; 则会被结合成 a = a + (++(++b));,自增运算符不能用于表达式,所以这么写无法通过编译。初始值 a0b1a = (a++) + ++b; 后,a 的值为多少呢?自己算一算再往下看。

赋值运算会先算等号右边的部分,(a++) + ++b 变成 (0++) + ++1,再变成 (0++) + 2,这个表达式的值为 2,而此时 a+ 1 了,a = 0 + 1; 之后,又该把 (0++) + 2 的值赋给 a 了,所以最终 a 的值为 2。可能看上去有点乱,多用用就好了,当然最好尽量避免在同一表达式中连续使用自增、自减运算符。

也可以像下面这样理解:

// a = (a++) + ++b;
t = a;      // t = 0;
a = a + 1;  // a = 1;
b = b + 1;  // b = 2;
a = t + b;  // a = 0 + 2;

a = a + 1; 还有一种写法:a += 1;,它比自增运算符灵活的地方是可以 a += 2;a -= 1; 同理。

上一篇讲的 if...else 结构,大部分都是以逻辑运算作为判断条件,逻辑运算只有两个结果:“真”、“假”。

  • a && b 读作:“a 与 b”。若 ab 都为“真”,则表达式的值为“真”。
  • a || b 读作:“a 或 b”。若 ab 其中任意一个为“真”,则表达式的值为“真”。
  • !a 读作:“非 a”。若 a 为“真”,则表达式的值为“假”。

举几个例子:

bool a = true;
bool b = false;
int c = 1;
a && b;    // 为假。
a || b;    // 为真。
!b;        // 为真。
!(c > 0);  // 为假。

另外 !a || b && c 的结合规则为 (!a) || (b && c)。“非”的优先级 > “与”的优先级 > “或”的优先级。下一篇列出所有运算符和优先级,太长了占篇幅,单开一篇。

  • 903
回复内容较长可以拖右下角↑
回到
顶部