本文介绍一维数组和二维数组作为实参,形参的接受方式。
首先说结论,一维数组传参时,形参既可以是数组形式,也可以是指针形式。
假设有以下代码
int main()
{
int arr[10]={0}; //定义一个整型数组arr,数组中每个元素的类型均为int
int *arr2[10]={0}; //定义一个指针数组arr2,数组中的每个元素的类型均为int*
test(arr); //将arr传参给test函数
test2(arr2); //将arr2传参给test2函数
}
void test(int arr[])
{
}
这种传参方式当然可行,形参用一个数组接受天然可行。因为实参只是arr,即数组首元素的地址,所以接受的时候并非整个数组传过去,因此可以省略大小。那么这里的arr[]只是便于大家理解,写成了数组的形式。其实本质上是个指针。
void test(int arr[10])
{
}
如上所说,arr[10]中的10可以省略。你写成10,100,1000都行,原因还是因为本质上test函数接受的并非整个数组,而是数组首元素的地址,所以不会根据数组大小去创建真正的数组。
void test(int *arr)
{
}
因为形参传的是数组首元素的地址,既然是一个地址,所以我用指针接受当然可行。
void test2(int *arr[])
{
}
int * arr2[10]={0}; 这条语句代表创建了一个指针数组arr2,数组有10个元素,每个元素的类型为int* ,并全部初始化为0。因此,我形参接受的时候也用一个指针数组类型接受,合情合理呀。
void test2(int **arr)
{
}
arr2为一个指针数组类型,里面放的是指针。arr2代表这个指针数组的首元素的地址。arr2这个地址,存放的是一个int* 类型的指针。存放指针的地址,就是一个二级指针。因此实参本质上是一个二级指针,那形参我用一个二级指针接受当然可以。
首先请注意:二维数组首元素的地址为第一行的地址,即整个一维数组的地址。
代码如下(示例):
int main()
{
int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{10,11,12,13,14} }
test(arr);
}
void test(int arr[3][5])
{
}
二维数组传参,我用一个二维数组接受,天然可以。
void test(int arr[][5])
{
}
注意二维数组的行能省略,列不能省略。且5要和形参的数组列相同。这是因为形参arr代表二维数组的首地址,即整个一维数组的地址,所以我必须知道地址结束的地方。因此5不能省略。
void test(int (*p)[5])
{
}
首先arr是二维数组的数组名,数组名代表首元素的地址。
二维数组的首元素,就是二维数组的第一行。(即例子中的{1,2,3,4,5})
因此arr就代表了二维数组中第一行的地址!!(即例子中的{1,2,3,4,5}的地址!)
既然实参是一个一维数组的地址,所以我只能用一个数组指针类型去接收。数组指针指的是指向数组的指针,依然为一个指针,存放的是整个数组的地址。
void print(int(*p)[5], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
printf("%-4d", *(*(p + i) + j));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{10,11,12,13,14} };
print(arr, 3, 5);
return 0;
}
在这里,有必要具体解释下这行语句:*(*(p + i) + j
这里p+i相当于第i行的地址,*(p+i)相当于拿到了第i行的数组名。因为对整个数组的地址解引用就相当于拿到了这个数组名。(*p= * &arr=arr,其中星号 * 和取地址号&可以抵消。)
以上就是一维数组传参和二维数组传参的一些方法。