0

这篇文章(不仅如此)中,我们了解到 ++ 运算符不能应用于返回值的表达式。很明显 5++ 写成 5 + 1 更好。我只想总结一下关于增量/减量运算符的整个事情。因此,让我们看一下这些代码片段,这些代码片段至少对第一次坚持使用 ++ 的人可能会有所帮助。

// Literal
int x = 0++; // Error

// Constant
const int Y = 1;
double f = Y++; // error. makes sense, constants are not variables actually.

int z = AddFoo()++; // Error

总结:++ 适用于变量、属性(通过合成糖)和索引器(相同)。
现在感兴趣的部分 - 任何文字表达式都在 CSC 中进行了优化,因此当我们编写时,说

int g = 5 + 1; // This is compiled to 6 in IL as one could expect.
IL_0001: ldc.i4.6 // Pushes the integer value of 6 onto the evaluation stack as an int32.

对于 5++ 并不意味着 5 变为 6,它可能是 5 + 1 的简写,例如 x++ = x + 1 这种限制背后的真正原因是什么?

int p = Foo()++ //? yes you increase the return value of Foo() with 1, what's wrong with that?

可能导致逻辑问题的代码示例值得赞赏。

现实生活中的一个例子可能是,执行比数组中的多一个动作。

for (int i = 0; i < GetCount()++; i++) { }

也许缺乏使用选择编译器团队来避免类似的功能?我不坚持这是我们缺乏的功能,只是想了解编译器编写者的阴暗面,尽管我不是。但我知道c++ 在方法中返回引用时允许这样做。我既不是一个 C++ 人(知识很差),只是想了解限制的真正要点。就像,仅仅是因为 c# 的人选择限制 ++ over value 表达式还是有确定的情况导致不可预测的结果?

4

2 回答 2

2

为了使一个特性值得支持,它确实需要有用。您提供的代码在任何情况下都比替代方案可读性差,后者只是使用普通的二进制加法运算符。例如:

for (int i = 0; i < GetCount() + 1; i++) { }

我完全赞成语言团队阻止你编写不可读的代码,而在你可以做到的任何情况下,都有一个更简单的替代方案。

于 2013-01-21T17:36:36.837 回答
0

那么在使用这些运算符之前,您应该尝试阅读他们如何做他们所做的事情。特别是,您应该了解后缀和前缀之间的区别,这有助于弄清楚什么是允许的,什么是不允许的。

++ 和 -- 运算符修改它们的操作数。这意味着操作数必须是可修改的。如果您可以为相关表达式分配一个值,那么它是可修改的,并且可能是一个变量(c#)。

看看这些运营商实际做了什么。后缀运算符应在您的代码行执行后递增。至于前缀运算符,他们甚至需要在调用方法之前访问该值。我阅读语法的方式是++lvalue (or ++variable)转换为memory operations:[read, write, read]或转换为lvalue++ [read, read, write]尽管许多编译器可能会优化二次读取。

因此,查看foo()++;该值将在执行代码的中心被淘汰。这意味着编译器需要将值保存在更长期的地方,以便在代码行完成执行后对所述值执行操作。毫无疑问,这也是 C++ 也不支持这种语法的确切原因。

如果你要返回一个引用,编译器不会对后缀有任何问题。当然,在 C# 中,值类型(即 int、char、float 等)不能通过引用传递,因为它们是类型。

于 2015-07-06T21:05:20.803 回答