论数组与指针-01 如何声明一个指向“多维数组“的指针

C语言中的数组值得注意的地方有以下两点:

1、C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。

2、对于一个数组,我们只能够做两件事:

    ①  确定该数组的大小;

    ②  获取指向该数组下标为0的元素的指针。

说明:第②点中,在数组作为函数定义的形式参数,编译器会将传进来的形参数组名变成一个指向数组首元素的指针;例如对于声明二维数组char a[2][5];a是一个拥有2个数组元素,而每个数组元素有着5个元素的数组,a为一个指向第0个数组元素的指针。

补充:

1、C语言中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。这样,多维数组就可以“仿真”出来了。

2、其他有关数组的操作,看上去是以数组下标进行运算的,实际上都是通过指针进行的。


拓展:那么什么时候数组与指针相同呢?作为函数定义的形式参数。(源于《C专家编程》9.2)


首先,来理解如何声明一个数组。例如,

int a[3];    

语句声明了a是一个拥有3个整型元素的数组。类似的,

struct{

    int p[4];

    double x;

}b[17];

声明了b是一个拥有17个元素的数组,其中每个元素都是一个结构,该结构包括了一个拥有4个整型元素的数组(p)和一个双精度类型的变量(x)。

    现在考虑下面的例子,

int calendar[12][31];

这个语句声明了calendar是一个数组,该数组拥有12个数组类型的元素,其中每个元素都是一个拥有31个整型元素的数组。(而不是一个拥有31个数组类型的元素的数组,其中每个元素又是一个拥有12个整型元素的数组。)因此,sizeof(calendar)的值是372(31×12)与sizeof(int)的乘积。

特别注意:如果calendar不是用于sizeof的操作数,而是用于其他的场合,那么calendar总是被转换成一个指向calendar数组的起始元素的指针。

    再看下面的声明:

int calendar[12][31];

int *p;

int i;

那么,calendar[4]的含义是什么?

    因为calendar是一个有着12个数组类型元素的数组,它的每个数组类型元素又是一个有着31个整型元素的数组,所以calendar[4]是calendar数组的第5个元素,是calendar数组中12个有着31个整型元素的数组之一。因此,calendar[4]的行为也就表现为一个有着31个整形元素的数组的行为。例如,

p = calendar[4];

指针p指向了数组calendar[4]中下标为0的元素。

因为calendar[4]对于calendar[4][31]而言是它的数组名,由于数组名在这种场合下,指向了数组首元素的地址,所以p指向数组首元素的地址。又如,

    sizeof(calendar[4])的结构为 31*sizeof(int)。

如果calendar[4]是一个数组,那么可以通过下标的形式来指定这个数组中元素。例如,

i = calendar[4][7];

类似的,可以改写成下面这样而意思保存不变:

i = *(calendar[4] + 7);

进一步写成,

 i = *(*(calendar + 4)+ 7);

这种情况下,这充分体现了数组名是指向数组首元素的指针。

    下面再看:

p = calendar;

    这个语句是非法的。因为calendar是一个二维数组,即“数组的数组”,在此处使用calendar名称会被转换为一个指向数组的指针;而p是一个指向整形变量的指针,这个语句试图将一种类型的指针赋值给另一种类型的指针,所以是非法的。

    那么如何声明一种指向数组的指针的方法?

int (*ap)[31];

    这个语句实际的效果是,声明了*ap是一个拥有31个整型元素的数组,因此ap就是指向这样的数组的指针。因而,我们可以这样写:

int calendar[12][31];

int (*monthp)[31];

monthp = calendar;

    这样,monthp将指向数组calendar的第1个元素,也就是数组calendar的12个有着31个元素的数组类型元素之一。

论数组与指针-02 二维数组、数组指针、指针数组(Iliffe向量):

https://blog.csdn.net/qq_39478139/article/details/107615646

论数组与指针-03 数组指针++步长:

https://blog.csdn.net/qq_39478139/article/details/107618652

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有对象的野指针°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值