C#和C++中++i运算符的区别

14

我已经写了下面这段代码,既有C++版本也有C#版本

 int i=0;
 ++i = 11;

在这之后,C#编译器会报错

The left-hand side of an assignment must be a variable, property or indexer

但是C++编译器生成了这段代码,没有出现错误,并且我得到了一个结果11,作为i的值。这种差异的原因是什么?


4
离题:为什么你想要先将它加一,然后直接设置为11?这个增量没有意义。 - RvdK
这段代码有什么用途? - Bo Persson
someArray[++i] = 11 更有意义。 - Joseph Le Brech
1
这对我来说很有趣。@mesiesta正确地解释了为什么会这样。 - shift66
4个回答

42
在C++中,前置自增运算符是左值,而在C#中不是。在C++中,++i返回对已增加的变量的引用。而在C#中,++i返回变量i已增加的值。因此,在这种情况下,++i在C++中是左值,在C#中是右值。
从C++规范中可以了解到前缀自增运算符的操作数类型应该是算术类型或指向完全定义的对象类型的指针。其值是操作数的新值,是一个左值。
P.S.后置自增运算符i++在C#和C++中都不是左值,所以这行代码会在两种语言中都出错。
 int i=0;
 i++ = 11;

6
请注意,在C++03中,++i = 11会导致未定义行为,因为您在没有中间序列点的情况下两次修改了i。然而,在C++11中,它是明确定义的:首先进行递增,然后进行赋值。

5
C# 和 C++ 是两种完全不同的语言和概念。它们只是因为语法基于 C 而共享名称。所以实际上,“为什么这在 C# 上可以,但在 C++ 上不行”没有意义。这就像说为什么一个表在英语中被称为 "table",而在西班牙语中被称为 "mesa" 一样。因为决定是那样的。
C# 简单地不允许这种语法。
在 C++ 中,你被允许:首先计算 ++i,这使得 i = 1,然后将 11 赋值给 i,这使得 i = 11

3
有点苛刻。这个问题在C语言中很常见,许多在C++中可行的东西也适用于C#!在我看来,这是一个完全合理的问题,尤其是在C++中,所涉及的代码表示一个没有逻辑意义的语句。 - adelphus
为什么要这么严厉呢?我只是在陈述C#和C++除了基于C之外没有共同之处。问题不适用于C,因为他并不是在询问C本身,而且在C中这个句子完全起作用,在C#中却不行,这正说明了C#与C除了名称和语法之外没有任何联系(顺便说一下,很多语言如Perl、Java等也都是抄袭C#的语法)。 - m0skit0
2
C#和C++有相似之处...它们不像Java和Haskell那样不同。所以对我来说这是一个合理的问题,也很有趣。 - Chuck Norris
它们就像Java和Haskell一样不同,但我不打算列举所有的差异和极少数的相似之处。了解这些确实很有趣,但我个人不会以那种方式提出问题。 - m0skit0

2

语义差异很大。在C++中,语义是将值11分配给由i标识的存储位置。在C#中,语义等同于以下语句的语义。

1=11

这就相当于试图将值11赋给值1,而C#编译器不允许这样做。(Fortran编译器实际上允许这样做,这可能会导致非常困难的调试场景)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接