c语言---指针

优先级和结合律

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
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值