C ++*p++无法理解优先顺序
运行此代码:C ++*p++无法理解优先顺序,c,pointers,operator-precedence,C,Pointers,Operator Precedence,运行此代码: #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 31。作为记录,我是编程新手,似乎我真的无法掌握窍门,如果这个问题很愚蠢,那么很抱歉:首先递
#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 31。作为记录,我是编程新手,似乎我真的无法掌握窍门,如果这个问题很愚蠢,那么很抱歉:首先递增p指向的位置,然后将指针向前移动1 p指向20,因此+20=21 然后指针将增加一次,因此,它将指向数组中20的下一个元素,即30 正如M.M所说,你把评估的顺序和优先顺序搞混了。阅读更多信息。首先递增p指向的位置,然后将指针向前移动1 p指向20,因此+20=21 然后指针将增加一次,因此,它将指向数组中20的下一个元素,即30
正如M.M所说,你把评估的顺序和优先顺序搞混了。更多有关它的内容。 < P>从C++标准中,C标准同样有效。 5.2后缀表达式 1后缀表达式组从左到右 后缀表达式和p++是后缀表达式,其优先级高于一元表达式 <> C++标准 5.3一元表达式 1带一元运算符的表达式从右向左分组 在这个表达式+++*p中有两个一元子表达式:*p和+++*p 所以整个表达式可以写成
++( *( p++ ) );
考虑到后缀表达式+,现在它是C标准
6.5.2.4后缀递增和递减运算符
2后缀++运算符的结果是操作数的值。
作为一种副作用,操作数对象的值的增量为
是,则会向其添加相应类型的值1
让我们考虑表达式语句
的结果++( *( p++ ) );
子表达式p++的操作数值是数组第一个元素int*类型的地址。然后由于解引用,表达式*p++产生数组第一个元素的左值,即x[0],然后其值增加。所以arry的第一个元素现在的值是21
同时,后缀增量增加了指针p,这是它的副作用,请参见上面引用的C标准。它现在指向数组的第二个元素
因此,输出将是
21 30
从C++标准中,C标准
同样有效。 5.2后缀表达式 1后缀表达式组从左到右 后缀表达式和p++是后缀表达式,其优先级高于一元表达式 <> C++标准 5.3一元表达式 1带一元运算符的表达式从右向左分组 在这个表达式+++*p中有两个一元子表达式:*p和+++*p 所以整个表达式可以写成++( *( p++ ) );
考虑到后缀表达式+,现在它是C标准
6.5.2.4后缀递增和递减运算符
2后缀++运算符的结果是操作数的值。
作为一种副作用,操作数对象的值的增量为
是,则会向其添加相应类型的值1
让我们考虑表达式语句
的结果++( *( p++ ) );
子表达式p++的操作数值是数组第一个元素int*类型的地址。然后由于解引用,表达式*p++产生数组第一个元素的左值,即x[0],然后其值增加。所以arry的第一个元素现在的值是21
同时,后缀增量增加了指针p,这是它的副作用,请参见上面引用的C标准。它现在指向数组的第二个元素
因此,输出将是
21 30
根据C运算符的优先级,后缀增量首先出现
优先级与求值顺序不是一回事
优先级控制哪些运算符与哪些操作数分组。在本例中,表达式为+++*p++;被解析为+++*p++
评估的顺序是
评价p++;这个评估的结果是&x[0],副作用是将p推进到x[1];
取消引用1的结果;本次评估结果为x[0];
将前缀++运算符应用于2的结果;此计算的结果是x[0]+1,其副作用是存储在x[0]中的值递增。
记住,副作用不必在评估后立即应用;它们可以推迟到序列点
根据C运算符的优先级,后缀增量首先出现
优先级与求值顺序不是一回事
优先权
控制哪些运算符与哪些操作数分组。在本例中,表达式为+++*p++;被解析为+++*p++
评估的顺序是
评价p++;这个评估的结果是&x[0],副作用是将p推进到x[1];
取消引用1的结果;本次评估结果为x[0];
将前缀++运算符应用于2的结果;此计算的结果是x[0]+1,其副作用是存储在x[0]中的值递增。
记住,副作用不必在评估后立即应用;它们可以推迟到序列点 你把优先级和求值顺序搞混了。优先级是指确定每个运算符的操作数的过程;例如,优先级告诉我们后缀-++是递增的p,而不是*p。优先级并不能说明这样的增量是发生在任何其他邻近操作之前还是之后。@VidorVistrom:这是一个糟糕的类比,因为表达式的实际增量时间未指定。一个方便的参考可能会有所帮助。注意联想我对编程还不熟悉,似乎我真的不懂它的窍门。老实说,我不知道+++*p++是如何工作的,但最重要的是我不想知道。你也不应该。首先,您永远不会编写这样的代码。其次,您几乎永远不会遇到这样的代码。如果你不幸遇到了这个问题,那么你只需诅咒作者,必要时重构它,然后继续。我的建议是:别担心。在现实生活中,清晰是代码最重要的方面之一。@bolov:你也不应该这样做。-这甚至不是坏建议!程序员当然应该知道!与其说是问题中的具体表达,不如说是理解为什么它会这样工作!在这方面,表达式是有用的。您将优先级与求值顺序混淆了。优先级是指确定每个运算符的操作数的过程;例如,优先级告诉我们后缀-++是递增的p,而不是*p。优先级并不能说明这样的增量是发生在任何其他邻近操作之前还是之后。@VidorVistrom:这是一个糟糕的类比,因为表达式的实际增量时间未指定。一个方便的参考可能会有所帮助。注意联想我对编程还不熟悉,似乎我真的不懂它的窍门。老实说,我不知道+++*p++是如何工作的,但最重要的是我不想知道。你也不应该。首先,您永远不会编写这样的代码。其次,您几乎永远不会遇到这样的代码。如果你不幸遇到了这个问题,那么你只需诅咒作者,必要时重构它,然后继续。我的建议是:别担心。在现实生活中,清晰是代码最重要的方面之一。@bolov:你也不应该这样做。-这甚至不是坏建议!程序员当然应该知道!与其说是问题中的具体表达,不如说是理解为什么它会这样工作!在这方面,表达式是有用的。你能解释一下+++*p++的答案被*p++替换并与之相关吗?如果我理解清楚的话,OP不会问@ShashwatKumar这个问题。当*p递增时,没有指定。p本身也是如此。这正是OP所困惑的事情之一。这是你的答案应该提供的一个非常重要的东西。你首先增加p指向的位置,然后把指针向前移动1。事实上是错的。我不确定我是否明白。{int*t=p++;++*t;}不能同时满足6.5.2.4.2的要求。后缀++运算符的结果是操作数的值。对于+++*p++,同时使用运算符优先级。这里,优先级和6.5.2.4要求p++等于p,在某个点上有p+1的副作用*p在这一点上是20,除非你说副作用可以应用于计算后缀操作符和应用解引用操作符之间。这就是你所说的吗?你能解释一下+++*p++被*p++替换的答案吗?如果我理解的很好,OP不是问@ShashwatKumar这个问题的。当*p增加时没有指定。p本身也是如此。这正是OP所困惑的事情之一。这是你的答案应该提供的一个非常重要的东西。你首先增加p指向的位置,然后把指针向前移动1。事实上是错的。我不确定我是否明白。{int*t=p++;++*t;}不能同时满足6.5.2.4.2的要求。后缀++运算符的结果是操作数的值。对于+++*p++,同时使用运算符优先级。这里,优先级和6.5.2.4要求p++等于p,在某个点上有p+1的副作用*p在这一点上是20,除非你说副作用可以应用于计算后缀操作符和应用解引用操作符之间。你是这么说的吗?如果我读了
e OP有,这是因为不清楚后缀++运算符的结果是操作数的值。句号,p++的结果就是p。。。作为副作用。。。将相应类型的值1添加到其中。。。表达式完全求值后。实际上,它可以被重构为+++*p;p++@大卫·兰金说得好!我用我糟糕的英语更新了我的帖子。这在理解上是一个很好的练习,但我同意如果编码器实际上是这样编码的,那么应该对其进行射击的评论:如果我读到OP的混淆,那是因为不清楚后缀++运算符的结果是操作数的值。句号,p++的结果就是p。。。作为副作用。。。将相应类型的值1添加到其中。。。表达式完全求值后。实际上,它可以被重构为+++*p;p++@大卫·兰金说得好!我用我糟糕的英语更新了我的帖子。这是理解的一个很好的练习,但我同意如果编码者实际上是这样编码的,那么应该对其进行拍摄的评论: