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

xiaoxiao2021-02-28  26

我们在学习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的问题确实比较抽象,难以理解,如果看了以后还有不懂的地方可以查阅相关的资料。
转载请注明原文地址: https://www.6miu.com/read-2650285.html

最新回复(0)