关于指针与数组下标加1的问题

我们在学习C语言的时候经常会碰到指针或者数组下标加1,这也是个令大家非常头疼的问题,那就是它加1以后实际上是加了多少,指针或者数组的下标移动到了哪里。
下面我就通过举几个例子来告诉大家答案。
例1:

#include <stdio.h>

int main(int argc, char **argv)
{
    int a[3]={
       0 
    };
    printf("%0x %0x %0x",a,a+1,&a+1);




    return 0;
}

打印结果:bfaf2268 bfaf226c bfaf2274
我们定义了一个整型的一维数组,对于这个数组而言,加1相当于扫过一个int类型,即4个字节,也相当于元素后移一位,所以a与a+1的地址相差4,那么最后一个&a+1呢?
我们知道a本身就是个地址,它是这个数组的首地址,那么我们取a的地址相当于取整个数组的地址,所以加1加的是整个数组,相当于往后移了整个数组,即4*3=12个字节。

例2:

#include <stdio.h>

int main(int argc, char **argv)
{
    int a[3][3]={1,2,3,4,5,6,7,8,9};
    printf("%0x %0x \n",a,a+1);
    printf("%0x %0x\n",a[0],a[0]+1);
    printf("%d\n",*(*(a+0)+1));
    printf("%0x\n",*(a+1));
    printf("%0x %0x %0x %0x\n",a+1,*(a+1),*(a+1)+1,&a[1][0]);
    int i,j;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++)
            printf("%d  ",*(*(a+i)+j));
    printf("\n");
    return 0;
}

打印结果:
bfcec434 bfcec440
bfcec434 bfcec438
2
bfcec440
bfcec440 bfcec440 bfcec444 bfcec440
1 2 3 4 5 6 7 8 9
我们首先定义了一个二维数组a,它和刚才的一维数组的区别就是a+1指的是数组移动了一行,也就是4*3=12个字节。为什么会这样呢?
在二维数组a中,a和a[0]都是指针,都指向这个数组的第一个元素,但它们却有很大的区别:a是行指针,也就是说它指向的是行,对a加1移动的是一行。而a[0]是列指针,也就是说对a[0]加1只是往后移动了一个元素。
其中a和&a[0]是等价的,当你对a[0]取地址后,它就从指向列指向了行。
a[0]和&a[0][0]还有*(a+0)是等价的,它们都是指向列的。

例3:

#include <stdio.h>

int main(int argc, char **argv)
{
    int a[3][4]={{1,2,3,4},{3,4,5,6},{5,6,7,8}};
    int i;
    int (*p)[4]=a,*q=a[0];
    printf("%p %p\n",p,p+1);
    printf("%p %p\n",q,q+1);
    return 0;
}

打印结果:
0xbff30698 0xbff306a8
0xbff30680 0xbff30684

我们定义了一个数组指针p,并且让这个数组指针p指向二维数组a,然后又定义了一个int型指针q指向a[0]。所谓数组指针就是这个指针指向的是一个数组的首地址,而且它不能指向一个一维数组,因为这样会和首元素的首地址相冲突。
所以对于数组加1肯定是行加1,而a[0]是指向列的,所以a[0]+1只是列加1,。

例4:

#include <stdio.h>

int main(int argc, char **argv)
{
    char *p = "hello";
    printf("%p %p\n",p,p+1);
    printf("%p %p\n",*p,*p + 1);
    printf("%d\n",sizeof(p));


    return 0;
}

打印结果:
0x80484e0 0x80484e1
0x68 0x69
4

例5:

#include <stdio.h>

int main(int argc, char **argv)
{
    int a = 4;
    int *p = &a;
    printf("%p %p\n",p,p+1);
    printf("%p %p\n",*p,*p + 1);
    printf("%d\n",sizeof(p));

    return 0;
}

打印结果:
0xbfa7b9ec 0xbfa7b9f0
0x4 0x5
4

由例4 例5这两个例子可以看出指针地址加1主要看你定义的指针所指向的类型。
主要是看你定义指针的类型,比如你定义int *p=NULL; 那么int占4个字节。指向int的指针+1,该指针所指的内存地址要+4;如果你是定义 char *p=NULL; 那么char占1个字节。指向char的指针+1,该指针所指的内存地址只要+1。

例6:

#include <stdio.h>

int main(int argc, char **argv)
{
    int a[2][3]={1,2,3,4,5,6};

    int* *p;
    p=&a[0];
    printf("%p %p\n",*p,*p + 1);
    printf("% 0x %0x",p,p+1);


    return 0;
}

打印结果:
0x1 0x5
bfa2d998 bfa2d99c

例:7:

 #include<stdio.h>
int main()
{
    char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"};
    char **p;
    p=name;
    printf("%0x %0x\n",p,p+1);
    printf("%0x %0x\n",name,name+1);
    printf("%p %p\n",*p,*p + 1);
    printf("%p %p\n",*name,*name + 1);
    return 0;
}
打印结果:
bf8de058 bf8de05c
bf8de048 bf8de04c
0x8048583 0x8048584
0x8048560 0x8048561

由例67可以看出,如果定义的是二级指针p,那么我们二级指针加1,那么它的地址就是加4,因为它指向的类型是指针类型,所有的指针类型加1都是相当于加了4个字节。而*p就要看它指向的类型了,如果是int就是4个字节,如果是char就是1个字节。

对于指针加1的问题确实比较抽象,难以理解,如果看了以后还有不懂的地方可以查阅相关的资料。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值