各类不同类型指针的区别到底是什么呢?
比如:double *、float*、int * 、char *、void *等;它们之间存在着哪些不同呢?
在这里,针对int *和cha *做个实验,以便更好的理解。
#include <stdio.h>
int main(void)
{
int *p;
char *q;
int k = 10;
char i = 10;
p = &k;
q = &i;
printf("&p = %p\n",&p);
printf("&q = %p\n",&q);
printf("&k = %p\n",&k);
printf("&i = %p\n",&i);
printf("p-> = %p\n",p);
printf("q-> = %p\n",q);
printf("k-> = %p\n",&k);
printf("i-> = %p\n",&i);
printf("------------------------------------\n");
printf("------------------------------------\n");
p++;
q++;
printf("&p = %p\n",&p);
printf("&q = %p\n",&q);
printf("&k = %p\n",&k);
printf("&i = %p\n",&i);
printf("p-> = %p\n",p);
printf("q-> = %p\n",q);
printf("k-> = %p\n",&k);
printf("i-> = %p\n",&i);
return 0;
}
运行结果:
&p = 0x7ffffc7ba8d8
&q = 0x7ffffc7ba8e0
&k = 0x7ffffc7ba8d4
&i = 0x7ffffc7ba8d3
p-> = 0x7ffffc7ba8d4
q-> = 0x7ffffc7ba8d3
k-> = 0x7ffffc7ba8d4
i-> = 0x7ffffc7ba8d3
------------------------------------
------------------------------------
&p = 0x7ffffc7ba8d8
&q = 0x7ffffc7ba8e0
&k = 0x7ffffc7ba8d4
&i = 0x7ffffc7ba8d3
p-> = 0x7ffffc7ba8d8
q-> = 0x7ffffc7ba8d4
k-> = 0x7ffffc7ba8d4
i-> = 0x7ffffc7ba8d3
首先i和k变量的地址没有变化。p 、q指针变量本身的地址值也没有发生变化,但是p++后,指向的地址值由0x7ffffc7ba8d4 变成了0x7ffffc7ba8d8 ,增加了4个字节。q++后,指向的地址值由0x7ffffc7ba8d3变成了0x7ffffc7ba8d4增加了一个字节。
为什么会发生这种变化呢?
因为p是int*,int在此次编译平台中占用4个字节的内存地址,所以p++之后,指针指向的地址偏移了4个字节。
q是char*,占用一个字节的内存地址,所以q++之后,指针指向的地址偏移了一个字节。同理,double *、float*也类似。
上图表示中,出现了一个类似的bug问题,q指向的位置怎么跑到p指向的地址上去了?
个人觉得这不是问题,这就是指针的魅力,指针本身没有问题,但是如果你要操作指针指向的值,这个时候就会出问题。
严格的说,上面的程序并不符合C语言的标准,只是为了更好的理解,所以才会那么操作。
总结:
对于指针的加减运算,标准只允许指针指向数组内的元素,或者超过数组长度的下一个元素。指针运算的结果也只是允许指针指向数组内的元素,以及超过数组长度的下一个元素。
今天没有说到void *,想听继续分解,请见下篇博文。