1

为什么这是不可能的?

int c = 0;
++c++;

或者在 PHP 中:

$c = 0;
++$c++;

我希望它将变量 c 增加 2,或者可能会做一些奇怪的事情,但是它在编译时会出错。我试图想出一个理由,但实际上一无所获……我的理由是:

  1. 编译器读取 ++
  2. 它读取变量
  3. 它会做任何事情来使变量的值递增,然后在执行应用程序时返回
  4. 它遇到另一个++
  5. 它使用前一个变量以便在增加值之前返回它
  6. 这就是令人困惑的地方:它是使用变量 c,还是尝试读取 (++c) 返回的值?或者,由于您只能执行 varname++(而不是 2++),它是否将 (++c) 视为指针,然后尝试读取该内存位置?不管它做什么,为什么它会给出一个编译错误?或者是错误预防,因为编译器的程序员知道它不会做任何有用的事情?

我并不是真的想使用它,当然也不是用于非一次性使用的代码,但我只是好奇。

4

3 回答 3

6

出于同样的原因,您不能这样做:

c++ = 5;

它返回一个值,该值不能修改也不能赋值。这也不是运行时错误 - 那是编译错误。(像这个。)

返回引用也没有意义,因为那时:

$a = 1;
$b = $a++; // How can it be a reference if b should be 1 and a should be 2?
于 2012-09-01T20:48:15.043 回答
3

不一定与语言无关,尽管看到一种不同的语言我会有点惊讶。

在 C 中(因此我假设在所有基于 C 的非烦人语言中),运算符优先级意味着您的表达式等同于++(c++). 根据您的逐步说明,您期望它等同于(++c)++,但事实并非如此。后缀++比前缀“绑定更紧密” ++

就像大家说的那样,表达式c++产生一个值,而不是一个可修改的对象(C 中引用一个对象的表达式称为左值)。这是必要的,因为对象c不再包含表达式计算的值——没有c++可以引用的对象。

在 C++ 中(不要与c++! 混淆),++c 一个左值。它指的是c现在具有新值的对象。

所以在 C++(++c)++中是语法正确的。c如果is 是类型,它恰好具有未定义的行为int(至少,它在 C++03 中做到了:C++11 定义了一些以前未定义的东西,而我对这些更改不是最新的)。

因此,如果您想象(或继续发明)一种类似 C++ 的语言,其中运算符优先级是您所期望的,那么您可以安排++c++它是有效的。大概它会增加c两次,并评估为旧值和新值之间的值。从某种意义上说,这种想象中的语言会“令人讨厌”,因为它与 C++ 略有不同,这往往会让人感到困惑。

++c++c如果是重载两个增量运算符的用户定义类型的实例,则在 C++ 中也有效。原因是用户定义类型的右值一个对象(“临时对象”),可以修改。但是一旦表达式被求值,临时的就被破坏了,修改也丢失了。

于 2012-09-02T00:52:50.977 回答
1

解释这一点的另一种方法是++运算符仅对左值进行操作。但是当你组合它们时,它被解析为++(c++)或者(++c)++- 在任何一种情况下,括号外的运算符的参数是一个右值(c在增量之前或之后的值),而不是一个左值。

于 2012-09-01T21:05:33.363 回答