摘要:总结了数组指针传递给函数为什么会退化为指针,二维数组参数在传递的时候需要注意哪些地方,最后给出两个实例加深理解。
一、数组作为参数为什么会退化为指针
1.C语言之中只会以值拷贝的方式传递参数,指针其实传递的也是值,只不过里面是地址罢了。那么加入我们需要向函数传递一个数组或者比较大的结构体的时候,是将整个数组都拷贝过去吗?是将整个结构体都拷贝过去吗?显然不是的。。。如果那样的话,我们定义一个a[10000],那么一个参数传递就要拷贝一万次,这样效率是很低的。
2.C语言设计之初是以高效为目的,所以它将数组名看做常量指针,只将数组首元素的地址传递给函数,这样通过指针,函数就可以找到这个数组,并加以使用。
二、二维数组参数
1.二维数组参数同样存在退化的问题,本质上,二维数组是按照一维数组在内存中排列的,二维数组中的元素都是一维数组。
2.二维数组参数中的第一维可以省略,但是第二维无论如何都不可以省略。
退化为指针的规则如下:总结就是将靠近数组名的方框,放到数组名左边去,加上*号即可,但是我还是按照理解去记忆的,如果理解不了就只有这个死方法了。
一维:
void f(int a[5])->void f(int a[])->void f(int* a)
二维:
void g(int a[3][3])-> void g(int a[][3])-> void g(int (*a)[3])
红色字体标注出来的,其实退化的是一个数组指针。
下面这个表也可以给出等价关系:
float a[5]->float* a;
int* a[5]->int** a;
char a[3][4]->char (*a)[4];
三、注意事项
1.C语言中无法向一个函数传递任意的多维数组。
一维:必须提供一个标志数组结束位置的长度信息,所以我们在传递给函数之前,必须给出一维数组的长度。
二维:不能直接传递给函数。
三维:用不到,无法传递。
2.为了提供正确的指针运算,必须提供除了第一维以外的所有维的长度。
下面这两个例子演示如何传递二维数组的参数:
<span style="font-size:18px;">例子1
#include <stdio.h>
#include <unistd.h>
void f(int (*p)[3])//这里二维指针传进来,第二维的信息不能省略,传进来的本质是一个数组指针
{
printf("%d\n",(*(p+1))[2]); //第二行的第三个数,就是5啦,这里复习下指针运算
printf("%d\n",(*p)[1]);//第一行的第二个数,就是1
}
int main(void)
{
int a[3][3]={{0,1,2},{3,4,5},{6,7,8}};
f(a);
return 0;
}
运行结果是:
5
1
例子2
#include <stdio.h>
void access(int (*p)[3],int row)
{
int col=sizeof(*p)/sizeof(int);
int i;
int j;
printf("sizeof(p):%d\n",sizeof(p));
for(i=0;i<row;i++)
for(j=0;j<col;j++)
{
printf("%d",(*(p+i))[j]);
}
printf("\n");
}
int main(void)
{
inta[3][3]={{0,1,2},{3,4,5},{6,7,8}};
access(a,3);
return0;
}</span>
主要看输入参数的,虽然没有给出列,但是数组指针的类型中其实已经包含了这个信息了。
这篇帖子就总结到这里,如有不正确的地方还请指出,大家共同进步!