优先级和结合律
http://c.biancheng.net/view/285.html
经查表,首先 * 与 ++ 的优先级是一样的,根据编译原理应当遵守靠右的规则,所以
*p++ = *(p++)
*p++和 *++p的区别
int a[4] = {1,10,100};
int *p = a;
printf("%d\n",*p++); //输出结果为1
printf("%d",*++p); //输出结果为100
}
p++ 分解步骤如下:
1、 首先与()优先级一样,所以 *(p++) 等价于 *p++ ,但是i++模式是先使用i的,所以应该先使用p,然后在对p进行自增操作
2、因此先取p的值,为1,打印出来
3、然后在对p++,即指针右移,指向10的位置
一句话解释 即temp = *p; p = p + 1;
*++p 分解步骤如下:
1、前面的 *p++ 已经导致指针右移到了10的位置
2、分解为 *(++p),这个时候使用括号是为了方便理解,按照++i模式,应该先对p进行自增,然后使用p
3、因此先执行++p 对指针p进行右移
4、然后对指针进行取值操作得到100,打印出来
一句话解释 即 p=p+1; temp=*p;
————————————————
https://blog.csdn.net/weixin_43864619/article/details/107310735
例题
int main(){
int a[10]={32,1,23,40,6,1,5,3,4,2},i;
int *p;
p=a;
printf("%d\n",(*p++));
printf("%d\n",*p);
printf("%d\n",(*(p++)));
printf("%d\n",*p);
// fun(b,10);
for(i=0;i<10;i++)printf("%3d",a[i]);
}
第一行,printf(“%d\n”,(*p++));
对于(p++):先取p进行输出,即为32,然后计算p++
第二行,printf(“%d\n”,*p);
此时p在第二个数字上,输出1
第三行,printf(“%d\n”,(*(p++)));
先取p,然后再++,所以先进行 *p取值输出1,然后再p后移一位
第四行 printf(“%d\n”,*p);
此时输出23
由此可知
*p++表示,p++后取值
易错题
int main(){
int a[5]={1,3,5,7,9};
int *q=a;
int n=5;
for(int i=0;i<n;i++){
printf("%3d->",*q);
(*q++)++;
printf("%3d",*q);
printf("\n");
for(int k=0;k<5;k++)printf("%3d",a[k]);
printf("\n");
}
printf("\n");
for(int i=0;i<5;i++)printf("%3d",a[i]);
}
(*q++)++即为 ( *(q++))++
先执行q++,先取q, 即(*q)++,然后q++
#include<stdio.h>
#include<math.h>
#include <string.h>
int fun(int x,int y){
static int m=0,i=2;
i+=m+1;
m=i+x+y;
return m;
}
int main(){
int a[5]={10,20,30,40,50};
int *p=a+1;
printf("%d",*p++);//*p++,从右向左,先p++,取p,*p,然后p=p+1
printf("%d",*p);
}
二位矩阵(*p)[n]
int main(){
int a[4][5]={{1,2,3,4,5},{1000,7,100,9,10},{11,12,13,14,15},{16,17,18,19,20}};
int (*p)[5]=a;
printf("%d\n",**p++);//1
printf("%d\n",**p);//1000
printf("%d\n",(*(p+1))[4]);//15
printf("%d\n",**(p+1));//11
printf("%d\n",*p[0]+2);//1002
printf("%d\n",p[0][0]);//1000
printf("%d\n",*(*a+1));//2
printf("%d\n",*(a[3]+1));//17
printf("%d\n",**(a+1)+1);//1001
}
**p++先取值 ,即取 a[ 0] [0],得到1,然后p++指向下一个地址,即p这回指向第二行
此时, **p为1000。
p在第二行,所以此时, *(p+1))[4] 先第三行第五个值
p在 第二行 ,所以此时, **(p+1))为第三行第一个值
p在 第二行 ,所以此时,*p[0]+2,先取第二行第一个值,再在值上加2,
即为 a[1][0]+2=1000+2=1002
*(*a+1)表示a[0][1]
*(a[3]+1)表示a[3][1]
**(a+1)+1表示a[1][0]+1
结构体+指针
struct st{
int n;
};
struct st b[3]={10,13,15},*p;
p=&b[0];
printf("%d\n",p->n);//10
printf("%d\n",p++->n);//10
printf("%d\n",p->n);//13
printf("%d\n",++p->n);//13
printf("%d\n",p->n);//14
printf("%d\n",p->n++);//14
printf("%d\n",p->n);//15
由此可见,->和++放在一起是从左向右运算,而且->的优先级更高
int main(){
struct st{
int age;
int num;
};
struct st std,*p;
p=&std;
std={12,19};
printf("%d\n",p->age);//12
printf("%d\n",(*p).age);//12
printf("%d\n",std.age);//12
}
*p.age报错,因为.的优先级高于->
#include<stdio.h>
int main(){
struct st{
int num;char flag;char adr[20];
}rec[10],*p=rec;
scanf("%s",&rec[0].adr);
scanf("%s",&(*p).adr);
scanf("%d\n",&(*p).num);
scanf("%c",&p->flag);
}
scanf(“%s”,&rec.adr);报错。 scanf(“%s”,&rec[0].adr);正确
scanf(“%s”,&p.adr);报错。scanf(“%s”,&(*p).adr);正确
p->flag , (*p).flag , rec[0].adr正确
习题
#include<stdio.h>
int main(){
struct st{
int n;
struct st *next;
};
static struct st a[3]={5,&a[1],7,&a[2],9,'\0'},*p;
p=&a[0];
printf("%d\n",p->n);//5
printf("%d\n",p++->n);//5
printf("%d\n",p->n);//7
printf("%d\n",p++->n);//7
printf("%d\n",p->n);//9
printf("%d\n",p++->n);//9
printf("%d\n",p->n);//0
}
#include<stdio.h>
int main(){
struct st{
int n;
struct st *next;
};
static struct st a[3]={5,&a[1],7,&a[2],9,'\0'},*p;
p=&a[0];
printf("%d\n",p->n);//5
printf("%d\n",p->n++);//5
printf("%d\n",p->n);//6
printf("%d\n",p->n++);//6
printf("%d\n",p->n);//7
printf("%d\n",p->n++);//7
printf("%d\n",p->n);//8
}