数组向指针传递
#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
答案是肯定的