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

取消引用后增量C时会发生什么,c,pointers,gcc,operator-precedence,C,Pointers,Gcc,Operator Precedence,关于这一点,我收到了很多相互矛盾的答案。但正如我一直理解的那样 当我们在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 0 非常简单的东西。现在,在人们告诉我的信息和我自己的经历中,我收到了一些不和谐的信息 // Same 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
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
现在,当我运行第二个版本的代码时,结果是它将输出0,然后递增指针。括号中隐含的操作顺序似乎被违反了。然而,这个网站上的一些其他答案告诉我,应该发生的正确的事情是,增量应该发生在取消引用之前。所以我想我的问题是:我的理解正确吗?增量后语句是否总是在行尾执行

其他信息:

我在LinuxMint上使用gcc编译,gcc版本为ubuntu 4.8.4


我还使用debian 4.7.2版在debian上的gcc上测试了这一点,
*p++
*(p++)
之间的含义没有区别

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

这两个表达式都表示“
p
递增,其先前的值被取消引用”

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

没有任何版本的代码可以生成输出,然后递增
p
。原因是,
p
在参数表达式中递增,该表达式生成一个传递到
printf
的值。在C语言中,序列点正好出现在调用函数之前。因此,
p
的新值必须在执行
printf
之前固定到位。在调用
printf
之前,无法进行输出。

现在,你必须对上面的内容稍加注意。由于
p
是一个局部变量,因此修改它不是一个外部可见的效果。如果
p
的新值未在任何地方使用,则可以完全优化增量。但是假设我们有一个
int*p在文件范围内,并改为使用它。然后表达式
printf(“…”,*p++)
必须在调用
printf
之前递增
p

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

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

后缀++运算符的结果是操作数的值。作为一个副作用,操作数对象的值会增加。。。C11dr 6.5.2.4 2

然后指针的副本被取消引用并返回
0
。这是事件的功能顺序

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


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

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

如果我们说

int i;
int p=0;
i = p++;
然后我会等于零,因为p等于零,但现在p已经增加了1;现在我仍然等于零,p等于1


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

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

后缀
++
的优先级高于一元
*
,因此
*p++
已被解析为
*(p++)
;你会发现这两种形式在行为上没有区别。这样,解引用运算符应用于
p++
的结果;线路

printf("%d", *p++);
大致相当于

printf("%d", *p);
p++;
需要注意的是,
p
实际上会在调用
printf
1之前更新

然而,
(*p)+
将是不同的;不是增加指针,而是增加
p
指向的对象


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

括号-
所暗示的操作顺序是括号,而不是括号。我想这就是你从上下文中所指的。正确的术语对于良好的沟通至关重要。这真的是没有错误的编译吗?你的数组初始化不正确,你的注释斜杠也不正确。我已经对帖子做了明显的更正。我应该也修复数组声明吗?
I=*p++
相当于
I=*p++
,相当于
(I=*p,p=p+1,I)
后缀增量是一元数operator@nicomp事实上,在计算机科学领域,这是真的,你在学校的注意力很好。然而,在ISO C术语中,我们有“一元表达式”和“后缀表达式”。参见C99 6.5.2“后缀运算符”和6.5.3“一元表达式”。C中“一元运算符”的重要意义在于,它是一元表达式中可能的运算符之一,扮演着该文法中描述的角色