我读过" 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}}是子表达式吗?为什么?
我对此感兴趣,因为我想了解假设中可能出现的副作用。
答案 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)
形式的表达式,其中Z
为4 + x++
。 4 + x++
由两个表达式4
和x++
组成。等等。所有这些表达都是
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++);
的子表达式,它是一个赋值。该分配是一个完整的表达 - 而不是一个子表达。我留下了一些未经探索的子表达式,我将把它们作为练习留给读者。