• 第35课 数组参数和指针参数分析


    1. 数组参数退化为指针的意义

    (1)C语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C语言以高效作是最初的设计目标,所以这种方法是不可取的。

    (2)参数位于栈上,太大的数组拷贝将导致栈溢出

    (3)将数组名看做常量指针传递的是数组的首元素地址,而不是整个数组。

    2. 二维数组参数

    (1)二维数组参数同样存在退化的问题:

      • 二维数组可以看做是一维数组,其中的每个元素又是一个一维数组

    (2)二维数维参数第一维的参数可以省略

      ①void f(int a[5])←→void f(int a[])←→void f(int* a)           一维数组参数

      ②void g(int a[5][3])←→void g(int a[][3])←→void g(int (*a)[3]);      二维数组参数

    (3)等价关系

    数组参数

    等效的指针参数

    备注

    一维数组:float a[5]

    指针:float* a

    相当于数组去掉第1维,然后把数组名前加上*。

    指针数组:int* a[5]

    指针的指针:int** a;

    二维数组:char a[3][4]

    数组的指针:char(*a)[4]

     

     

    (4)被忽视的知识点

      ①C语言中无法向一个传递任意多维数组。换一句话讲,形参int a[][3]是合法的,但int a[][]是非法的。

      ②因此,必须提供除第1维之外的所有其他维长度。第一维之外的维度信息用于完成指针运算。

    【实例分析】传递与访问二维数组

      1 #include <stdio.h>
      2 
      3  
      4 
      5 void access(int a[][3],int row) //a[][3],形参第2维的长度必须提供
      6 
      7 {
      8 
      9     int  col = sizeof(*a)/sizeof(int);
     10 
     11    
     12 
     13     int i = 0;
     14 
     15     int j = 0;
     16 
     17    
     18 
     19     printf("sizeof(a) = %d
    ",sizeof(a)); //指针,4字节
     20 
     21  
     22 
     23     //a为int (*a)[3]类型,即a指向一个有3个int型元素的数组
     24 
     25     printf("sizeof(*a) = %d
    ",sizeof(*a));//3*4 =12字节
     26 
     27    
     28 
     29     for(i = 0;i < row; i++)
     30 
     31         for(j = 0; j < col; j++)
     32 
     33         {
     34 
     35             printf("%d
    ", a[i][j]);
     36 
     37         }
     38 
     39    
     40 
     41     printf("
    ");
     42 
     43 }
     44 
     45  
     46 
     47 void access_ex(int b[][2][3],int n) //数组参数的第2、3维长度必须提供
     48 
     49 {   
     50 
     51     int i = 0;
     52 
     53     int j = 0;
     54 
     55     int k = 0;
     56 
     57    
     58 
     59     printf("sizeof(b) = %d
    ",sizeof(b)); //指针,4字节
     60 
     61  
     62 
     63     //b为int (*b)[2][3]类型,即b指向一个有2行3列int型元素的二维数组
     64 
     65     printf("sizeof(*b) = %d
    ",sizeof(*b));//2 * 3 * 4 = 24字节
     66 
     67    
     68 
     69     for(i = 0;i < n; i++)
     70 
     71         for(j = 0; j < 2; j++)  
     72 
     73              for(k = 0; k < 3; k++)
     74 
     75              {
     76 
     77                  printf("%d
    ", b[i][j][k]);
     78 
     79              }
     80 
     81    
     82 
     83     printf("
    ");
     84 
     85 }
     86 
     87  
     88 
     89 int main()
     90 
     91 {
     92 
     93     int a[3][3] = {{0, 1, 2},{3, 4, 5},{6, 7, 8}};
     94 
     95     int aa[2][2] = {0};
     96 
     97     int b[1][2][3] = {0};
     98 
     99  
    100 
    101     access(a, 3);
    102 
    103     //access(aa,2);//error,int(*)[2]与int (*)[3]类型不匹配
    104 
    105  
    106 
    107     access_ex(b, 1);
    108 
    109     //access_ex(aa,2);//int(*)[2]与int(*)[2][3]类型不匹配
    110 
    111  
    112 
    113     return 0;
    114 
    115 }

    3. 小结

    (1)C语言中中会以值拷贝的方式传递参数

    (2)C语言中的数组参数必然退化为指针

    (3)多维数组形参,必须提供除第1维之外所有维长度

    (4)对于多维数组函数参数只有第一维是可变的(即无需提供)

  • 相关阅读:
    1-15-2-RAID1 企业级RAID磁盘阵列的搭建(RAID1、RAID5、RAID10)
    1-15-1 RAID磁盘阵列的原理和搭建
    伪随机数算法(一)
    Swing---WindowConstants
    cmd_ping命令
    开灯问题
    freopen()函数
    Beginning Python Chapter 3 Notes
    Beginning Python Chapter 2 Notes
    String | StringBuffer | StringBuilder 比较
  • 原文地址:https://www.cnblogs.com/hoiday/p/10085733.html
Copyright © 2020-2023  润新知