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("
");
 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 10
typedef 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	", arr->a[i][j]);
        }
        printf("
");
    }
}
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("
");
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     //free
32     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就被销毁, 因此该段内存没有被释放,也没法被释放, 因此就造成内存泄露。

原文地址:https://www.cnblogs.com/monicalee/p/3834649.html