为什么我不能用C-like语言做++ i ++?

半开玩笑地半开玩笑为什么我不能用C-like语言做++i++ ,特别是在C#中?

我希望它增加值,在我的表达式中使用它,然后再次递增。

简短回答: i++不是“左值”,因此不能成为作业的主题。

尽管简短的回答“它不是一个左值”是正确的 ,但这或许只是在乞求这个问题。 为什么不是左值 ? 或者,正如我们在C#中所说的,一个变量

原因是因为你不能吃蛋糕也不能吃 。 从逻辑上解决这个问题:

首先,C#中的++运算符的含义,无论是后缀还是前缀,都是“获取此变量的值,递增值,将新值赋给变量,并生成值作为结果” 。 作为结果生成的值是原始值或递增值,具体取决于它是后缀还是前缀。 但不管怎样,你产生了一个价值。

其次, 变量的值始终是该变量的当前内容 。 (模拟某些奇怪的线程场景会让我们远远不够。)

我希望你同意这些是完全明智的规则。

现在应该清楚为什么i ++的结果不能变量,但如果不是,请让我说清楚:

假设我是10.I ++的含义应该是“得到i – 10的值 – 增加它 – 11 – 存储它 – 我现在是11 – 并给出原始值作为结果 – 10”。 所以当你说print(i ++)它应该打印10,而11应该存储在i中。

现在假设i ++的含义是返回变量 ,而不是 。 你说print(i ++)会发生什么? 你得到i – 10的值 – 增加它 – 11 – 存储它 – 我现在是11 – 并且结果给出变量。 变量的当前值是多少? 11! 这正是您不想打印的内容。

简而言之,如果i ++返回一个变量,那么它将完全与运算符的预期含义完全相反 ! 您的提案在逻辑上是不一致的,这就是为什么没有语言这样做的原因。

因为你关心下一个程序员维护(或试图重写)你的代码,很久你因为违反流行的约定而被解雇了。

我测试了(++ i,i ++)作为解决方法:

 #include  int main(){ int i=0; printf(" i: %i\n", i ); printf(" (++i,i++): %i\n", (++i,i++) ); printf(" i: %i\n", i ); } 

结果:

 i: 0 (++i,i++): 1 i: 2 

因为i++的结果不是左值。

我相信递增(或递减)运算符需要赋值的左值。 但是++ i不是左值,它是一个表达式。 精通编译器的人可能能够澄清这种约束是否有任何技术原因。

从C#3.0规范的 7.5.9节:

后缀增量或减量操作的操作数必须是分类为变量,属性访问或索引器访问的表达式。 操作的结果是与操作数相同类型的值。 如果后缀增量或减量操作的操作数是属性或索引器访问,则属性或索引器必须同时具有get和set访问器。 如果不是这种情况,则会发生编译时错误。

此外,将首先计算后增量表达式( i++ ),因为它具有比预增量( ++i )运算符更高的优先级。