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

  • 相关阅读:
    MOSS中的User的Title, LoginName, DisplayName, SID之间的关系
    如何在Network Monitor中高亮间隔时间过长的帧?
    SharePoint服务器如果需要安装杀毒软件, 需要注意什么?
    如何查看SQL Profiler? 如何查看SQL死锁?
    什么是Telnet
    The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
    Windows SharePoint Service 3.0的某个Web Application无搜索结果
    网络连接不上, 有TCP错误, 如果操作系统是Windows Server 2003, 请尝试一下这里
    在WinDBG中查看内存的命令
    The virtual machine could not be started because the hypervisor is not running
  • 原文地址:https://www.cnblogs.com/monicalee/p/3834649.html
Copyright © 2011-2022 走看看