首页 > 代码库 > 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就被销毁, 因此该段内存没有被释放,也没法被释放, 因此就造成内存泄露。