【问题标题】:Difference between i++ and (i)++ in CC语言中i++和(i)++的区别
【发布时间】:2019-07-21 08:27:36
【问题描述】:
int i = 3;
int j = (i)++;

int i = 3;
int j = i ++;

以上两种情况的评估方式有区别吗?

第一种情况相当于增加一个右值还是未定义的行为?

【问题讨论】:

  • 在宏定义中,括号的随意使用很常见。他们确实有很大的不同,你会喜欢你得到的错误信息。嗯,通常。
  • 整数没有区别。但是,情况并非总是如此,在组合括号和运算符时必须小心,@govin-parmar 展示了一个很好的例子,指针会发生什么。
  • 需要明确的是,这两种情况都是明确定义的(即,不是 UB),并且会将 3 存储在 j 中。
  • 我是不是想多了”是的。

标签: c language-lawyer increment evaluation


【解决方案1】:

i++(i)++ 行为相同。 C 2018 6.5.1 5 说:

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

C 1999 中的措辞相同。

【讨论】:

  • 为了完整性,一直都是这样吗?我的意思是,我知道它有,但是您的参考资料说 C 2018(即最新版本),所以把它拼出来不会有什么坏处。
  • @MrLister 是的,即使是 ANSI C (1978) 之前的版本也有这种行为。它没有正式说明(很少有),但在 K&R 第一版中的一些示例中需要它,例如(*ptr)++
【解决方案2】:

在您的 i++(i)++ 的简单示例中,没有区别,如 Eric Postpischil 的回答中所述。

但是,如果您使用 * 运算符解引用指针变量并使用增量运算符,则这种差异实际上是有意义的; *p++(*p)++ 之间存在差异。

前一条语句取消引用指针,然后增加指针本身;后一条语句取消引用指针,然后递增取消引用的值。

【讨论】:

  • 例如,如果你定义了一个宏#define postinc(x) x++,那么postinc(*p) 将不会按照你所期望的函数式表示法来做。这就是为什么在编写宏时通常会使用大量括号,例如#define postinc(x) ((x)++)
  • 您的答案归结为“括号可用于强制运算符优先级”,这很明显,而不是 OP 所要求的。
  • @GiacomoAlzetta 对此答案进行了长时间的讨论,但已被适度删除。简而言之,我觉得解释这种特殊的细微差别很重要,因为特别是将这两种表达方式混合起来是 C 初学者常见的错误来源。
  • @GiacomoAlzetta 请记住,SO 答案应该对任何阅读该问题的人都有用,而不仅仅是 OP 或已经熟悉所询问技术的人。根据我的经验,(expr)++ 最常见的用法是增加一个取消引用的值,因此给初学者以expr++ 等效的印象是有害的。
  • @SolomonUcko 不,第一个会取消引用指针然后增加它。第二个将增加指针然后取消引用它。
猜你喜欢
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 2017-10-23
  • 1970-01-01
  • 2011-08-06
  • 2014-12-25
  • 1970-01-01
相关资源
最近更新 更多