27. 数组参数和指针参数分析

为什么C语言中的数组参数会退化为指针?

C语言中 只会以值拷贝的方式传递参数
当向函数传递数组时, 将数组名看做常量指针传数组首元素地址
传值----传址----本质上都是传值,传地址只不过是传的地址值,以值拷贝的方式传递参数

二维数组参数

二维数组参数同样存在退化的问题(退化为数组指针)
二维数组可以看做是一维数组
二维数组中的每个元素是一维数组
二维数组参数中第一维的参数可以省略
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]);

等价关系(去方框,变星号,放左边)

注意事项

C语言中无法向一个函数传递任意的多维数组
为了提供正确的指针运算,必须提供 除第一维之外的 所有维长度
void f(int (*p)[3]){}
p 是一个指向包含3个整数的数组的指针。
这里的 (*p)[3] 是一个类型声明,它告诉编译器 p 是一个指针,解引用 p 得到的是一个包含3个整数的数组。
因此, 当你传递一个二维数组到 f 函数时,你实际上传递了一个指向该二维数组第一行的指针。
#include <stdio.h>
#include <malloc.h>
void f(int (*p)[3])//数组指针,每个元素是int,大小是3;
{
    printf("sizeof(p) = %d\n",sizeof(p));
    printf("%d\n",(*(p+1))[1]);
}
int main()
{
    int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
    printf("sizeof(a) = %d\n",sizeof(a));
    f(a);
    return 0;
}
result:
36    //int[3][3]类型数组的大小
8    //传递实际上是值拷贝,拷贝了数组首元素的地址
3

限制

.  一维数组参数 -  必须提供一个 标示数组结束位置的长度信息
.  二维数组参数 -   不能直接传递给函数
.  三维或更多维数组参数 - 无法使用

传递与访问二维数组的方式

#include <stdio.h>
void access(int a[][3], int row)//row 行;int a[][3]退化为int (*a)[3];最好直接替换为int (*a)[3]
{
    int col = sizeof(*a) / sizeof(int);//*是防盗门钥匙,打开防盗门后得到的是一个包含3个整数的数组。
    int i = 0;
    int j = 0;
   
    printf("sizeof(a) = %d\n", sizeof(a));
   
    for(i=0; i<row; i++)
    {
        for(j=0; j<col; j++)
        {
            printf("%d", a[i][j]);
        }
    }
}
int main()
{
    int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
   
    access(a, 3);
}
result:
sizeof(a) = 8
012345678

为什么在申请二维数组的时候没有采用数组指针的方式,而是采用二级指针+指针的方式?

1. 数组指针:这种方式通常用于固定大小的二维数组。例如,int (*array)[5] 是一个指向包含5个整数的数组的指针。这种方式的好处是,它可以让你像操作普通二维数组一样操作内存,而且编译器可以为你做很多类型检查。但是,这种方式的一个限制是, 它通常用于固定大小的数组
2. 二级指针:这种方式 通常用于动态分配的二维数组,即数组的每一行可以有不同的大小,或者数组的大小在运行时确定。例如,int **array 是一个指向整数指针的指针,这些整数指针又指向实际的整数数据。使用这种方式,你可以根据需要动态地分配和释放每一行的内存。
数组指针 它通常用于固定大小的二维数组,而使用二级指针+指针的方式,你可以根据需要动态地分配每一行的内存,每一行的大小也可以不同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值