&++x 和 &x++ 的区别

Hem*_*ava 6 c++ unary-operator pre-increment post-increment postfix-operator

虽然这个问题可能在某处得到回答,但我找不到。

下面写的第一条语句有效而第二条语句无效?为什么?

int main() {
  int x = 1, y = 2;

  int *p = &++x; // First
  std::cout << "*p = " << *p << std::endl;

  // int *q = &x++; // Second
  // std::cout << "*q = " << *p << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 4

在这份声明中

\n\n
int *p = &++x;\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用了两个一元运算符:预自增 ++ 和取地址。一元运算符从右到左执行。因此,首先变量x被递增,并将其地址分配给指针p,预递增运算符的结果是lvalue递增的对象。

\n\n

例如这样的表达式

\n\n
++++x;\n
Run Code Online (Sandbox Code Playgroud)\n\n

是正确的。

\n\n

在这份声明中

\n\n
int *p = &x++;\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用后缀运算符后自增++和取地址一元运算符。后缀运算符相对于一元运算符具有更高的优先级。所以首先执行后增量。其结果是一个临时对象,其中包含变量 x 递增之前的值。然后执行取地址运算符。

\n\n

但是,您不能获取临时对象的地址。因此对于这个声明,编译器将发出错误。

\n\n

与预自增运算符相反,这样的表达式如下

\n\n
x++++;\n
Run Code Online (Sandbox Code Playgroud)\n\n

是无效的。

\n\n

来自 C++ 17 标准(5.3.2 递增和递减)

\n\n
\n

1 前缀 ++ 的操作数通过添加 1 进行修改,或者如果它是 bool,则设置为 true(不推荐使用此用法)。操作数应是可修改的左值。操作数的类型应为算术类型或指向完全定义的对象类型的指针。结果是更新后的操作数;它是一个左值,如果\n操作数是一个位域,那么它是一个位域......

\n
\n\n

以及(5.2.6 递增和递减)

\n\n
\n

1后缀++表达式的值是其操作数的值。[\n注:获取到的值是原始值的副本\xe2\x80\x94尾注\n]...

\n
\n\n

在 C 中,这两个操作都会产生一个值。所以在C中你也可能不会写

\n\n
++++x;\n
Run Code Online (Sandbox Code Playgroud)\n