C语言数组指针问题

在网上看到一个这样代码:

int main
​{
    ​int a[5] = {1,2,3,4,5};
    ​int *str = (int *)(&a+1);
    ​printf("%d\n%d\n", *(a+1), *(str-1));
    ​return 0;
​}​

我一开始也陷入了陷阱里,没想这一个数组指针,以为只是普通的首地址加上一个数据类型的字节,于是我开始进行了下面一系列的实验:

#include<stdio.h>
int main(void)
{
    int a[5] = { 1,2,3,4,5 };
    int *b = (int*)(&a+1);
    for (int count = 0; count < 6; count++)
    {
        printf("&a[%d]=%d\n", count, a + count);
        printf("&a[%d]=%d\n", count, &a[count]);
    }
    printf("\n");
    printf("b=%d\n",b);
    printf("b-1=%d\n", b-1);​
    printf("*b=%d\n",*b);
    printf("*b-1=%d\n",*b-1);
    printf("*(b-1)=%d\n",*(b-1));
    return 0;
}

打印出来的结果如图一所示:
图一

因为指针类型是int*类型,所以在每+1为4个字节(编译环境:VS2015)。b和a[5]的地址相同,其实这个写法是错的,会越界。b-1和a[4]地址相同。所以可以看出这个+1加的&a是整一个数组的长度。

那是不是这样呢?我们把上面的printf(“&a[%d]=%d\n”, count, a + count);改成printf(“&a[%d]=%d\n”, count, &a + count);
打印结果如图二所示:
图二

可以看到&a+1之间是以20个字节为单位,&a[1]之间以4个字节为单位。证明我上面说的,那+1该加多少呢?是不是与前面的地址所指的长度有关?我们把上面的printf(“&a[%d]=%d\n”, count, &a + count);改成printf(“b + %d =%d\n”, count, b + count);,我们来看一下结果:
图三

我们可以看到第一个b+0还是&a[5]的地址,那为什么后面是以4个字节为单位呢?而不是以20个字节呢?那是因为在定义b这个指针的时候,把他的类型转换成了int*型(int b=(int)(&a+1));所以现在可以证明:+1要加多少跟+1前面的指针类型有关系。

那二维数组的时候,情况又是怎么样的呢?我又写了以下的程序进行测试:​

#include<stdio.h>
int main(void)
{
    int a[3][3] = { { 1,2 },{ 3,4 },{ 5,6 } };
    int *b = (int*)(&a + 1);
    for (int c = 0; c < 3; c++)
    for (int d = 0; d < 3; d++)
    printf("&a[%d][%d]=%d\n", c, d, &(a[c][d]));
    printf("\n");
    for (int count = 0; count < 3; count++)
    {
        printf("a + %d=%d\n", count, a + count);
        printf("&a[%d]=%d\n", count, &a[0] + count);
    }
    printf("\n");
    printf("&a[2][1]=%d\n", &(a[2][1]));
    printf("b=%d\n", b);
    printf("b-1=%d\n", b - 1);
    printf("*b=%d\n", *b);
    printf("*b-1=%d\n", *b - 1);
    printf("*(b-1)=%d\n", *(b - 1));
    return 0;
}

结果如图四所示:
图四

我们可以看出a+count是以12个字节为单位,因为我们定义的是int型3*3的二维数组,所以一行为12。在二维数组的指针中a=&a[0][0],a+1=&a[1][0],依此类推。

我们现在把​printf(“a + %d=%d\n”, count, a + count);改成printf(“&a + %d=%d\n”, count, &a + count);看看是不是以3*3*4=36个字节为单位递增,我们打印看一下结果:
图五

看来我们的推导是正确的,果然是以36个字节为单位递增。所以:+1要加多少个字节跟+1前面的指针类型有关系。&a是数组指针,代表数组的总长度,所以&a+1中的1为数组a所占的内存。而a+1中的a跟&a[0][0]是一样的,都表示的是数组的首地址,所以其中+1中的1为数组的类型字节数。
以上实验均在windows平台上运行,Linux平台下结果不同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值