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

如何声明数组指针?

数组指针:形如 char (*c)[10];这样的声明,c是一个指向包含10个字符型元素的数组的指针,即指向数组首元素地址的指针;

{
    int a[4][5];
    int (*p)[5]=a;
}

这里a是个二维数组的数组名,相当于一个二级指针常量;//二维数组名与二级指针毫无关系(初学者常常混淆)。

p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;

*(p+i)是一维数组a[i][0]的地址;

*(p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),*(*(p+2)+3)表示a[2][3]的值。

//(*p)[5]其中的5换成其他的数字在vc++6.0环境中都无法通过编译

(*p)[5]其中的5在上述例子中没有表示任何意思你可以换成除0以外的整数,[5]的作用就是帮助你记忆说你所指向的一维数组的长度。(不过除了与定义的二维数组的长度一致的不会警告之外 )其他的数会警告但是不影响结果。(百度百科)

“二维数组、数组指针、指针数组(Iliffe向量)”相关概念见https://blog.csdn.net/qq_39478139/article/details/107615646

此处不再赘述。

首先看一个例子,预测并对比p++,r++,t++每次增加的步长是多少字节。

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
    int a[2][3][4];
    int (*p)[3][4] = a;
    int (*r)[4] = a[0];
    int *t = a[0][0];
    printf("p=%d r=%d t=%d\n",p,r,t);
    printf("p=%d r=%d t=%d\n",++p,++r,++t);
    return 0;
}

打印结果:(其中int类型占4bytes)

p=6421920   r=6421920   t=6421920
p=6421968   r=6421936   t=6421924
步长(t) =1   *4bytes =  4bytes;
步长(r) =4   *4bytes = 16bytes;
步长(p)=4*3*4bytes = 48bytes;

那么上例中p、r、t 各代表什么意思呢?

int (*p)[3][4] = a; 声明了*p是一个“拥有着3个数组,而这每一个数组拥有4个整型元素”的数组,因此,p就是一个指向这样的数组的指针;

类似的,*r是一个拥有“4个整型元素”的数组,r是一个指向该数组的指针;

由于在某种场合下(数组作为函数定义的形式参数),数组名代表数组首元素的地址,那么a[0][0]代表元素a[0][0][0]的地址,所以t是一个指向a[0][0][0]的指针;

因此,p的步长为12*4bytes;r的步长为4*4bytes;t的步长为1*4bytes;

不妨再看一个例子,

#include <stdio.h>
#include <stdlib.h>
void test(char **ptr){
    int i = 3;
    while(i--){
        printf("%s\n",*ptr++);
    }
}
int main(int argc, char** argv)
{
    char *p[3] = {"abc", "defg", "hijkl"};//指针数组
    char c[3][5];
    char (*q)[5] = c;//数组指针
    test(p);
    printf("%d\n",q);
    q++;
    printf("%d\n",q);//+5bytes
    char (*r)[3][5] = &c;    
    r++;
    printf("%d\n",r);//+15bytes
    return 0;
}

通过第一个例子,可以很轻松的计算出q的步长;这里的r代表了整个数组的步长。

char (*r)[3][5] = &c; 声明了*r是一个“拥有3个数组,每个数组有5个整型元素”的数组,而r是一个指向这样的数组的指针;char类型大小为1byte,所以r的步长为3*5*1byte。

思考:对于数组a[3],a,&a,a+1,&a+1有什么区别?&a占内存吗?

关于这个问题的解释请看:https://blog.csdn.net/qq_39478139/article/details/107807421 数组名a和数组名取地址&a的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

没有对象的野指针°

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

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

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

打赏作者

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

抵扣说明:

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

余额充值