C语言中i++和(i)++的区别
Posted
技术标签:
【中文标题】C语言中i++和(i)++的区别【英文标题】:Difference between i++ and (i)++ in C 【发布时间】:2019-07-21 08:27:36 【问题描述】:int i = 3;
int j = (i)++;
对
int i = 3;
int j = i ++;
以上两种情况的评估方式有区别吗?
第一种情况相当于增加一个右值还是未定义的行为?
【问题讨论】:
在宏定义中,括号的随意使用很常见。他们确实有很大的不同,你会喜欢你得到的错误信息。嗯,通常。 整数没有区别。但是,情况并非总是如此,在组合括号和运算符时必须小心,@govin-parmar 展示了一个很好的例子,指针会发生什么。 需要明确的是,这两种情况都是明确定义的(即,不是 UB),并且会将 3 存储在j
中。
“我是不是想多了”是的。
【参考方案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 不,第一个会取消引用指针然后增加它。第二个将增加指针然后取消引用它。以上是关于C语言中i++和(i)++的区别的主要内容,如果未能解决你的问题,请参考以下文章