1. 数组参数退化为指针的意义
(1)C语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C语言以高效作是最初的设计目标,所以这种方法是不可取的。
(2)参数位于栈上,太大的数组拷贝将导致栈溢出。
(3)将数组名看做常量指针,传递的是数组的首元素地址,而不是整个数组。
2. 二维数组参数
(1)二维数组参数同样存在退化的问题:
-
- 二维数组可以看做是一维数组,其中的每个元素又是一个一维数组
(2)二维数维参数中第一维的参数可以省略
①void f(int a[5])←→void f(int a[])←→void f(int* a) 一维数组参数
②void g(int a[5][3])←→void g(int a[][3])←→void g(int (*a)[3]); 二维数组参数
(3)等价关系
数组参数 |
等效的指针参数 |
备注 |
一维数组:float a[5] |
指针:float* a |
相当于数组去掉第1维,然后把数组名前加上*。 |
指针数组:int* a[5] |
指针的指针:int** a; |
|
二维数组:char a[3][4] |
数组的指针:char(*a)[4] |
(4)被忽视的知识点
①C语言中无法向一个传递任意多维数组。换一句话讲,形参int a[][3]是合法的,但int a[][]是非法的。
②因此,必须提供除第1维之外的所有其他维长度。第一维之外的维度信息用于完成指针运算。
【实例分析】传递与访问二维数组
1 #include <stdio.h> 2 3 4 5 void access(int a[][3],int row) //a[][3],形参第2维的长度必须提供 6 7 { 8 9 int col = sizeof(*a)/sizeof(int); 10 11 12 13 int i = 0; 14 15 int j = 0; 16 17 18 19 printf("sizeof(a) = %d ",sizeof(a)); //指针,4字节 20 21 22 23 //a为int (*a)[3]类型,即a指向一个有3个int型元素的数组 24 25 printf("sizeof(*a) = %d ",sizeof(*a));//3*4 =12字节 26 27 28 29 for(i = 0;i < row; i++) 30 31 for(j = 0; j < col; j++) 32 33 { 34 35 printf("%d ", a[i][j]); 36 37 } 38 39 40 41 printf(" "); 42 43 } 44 45 46 47 void access_ex(int b[][2][3],int n) //数组参数的第2、3维长度必须提供 48 49 { 50 51 int i = 0; 52 53 int j = 0; 54 55 int k = 0; 56 57 58 59 printf("sizeof(b) = %d ",sizeof(b)); //指针,4字节 60 61 62 63 //b为int (*b)[2][3]类型,即b指向一个有2行3列int型元素的二维数组 64 65 printf("sizeof(*b) = %d ",sizeof(*b));//2 * 3 * 4 = 24字节 66 67 68 69 for(i = 0;i < n; i++) 70 71 for(j = 0; j < 2; j++) 72 73 for(k = 0; k < 3; k++) 74 75 { 76 77 printf("%d ", b[i][j][k]); 78 79 } 80 81 82 83 printf(" "); 84 85 } 86 87 88 89 int main() 90 91 { 92 93 int a[3][3] = {{0, 1, 2},{3, 4, 5},{6, 7, 8}}; 94 95 int aa[2][2] = {0}; 96 97 int b[1][2][3] = {0}; 98 99 100 101 access(a, 3); 102 103 //access(aa,2);//error,int(*)[2]与int (*)[3]类型不匹配 104 105 106 107 access_ex(b, 1); 108 109 //access_ex(aa,2);//int(*)[2]与int(*)[2][3]类型不匹配 110 111 112 113 return 0; 114 115 }
3. 小结
(1)C语言中中会以值拷贝的方式传递参数
(2)C语言中的数组参数必然退化为指针
(3)多维数组形参,必须提供除第1维之外的所有维长度。
(4)对于多维数组的函数参数,只有第一维是可变的(即无需提供)