首先,这涉及到两个知识点:指针和自加运算符作为前缀和后缀运算符的区别。
为了具体分析,简单的写如下程序:
#include <stdio.h>
//自定一个结构体。指向结构体中的变量是指针用的最多的场合,有典型意义
struct node
{int a;};
int main()
{
struct node array[4]={{0},{1},{2},{3}};//结构体数组 array
struct node *p=array;//结构体指针 p
printf("%d\n",(++p) ->a);
printf("%d\n",(p++)->a);
}
运行结果为:
1
1
运行结构分析:
指针初始时指针结构体数组 array的第0个元素 ,即 p->a=array[0].a=0
语句(++p) ->a ,由于是自加运算作为前缀,要在【执行这条语句时】 p先加一, 即指针p指向了 array的第1个元素array[1],输出结构为1.【执行完这条语句 】p 指向了array[1]。
语句(p++)->a,由于是自加运算符作为后缀,【执行语句时】指针本身不加一,依然指向 array的第1个元素array[1],],(p++)->a=array[1].a=1。.【执行完这条语句 】 p 才加一,指向 arry的第2个元素array[2].
总结:
自加运算符作为前缀运算符,执行所在语句时变量就已经加一。
自加运算符作为后缀运算符,执行完所在语句时变量才加一。
从以上我们可以知道前两者的区别,那后两者呢?在这里我们先来看一组代码。
#include<stdio.h>
int main()
{
struct table {
int x, y;
}a[4]={{10, 20}, {30, 40}, {50, 60}, {70, 80}};
struct table *p = a;
printf("%d,", p++->x); /* 以下输出数据之间没有空格分隔 */
printf("%d,", ++p->y);
printf("%d", (a+3)->x);
}
运行结果:
在这里我们或许有一些疑问,按照上面学过的知识,第二个数不应该是40吗?而结果是41。我们再仔细地看一下代码,前两行输出“p++”和“++p”均没有括号,假如都有括号答案一定是10,60,70(这里小编已经证实过了),因此我们不难得出结论,一定是括号的有无决定了运算的顺序。
这里,小编就不卖关子了,直接说结论吧。
其实,(p++)->a和p++ ->a的作用效果都一样,都是在执行这条语句时,都是输出数组p的第一个元素,然后再进行自加作用(即自加后缀),而(++p) ->a 和 ++p ->a的作用却有很大的区别。我们就题而言,代码中第二行输出的执行过程为:由于第一行的自加后缀作用,p在执行完第一行输出后肯定指向结构体数组的第二个元素(即a[1]),执行开始的时候,p并没有进行自加效应,而是先执行后面的p->y成分,得出40,然后针对于40再进行自加运算而得出最后的结果41。
以上就是第二行输出的执行结果。在这里,我们不妨总结一下,在没有括号的情况下++p-> a中“++”的优先级后于“->”,而“p++ ->a”中“++”的优先级则先于“->”。最后,再奉上一组代码证明此结论。
#include<stdio.h>
int main()
{
struct table {
int x, y;
}a[4]={{10, 20}, {30, 40}, {50, 60}, {70, 80}};
struct table *p = a;
printf("%d,", p++->x); /* 以下输出数据之间没有空格分隔 */
printf("%d,", (++p)->y);//注意加上括号后
printf("%d", (a+3)->x);
}
运行结果:
结果和前两行输出“p++”和“++p”均没有括号的结果一致,所以小编的结论还是挺有说服力的。
如果大家认为小编的结论有误,欢迎私信或者加以评论(这个结论仅供参考),谢谢。