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

  • 相关阅读:
    【BZOJ3993】星际战争(SDOI2015)-二分答案+最大流
    【BZOJ3996】线性代数(TJOI2015)-最小割
    【BZOJ3996】线性代数(TJOI2015)-最小割
    【APIO2010T2】巡逻-贪心+树形DP
    【APIO2010T2】巡逻-贪心+树形DP
    【NOIP2016提高组T2】天天爱跑步-倍增LCA+树上差分
    【NOIP2016提高组T2】天天爱跑步-倍增LCA+树上差分
    【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
    【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
    【POJ1679】The Unique MST-次小生成树(判断最小生成树唯一性)
  • 原文地址:https://www.cnblogs.com/monicalee/p/3834649.html
Copyright © 2020-2023  润新知