• 函数的二维数组和二阶指针参数


      在C语言中,一般给函数传递一维数组的参数时,那个参数一般直接声明为一个指针!而且我一直觉得数组名其实是一个常量指针,就是这个指针所指向的地址不能改变!但是我今天刚刚发现,这在多维数组里面是完全不同的!

      为什么呢,因为多维维数组有一个特性,就是多维数组做参数的时候,一定要指定除了第一个长度之外的其他长度!我有一个二维数组array[3][4],如果我要传递给函数func(),那么func()的函数原型应该这样定义:  

    int func(int arr[][4]);    //正确
    int func(int *arr[4]);    //正确

    而这样定义则是错误的:

    int func(int **arr);    //错误
    int func(int arr[][]);    //错误

      而多阶指针则是不需要指定长度的!

      比如下面这个关于二维数组的代码,这个是正确的!

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #define COL 3
     4 #define ROW 4
     5 int func(int aa[][COL])
     6 {
     7     int i,j;
     8     for(i=0;i<ROW;i++)
     9     {
    10     for(j=0;j<COL;j++)
    11         printf("%d ",aa[i][j]);
    12     printf("
    ");
    13     }
    14 }
    15 int main(int argc,char *argv[])
    16 {
    17     int aa[ROW][COL];
    18     int i,j;
    19     
    20     //赋初值
    21     for(i=0;i<ROW;i++)
    22     for(j=0;j<COL;j++)
    23         aa[i][j] = i+j+2;
    24 
    25     func(aa);
    26 
    27     return 0;
    28 }

      还有下面这个二阶指针的代码也是正确的:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #define COL 3
     4 #define ROW 4
     5 int func(int **pp)
     6 {
     7     int i,j;
     8     for(i=0;i<ROW;i++)
     9     {
    10     for(j=0;j<COL;j++)
    11         printf("%d ",pp[i][j]);
    12     printf("
    ");
    13     }
    14 }
    15 int main(int argc,char *argv[])
    16 {
    17     int **pp;
    18     int i,j;
    19 
    20     pp = (int **)malloc(sizeof(int *)*ROW);
    21     for(i=0;i<ROW;i++)
    22     {
    23         pp[i] = (int *)malloc(sizeof(int)*COL);
    24     }
    25     
    26     for(i=0;i<ROW;i++)
    27     for(j=0;j<COL;j++)
    28         pp[i][j] = i+j+2;
    29     func(pp);
    30 
    31     for(i=0;i<ROW;i++)
    32     {
    33         free(pp[i]);
    34     }
    35     free(pp);
    36     return 0;
    37 }

      但是有一点,就是这两个一定不能混着用!否则除了问题你都不知道去哪里找!比如下面这段代码:

     1 #include<stdio.h>
     2 #define COL 3
     3 #define ROW 4
     4 int func(int **pp)
     5 {
     6     int i,j;
     7     for(i=0;i<ROW;i++)
     8     {
     9     for(j=0;j<COL;j++)
    10         printf("%d ",pp[i][j]);
    11     printf("
    ");
    12     }
    13 }
    14 int main(int argc,char *argv[])
    15 {
    16     int pp[ROW][COL];
    17     int i,j;
    18     
    19     for(i=0;i<ROW;i++)
    20     for(j=0;j<COL;j++)
    21         pp[i][j] = i+j+2;
    22     func(pp);
    23 
    24     return 0;
    25 }

          这里我定义了一个二维数组,但是当作指针传进去了,然后我用的gcc给我这样一个警告(vc++6.0是当做错误来对待的)!

      警告传递的参数不对劲!

      如果觉得这个警告碍眼,可以直接加一个强制类型转换,就把警告去了!针对上面那个代码就是把第22行改成下面这种形式:

    func((int **)pp);

      然后编译和运行的结果如下:

      然后,我只能说,恭喜你,哥们,你的代码成功地进入了一种让你抓狂的状态!

      Ok,上面仅仅是开个玩笑,这里还是要强调一遍,指针和数组不一样,真的不一样,尤其是多维数组和多维指针,传递参数的时候千万不能混了!

    ================================================

    2014.11.21更新

      这两天在和别人讨论的时候,突然对这个东西有了更多的体会!

      那个二维数组做参数的时候声明长度的用意是什么,其实不就是要划定这个函数能够访问的内存空间的长度!而实现同样功能的二阶指针就不需要来划定这么一个空间!以前我们常讲,C语言的特性就是对于程序员比较信任,给予程序员较高的自由度,同时,这种较高的自由而导致的错误也得由程序员来解决!那么这个特性体现在哪里,我感觉就体现在C语言的核心(这里我用了核心这个词,而没有用灵魂这个词,我感觉C语言的灵魂更像是函数!它代表了将功能打包成模块,然后逐级调用!这正是面向过程思想的体现!),指针上面!上面就是一个很好的例子,数组需要声明访问的内存长度,而指针却不需要,这就说明指针具有较高的自由度,也是C语言给予程序员较高自由度的体现!

  • 相关阅读:
    解决云服务器ECS,windows server 2012不能安装SQL Server 2012,不能安装.NET Fromework 3.5
    html5中checkbox的选中状态的设置与获取
    sql server 韩文查询匹配失败
    管理nuget程序包中搜索不到任何程序包
    ftp下出现“当前的安全设置不允许从该位置下载文件”提示
    windows server 2012 下IIS8.5关于“ 配置错误 不能在此路径中使用此配置节”的解决办法
    服务器升级后访问网站资源返回404
    centos7yum的更新与优化
    linux(centos7)命令提示符优化
    检查vmware虚拟软件服务是否开启?
  • 原文地址:https://www.cnblogs.com/bwangel23/p/4108841.html
Copyright © 2020-2023  润新知