指针传参的总结实验

数组向指针传递

#define R 2
#define C 2
text(int** pp) {
	printf("%d\n", **pp);
	printf("%d\n",*(*pp+1*R+1));
}

main() {
	int a[R][C] = { {1,2},{3,4} };
	int* p = &a[0][0];
	text(&p);
}

如上图所示,二级指针是一个指向指针的指针,它所保存的内容是一级指针的地址
它通过两次解引用间接访问指针p所指向的内存中的值,也就是1

当我想要使用它访问这个数组中的4时,如果使用数组,它会是这样的a[1][1],而在这个例子中使用指针访问它就需要使用这样的一个定位公式*(*pp+i*R+n),我们会发现,这与使用一级指针访问内存时的公式*(p+i*R+n)十分相似,其实他们是一样的,使用二维时多了一步解引用的操作

但是在使用二维指针时,我们想,像a[0][0]到a[1][1]这样的方式去移动指针,而不是像使用一级指针一样去使用二级指针,那么可以使用下面这种方式,用指针数组指向a的第一维度,并将它们储存在一个连续的内存中

text(int** pp) {
	printf("%d\n", **pp);
	printf("%d\n", *(*(pp + 1) + 1));
}

main() {
	int a[2][2] = { {1,2},{3,4} };
	int *p[2];
	p[0] = &a[0][0];
	p[1] = a[1];
	text(&p);
}

上面我使用的指针数组,接下来对数组指针进行一次辨析

text3(int(*p)[]) {
	printf("%d\n", **p);
	printf("%d\n", *(*p+1*R+1));
	printf("address_p=%p\naddress_(*p+1)=%p\n**p=%d\n", p, *p + 1, **p);
}

address_p=008FF908
address_*p=008FF908
address_(*p+1)=008FF90C
**p=1
address_a=008FF908

从实验结果可以看出,对数组指针指向的地址进行移动,它的原理与移动一级指针是一样的

当然我想通过对p本身操作来在内存空间的层次上移动,但是显然用p+1这种方式是不可行的,可以看出它的储存方式与指针数组p[1] = a[1];相同,指针储存的是二维数组中第一个元素的地址,同时也是第一个维度的第一个元素的地址,只有解引用一次后产生的地址才能够被运算,对于int[]*类型的运算是不被允许的,地址操作对应的运算类型是类似于int*,而在用数组指针指向二维数组时,它的首地址p的类型就属于int[]*

那么,既然二级指针只能指向地址的地址,那么我是否可以将a地址的地址直接传参给二级指针&&a[0][0]
显然,这个表达式是不成立的,这里取的并不是地址的地址,而是,在取地址后,对“地址的值”取地址,而这个使用是不合法的

之所以我可以使用二级指针对地址两次间接访问,是因为二级指针所指向的一级指针本身拥有一个确定的地址

数组向数组传递

text5(int p[][R]) {
	printf("%d\n", p[1][1]);
	printf("%d\n", *(*(p + 1) + 1));
	printf("%p\n", p);
}

text4(int p[]) {
	printf("%d\n", *(p + 1 * R + 1));
	printf("%d\n", p[0]);
	printf("address_p[0]=%p\n", p);
}

address_a=004FF99C
address_&a=00A21023
4
1
address_p[0]=004FF99C
4
4
004FF99C

从结果中的地址信息,我可以看出,这个方法的本质还是数组向指针传递
这里的text5(int p[][R])text4(int p[])中声明定义的形参变量是指针

· 第一个text5(int p[][R])中参数的使用是一个类似于指针数组向二级指针传递后的使用
· 第二个text4(int p[])中是与一级指针等价的形参变量

text6(int p[]) {
	int b = 3;
	printf("text6_*p=%d\n", *p);
	printf("text6_*(p+3)=%d\n", *(p+3));
	p = &b;//如果p与一级指针等价,那么该操作合法
	printf("%d\n", *p);

}
main(){
	//部分省略
	text6(a);
	printf("更改text6中指针p的指向的内存位置后a[0][0]=%d\n", a[0][0]);
}

text6_p=1
text6_
(p+3)=4
3
更改text6中指针p的指向的内存位置后a[0][0]=1

可以看出以text5(int p[][R])text4(int p[])形式创建的形参变量属于指针类型,但是可以以数组的形式使用

所以我测试了一下指针是否可以以同样的方式使用

text7(int* p) {
	printf("%d\n", p[0]);
}

*p以数组形式使用时=1

答案是肯定的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoRealScenery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值