首页 > 代码库 > 0709 C语言常见误区----------二维数组做参数
0709 C语言常见误区----------二维数组做参数
总结:
1.二维数组名是指向一位数组的指针,本例中,其类型为 int (*)[4],在传递的过程中丢失了第一维的信息,因此需要将第一维的信息传递给调用函数。
关于二维数组名代表的类型,可通过下面的例子看出。
1 /************************************************************************* 2 > File Name: test_2arr.c 3 > Author:Monica 4 > Mail:liling222@126.com 5 > Created Time: Wednesday, July 09, 2014 PM07:29:55 HKT 6 ************************************************************************/ 7 8 #include <stdio.h> 9 int main(int argc, char* argv[]){10 int arr[10];11 int (*p)[10] = &arr;12 return 0;13 }
编译器通过。
2.任何数组都可以看做是比它低一维的数组组成的数组。例如int a[3][4][5]可以看做是二维数组int b[4][5]组成的一位数组。数组和指针存在等价关系。
int a[10] <=> int * const a;
int a[2][3] <=> int (*const a)[3];
当把数组名作为函数参数传递时, 数组退化为上述同类型的指针。因此传递多维数组时, 必须制定处第一维外的所有维度信息。(引用自高质量C/C++程序设计指南第7章)
3.再写一个传递一位数组的例子。
1 #include <stdio.h> 2 3 void print_arr3(int* a, int len){ 4 int i; 5 for(i = 0; i < len; i ++) 6 printf("%d ", a[i]); 7 printf("\n"); 8 } 9 int main(int argc, const char *argv[])10 {11 int a[5] = {1, 2, 3, 4, 5};12 print_arr3(a, 5);13 return 0;14 }
4.C/C++为什么要把数组传递改写为指针传递呢?(引用自高质量C/C++程序设计指南)
数组在内存中是连续字节存放的, 因此编译器可以通过地址计算来引用数组中的元素。
出于性能考虑。如果把整个数组中的元素全部传递过去, 不仅需要大量的时间来拷贝数组,而且这个拷贝还会占用大量的堆栈空间。
5.采用上述方法传递参数时, 维度已经确定,因此通用性不强,主要有两个解决方案:
用结构体将数组封装起来。
采用动态分配数组直接传递指针变量。
6.对于5的实现例子。
/************************************************************************* > File Name: print_arr2.c > Author:Monica > Mail:liling222@126.com > Created Time: Wednesday, July 09, 2014 PM03:42:43 HKT ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <time.h>#define M 10#define N 10typedef struct tag{ int a[M][N]; int m; int n;}ARR;void print_arr2(ARR* arr){ int i,j; for(i=0; i<arr->m; i++){ for(j=0; j<arr->n; j++){ printf("%d\t", arr->a[i][j]); } printf("\n"); }}int main(){ ARR arr;// arr.a[3][] = {{1,2 3},{3, 4, 5},{3, 4, 7}}; arr.m = 3; arr.n = 4; int i, j; srand(time(NULL)); for(i=0; i<arr.m; i++){ for(j=0; j<arr.n; j++){ arr.a[i][j] = rand()%10; } } print_arr2(&arr); return 0;}
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define M 3 5 #define N 4 6 7 void print_arr4(int** a, int m, int n){ 8 int i, j; 9 for(i = 0; i < m; i++){10 for(j = 0; j < n; j++){11 printf("%d ", a[i][j]);12 }13 printf("\n");14 }15 }16 17 int main(int argc, char* argv){18 int** arr;19 int i, j;20 srand(time(NULL));21 arr = (int **)malloc(M * sizeof(int *));22 for(i = 0; i < M; i ++){23 arr[i] = (int *)malloc(N * sizeof(int));24 }25 for(i = 0; i < M; i++){26 for(j = 0; j < N; j++){27 arr[i][j] = rand()%10;28 }29 }30 print_arr4(arr, M, N);31 //free32 for(i = 0; i < M; i++){33 free(arr[i]);34 }35 free(arr);36 return 0;37 }38
7.关于内存泄露。
内存泄露简单地说就是分配了一段内存空间,但是没有释放,也没有任何指针指向它。例如
void test(){ int * p = (int *)malloc(10 * sizeof(int));}int main(){ test(); return 0;}
test函数中申请了40字节的内存空间,由局部变量p指向, 但是调用完test函数之后p就被销毁, 因此该段内存没有被释放,也没法被释放, 因此就造成内存泄露。