目录
1、一维数组传参
调用方式以及传递参数如下,我们需要考虑的是如何设计这个函数,不同的理解方式会有不同的设计方式。下面就从两个角度来设计
int main()
{
int arr[10] = {0};
test(arr); //需要设计的函数是test函数,传递的参数是数组名arr,即首元素地址
}
============ 角度一:传递的是数组 ============
这边传递的是数组名,我们就当作是传了一个数组过去,那函数的形参也需要用数组来接收了,那么函数形参可以这样设计:
void test(int arr[]) // 方式一
{}
void test(int arr[10]) // 方式二
{}
void test(int arr[100]) // 方式三(语法没问题但是不推荐,让人容易误解)
{}
需要注意的是,形参里数组的大小没有任何意义 ,之前介绍函数栈帧开辟的过程提到,形参只有在需要用到的时候才会被创建,然后去找实参在栈上的地址。
============ 角度二:传递的是指针 ============
数组名其实就是首元素的地址,所以我们也可以当作是传了一个地址过去,那边使用指针来接收。
test(int* arr)
{}
2、二维数组传参
同样的,调用方式以及传递参数如下,下面我们同样从两个角度来设计
int main()
{
int arr[3][5] = {0};
test(arr); //需要设计的函数是test函数,传递的参数是数组名arr
}
============ 角度一:传递的是数组 ============
传递数组,数组接收,但是需要注意的是,二维数组不能省略列,但是可以省略行,因为二维数组在存储的时候,是先存满一行,然后再存下一行,因此一行有多少列必须要明确。
void test(int arr[3][5]) // 方式一
{}
void test(int arr[][5]) // 方式二
{}
============ 角度二:传递的是指针 ============
传递地址,指针接收。数组名表示首元素地址,这个没错,但是二维数组的首元素地址不是第一行第一列的元素的地址,而是第一行的地址!
也就是说,如果我们要以指针的形式传递二维数组的话,其实传递的是第一行的数组的地址,此时我们就可以使用 数组指针。声明数组指针的时候,我们需要知道,指向的数组有多大(大小是5),数组元素类型是什么(int类型)
- 首先声明一个变量ptr,这个变量是指针类型,即 *ptr
- 然后指向一个数组,数组大小是5,即 *ptr[5]
- 最后补上这个数组的元素类型,即 int *ptr[5]
void test(int (*ptr)[5])
{}
// void test(int** arr) //error
// {}
为什么不合适呢?你要用一个二级指针去接收一个数组的地址,这肯定是不行的,如果你用一个二级指针去接收一个一级指针变量的地址,指针接收指针地址,这个是没有问题的。