C++中i ++和(i)++之间的区别

Pol*_*000 49 c evaluation increment language-lawyer

int i = 3;
int j = (i)++;
Run Code Online (Sandbox Code Playgroud)

VS

int i = 3;
int j = i ++;
Run Code Online (Sandbox Code Playgroud)

虽然上面两个例子都存储了3个__CODE__,但上述两个案例的评估方式是否存在差异?

既然__CODE__是a __CODE__,那么__CODE__第一种情况是否会被评估为表达式,这相当于递增rvalue?或者它是未定义的行为,只是恰好存储3 __CODE__

或者我是否过度思考它只是一个简单的后缀?

Eri*_*hil 92

i++并且(i)++行为相同.C 2018 6.5.1 5说:

带括号的表达式是主表达式.它的类型和值与未表示的表达式相同.如果未表示的表达式分别是左值,函数指示符或空表达式,则它是左值,函数指示符或void表达式.

C 1999中的措辞相同.

  • @MrLister是的,甚至在ANSI C(1978)之前都有这种行为.它没有正式拼写(很少),但它是第一版K&R中的一些例子所必需的,例如`(*ptr)++`. (7认同)
  • 为了完整起见,是否一直都是这种情况?我的意思是,我知道它有,但是您的参考文献说的是C 2018(即最新版本),因此清楚地说明它不会有什么坏处。 (2认同)

Gov*_*mar 52

在您简单的例子i++对比(i)++,没有任何区别,如埃里克Postpischil的回答说.

但是,如果您*使用运算符取消引用指针变量并使用increment运算符,则这种差异实际上是有意义的; *p++和之间有区别(*p)++.

前一个语句取消引用指针,然后递增指针本身; 后一个语句取消引用指针然后增加解除引用的值.

  • 您的答案归结为"括号可用于强制执行运算符优先级",这很明显,而不是OP所要求的. (10认同)
  • 因此,例如,如果您定义一个宏`#define postinc(x)x ++`那么`postinc(*p)`将不会按照函数式表示法执行您所期望的操作.这就是为什么在编写宏时,通常使用大量括号,例如`#define postinc(x)((x)++)` (7认同)
  • @GiacomoAlzetta请记住,SO答案应该对阅读问题的人有用,而不仅仅是OP或已经熟悉被问及的技术的人.根据我的经验,`(expr)++`的最常见用法是增加一个去引用的值,因此给初学者一个'expr ++`等效的印象是有害的. (7认同)
  • @GiacomoAlzetta对这个答案进行了长时间的讨论,并通过审核予以删除.缺点是我觉得解释这个特殊的细微差别非常重要,因为特别混合这两个表达式是C中初学者的常见错误来源. (3认同)
  • @SolomonUcko不,第一个会取消引用指针然后递增它.第二个会增加指针,然后取消引用它. (3认同)
  • @SolomonUcko当然,`(*p ++);` (2认同)