当您取消引用后增量C时会发生什么

我收到了很多相互矛盾的答案。 但正如我一直理解的那样。

当我们在C中有一个指针并在后增量语句中使用它时,后增量将始终在代码行结算后发生。

int array[6] = {0,1,2,3,4,5}; int* p = array; printf("%d", *p++); // This will output 0 then increment pointer to 1 

输出:

 0 

非常简单的东西。 现在,我正在接受人们告诉我的信息和我自己的经历中的一些不和谐。

 // Same code as Before int array[0] = {0,1,2,3,4,5}; int* p = array; printf("%d", *(p++)); // Issue with this line 

输出:

 0 

现在,当我运行代码的第二个版本时结果是它将输出0然后递增指针。 括号隐含的操作顺序似乎被违反了。 然而,这个网站上的其他一些答案告诉我,应该发生的正确的事情是增量应该在取消引用之前发生。 所以我想我的问题是:我的理解是否正确? post post increment语句总是在行尾执行吗?

附加信息:

我正在使用gcc版本ubuntu 4.8.4在linux mint上编译gcc

我也在debian上使用版本debian 4.7.2在gcc上测试了这个

OP的“结果是它将输出0 THEN递增指针。” 是不正确的。

后缀增量返回指针的值。 将此值视为原始指针值的副本。 指针递增,不影响复制。

postfix ++运算符的结果是操作数的值。 作为副作用,操作数对象的值递增。 …… C11dr 6.5.2.4 2

然后取消引用指针的副本并返回0 。 这是事件的function序列。

由于递增指针和取消引用指针副本的副作用不会相互影响,因此首先出现哪一个是无关紧要的。 编译器可以根据需要进行优化。

“行尾”不涉及代码。 表达的结尾很重要。

*p++*(p++)之间的含义没有区别。

这是因为后缀运算符的优先级高于一元运算符。

这两个表达式都意味着“ p递增,其先前值被解除引用”。

如果要增加指针引用的对象,则需要通过编写(*p)++来覆盖优先级。

没有版本的代码可以产生输出, 然后增加p 原因是p参数表达式中递增,该表达式产生一个传递给printf的值。 在C中,序列点恰好在调用函数之前发生。 所以p的新值必须在printf执行之前就位。 并且在调用printf之前不能输出。

现在,你必须带上一点点盐。 由于p是局部变量,因此修改它不是外部可见效果。 如果p的新值未在任何地方使用,则可以完全优化增量。 但是假设我们有一个int * volatile p; 在文件范围,并使用它。 然后表达式printf("...", *p++)必须在调用printf之前递增p

表达式p++有一个结果 (增量前的p值)和副作用p的值更新为指向int类型的下一个对象)。

Postfix ++优先级高于一元* ,因此*p++已被解析为*(p++) ; 你会发现这两种forms之间的行为没有区别。 IOW,dereference运算符应用于p++结果 ; 这条线

 printf("%d", *p++); 

大致相当于

 printf("%d", *p); p++; 

需要注意的是,在调用printf 1之前, p实际上会更新。

但是, (*p)++ 有所不同; 而不是递增指针,你正在增加p 指向的东西。


1.必须在下一个序列点之前应用++--运算符的副作用,在此特定情况下,在计算函数参数和调用函数本身之间。

这是我对此的看法。 让我们完全忽略printf函数并使事情变得更简单。

如果我们说

 int i; int p=0; i = p++; 

那么我将等于零,因为p等于零,但现在p增加了1; 所以现在我仍然等于零,p等于1。

忽略i和p作为整数的声明,如果我们在示例中包装它, i = *(p++) ,则会发生相同的动作,但我现在包含p指向的值,其值为零。 但是,现在p的值已增加1。