什么可以是子表达式?

时间:2016-04-25 21:29:32

标签: c++ expression sequence-points

我读过" C ++。Primer plus。 Stephen Prata"(第6版)。 在页面209是:

y = (4 + x++) + (6 + x++);
     

表达式4 + x++不完整   表达式,因此C ++不保证x将递增   在评估子表达式4 + x++之后立即执行。在这里   完整表达式是整个赋值语句和分号   标记序列点,因此C ++保证的所有内容都是x   在程序移动到的时候已经增加了两次   以下陈述。 C ++没有指定x是否递增   在评估每个子表达式之后或仅在所有子表达式之后   已经评估了表达式,这就是你应该避免的原因   这种陈述。

我读了"序列点和表达评估"视觉系统杂志,2002年8月.Klaus Kreft& Angelika Langer。 有:

 x[i]=i++ + 1; 
     

在我们输入语句之前,假设变量i的值为1。   评估这个表达式的结果是什么?正确的   答案是:我们不知道。然而,程序员经常相信   他们知道这个程序片段的作用。典型的答案   包含:" x[1]的值为2"或者" x[2]将具有该值   2",甚至" x[1]的值为3"。

     

第三种选择绝对是错误的。这不会发生,因为i++   是后缀增量并返回i的初始值1;因此   作业右侧的值是2,绝对是   不是3。 [...]到目前为止一直很好,但我们不知道   将修改数组x的哪个条目。索引是1还是2   何时将右侧值分配给x[i]

     

这个问题没有明确的答案。它完全取决于   编译器评估子表达式的顺序。如果   编译器从赋值的右侧开始并进行评估   在i++ + 1确定数组x中的哪个位置必须为之前x[2]   分配给i的人将被修改,因为i++已经存在   在评估子表达式i的过程中增加了。   相反,如果编译器在左侧开始并且数字   它必须分配到数组x中的位置1,这在当时   在评估右侧之前,它仍然是位置x[1]   我们最终会修改4 + x++。两种结果都是平等的   可能同样正确。 "

如何理解子表达式在哪里? 6 + x++x[i]是子表达式,因为它们是圆括号? i++ + 1和{{1}}是子表达式吗?为什么? 我对此感兴趣,因为我想了解假设中可能出现的副作用。

2 个答案:

答案 0 :(得分:2)

打破这一行

y = (4 + x++) + (6 + x++);

是一个表达式语句。这样的事情由一个表达式后跟;组成,所以

y = (4 + x++) + (6 + x++)

是一个表达。

由于此表达式 是另一个表达式的一部分(但只有表达式 - 语句),因此已满-expression 。另一方面,子表达式 另一个表达式的一部分的表达式。在下文中,我将使用大写字母来命名表达式,而不是C ++标识符。

上面的完整表达式是形式的赋值表达式:

y = A

其中A是剩余的加法表达式

(4 + x++) + (6 + x++)

加法表达式的格式为X + Y,因此我们将其分解为两个表达式

(4 + x++)
(6 + x++)

第一个包含(Z)形式的表达式,其中Z4 + x++4 + x++由两个表达式4x++组成。等等。所有这些表达都是

的一部分
y = (4 + x++) + (6 + x++)

因此它们是上述表达式的子表达式

答案 1 :(得分:1)

  

什么是子表达式?

任何 表达式都可以是子表达式。虽然,某些表达式可能不是某些其他表达式的子表达式。

  

4 + x++6 + x++是子表达式

正确。这两个都是算术表达式,更具体的补充。

  

因为它们是圆括号吗?

好吧,有点儿。在括号内,它们确实是带括号的表达式的子表达式。

一般来说,它们是子表达式,因为它们是表达式,但也是另一个表达式的一部分。

  

x[i]i++ + 1是子表达式吗?为什么呢?

是的,他们是。见

以下是c ++中所有可能expressions的便捷列表。

让我们在y = (4 + x++) + (6 + x++);中找到子表达式。没有子表达式的第一个表达式是4。这是一个文字。它是4 + x++的子表达式,是一个补充。添加的格式为A + B。在这种情况下,子表达式A为4,子表达式B为x++,这是后增量。哦,但它也包含一个子表达式:x。它是一个标识符,不包含子表达式。 4 + x++是带括号的表达式(4 + x++)的子表达式。这是(4 + x++) + (6 + x++)的子表达式,它是y = (4 + x++) + (6 + x++);的子表达式,它是一个赋值。该分配是一个完整的表达 - 而不是一个子表达。我留下了一些未经探索的子表达式,我将把它们作为练习留给读者。