目录
调用方式以及传递参数如下,我们需要考虑的是如何设计这个函数,不同的理解方式会有不同的设计方式。下面就从两个角度来设计
- 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)
- {}
同样的,调用方式以及传递参数如下,下面我们同样从两个角度来设计
- int main()
- {
- int arr[3][5] = {0};
- test(arr); //需要设计的函数是test函数,传递的参数是数组名arr
- }
============ 角度一:传递的是数组 ============
传递数组,数组接收,但是需要注意的是,二维数组不能省略列,但是可以省略行,因为二维数组在存储的时候,是先存满一行,然后再存下一行,因此一行有多少列必须要明确。
- void test(int arr[3][5]) // 方式一
- {}
-
- void test(int arr[][5]) // 方式二
- {}
============ 角度二:传递的是指针 ============
传递地址,指针接收。数组名表示首元素地址,这个没错,但是二维数组的首元素地址不是第一行第一列的元素的地址,而是第一行的地址!
也就是说,如果我们要以指针的形式传递二维数组的话,其实传递的是第一行的数组的地址,此时我们就可以使用 数组指针。声明数组指针的时候,我们需要知道,指向的数组有多大(大小是5),数组元素类型是什么(int类型)
- void test(int (*ptr)[5])
- {}
- // void test(int** arr) //error
- // {}
为什么不合适呢?你要用一个二级指针去接收一个数组的地址,这肯定是不行的,如果你用一个二级指针去接收一个一级指针变量的地址,指针接收指针地址,这个是没有问题的。