C语言学习笔记(20) 数组参数和指针参数分析

摘要:总结了数组指针传递给函数为什么会退化为指针,二维数组参数在传递的时候需要注意哪些地方,最后给出两个实例加深理解。


一、数组作为参数为什么会退化为指针

    1.C语言之中只会以值拷贝的方式传递参数,指针其实传递的也是值,只不过里面是地址罢了。那么加入我们需要向函数传递一个数组或者比较大的结构体的时候,是将整个数组都拷贝过去吗?是将整个结构体都拷贝过去吗?显然不是的。。。如果那样的话,我们定义一个a[10000],那么一个参数传递就要拷贝一万次,这样效率是很低的。

    2.C语言设计之初是以高效为目的,所以它将数组名看做常量指针,只将数组首元素的地址传递给函数,这样通过指针,函数就可以找到这个数组,并加以使用。


二、二维数组参数

    1.二维数组参数同样存在退化的问题,本质上,二维数组是按照一维数组在内存中排列的,二维数组中的元素都是一维数组。

    2.二维数组参数中的第一维可以省略,但是第二维无论如何都不可以省略。

    退化为指针的规则如下:总结就是将靠近数组名的方框,放到数组名左边去,加上*号即可,但是我还是按照理解去记忆的,如果理解不了就只有这个死方法了。

    一维:

    void f(int a[5])->void f(int a[])->void f(int* a)

    二维:

    void g(int a[3][3])-> void g(int a[][3])-> void g(int (*a)[3])

    红色字体标注出来的,其实退化的是一个数组指针。

    下面这个表也可以给出等价关系:

    float a[5]->float* a;

    int* a[5]->int** a;

    char a[3][4]->char (*a)[4];

 

三、注意事项

    1.C语言中无法向一个函数传递任意的多维数组。

    一维:必须提供一个标志数组结束位置的长度信息,所以我们在传递给函数之前,必须给出一维数组的长度。

    二维:不能直接传递给函数。

    三维:用不到,无法传递。

    2.为了提供正确的指针运算,必须提供除了第一维以外的所有维的长度。

    下面这两个例子演示如何传递二维数组的参数:

<span style="font-size:18px;">例子1
#include <stdio.h>
#include <unistd.h>
 
void f(int (*p)[3])//这里二维指针传进来,第二维的信息不能省略,传进来的本质是一个数组指针
{
    printf("%d\n",(*(p+1))[2]); //第二行的第三个数,就是5啦,这里复习下指针运算
    printf("%d\n",(*p)[1]);//第一行的第二个数,就是1
}
 
int main(void)
{
    int a[3][3]={{0,1,2},{3,4,5},{6,7,8}};
      
    f(a); 
      
    return 0;
}
运行结果是:
5
1
 
例子2
#include <stdio.h>
 
 
void access(int (*p)[3],int row)
{
    int col=sizeof(*p)/sizeof(int);
    int i;
    int j;
   
    printf("sizeof(p):%d\n",sizeof(p));
   
    for(i=0;i<row;i++)
       for(j=0;j<col;j++)
           {
              printf("%d",(*(p+i))[j]);  
           }  
    printf("\n");    
}
 
 
int main(void)
{
    inta[3][3]={{0,1,2},{3,4,5},{6,7,8}};
      
    access(a,3);
      
    return0;
}</span>
 

    主要看输入参数的,虽然没有给出列,但是数组指针的类型中其实已经包含了这个信息了。

    这篇帖子就总结到这里,如有不正确的地方还请指出,大家共同进步!

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值