运行此代码:
#include <stdio.h>
int main() {
int x[]={20,30};
int *p=x;
++*p++;
printf("%d %d\n",x[0],*p);
return 0;
}
输出是21 30,这对我来说没有意义,因为根据C运算符优先级,后缀增量首先出现,但如果在我看来输出应该是20的情况。对于记录我我是编程的新手,我似乎无法掌握它,如果这个问题是愚蠢的话,很抱歉:)
答案 0 :(得分:8)
来自C ++标准(同样适用于C标准)
5.2后缀表达式 1个后缀表达式组从左到右。
后缀表达式和p++
是后缀表达式,其优先级高于一元表达式。
C ++标准
5.3一元表达式 1具有一元运算符组的表达式从右到左。
在此表达式++*p
中,有两个一元子表达式:*p
和++( *p )
因此整个表达式可以写成
++( *( p++ ) );
考虑后缀表达式++(现在是C标准)
6.5.2.4后缀增量和减量运算符
2 postfix ++运算符的结果是操作数的值。 作为副作用,操作数对象的值递增(即 是,相应类型的值1被添加到它)。
让我们考虑表达式语句的结果
++( *( p++ ) );
子表达式p++
具有其操作数的值,该值是数组第一个元素的类型int *
的地址。然后由于解除引用,表达式*( p++ )
产生数组的第一个元素的左值x[0]
,然后它的值增加。所以arry的第一个元素现在的值为21。
同时后缀增量使指针p
增加为副作用(参见上面C标准的引用)。它现在指向数组的第二个元素。
因此输出将是
21 30
答案 1 :(得分:2)
首先递增p
指向的位置,然后将指针推进一个。
因此,p
指向20,因此++ 20 = 21。
然后指针将增加一次,由于pointer's arithmetic,它将指向数组中20的下一个元素,即30。
正如M.M所说,你很困惑,评估顺序优先。阅读更多相关信息here。
答案 2 :(得分:1)
根据C运算符优先级,后缀增量首先出现
优先级与评估顺序不同。
优先级控制哪些运算符与哪些操作数组合在一起。在这种情况下,表达式++*p++;
被解析为++(*(p++))
。
评估顺序是
p++
;此评估的结果为&x[0]
,副作用是将p
提升为x[1]
; x[0]
; ++
运算符应用于结果2;此评估的结果为x[0] + 1
,副作用表示存储在x[0]
中的值会递增。 请记住,评估后不必立即应用副作用;它们可能会推迟到序列点。