1 偏移量
在c语言中如果,我们给数组的数组名(即指向数组第一个元素的指针)进行自加运算,加的是这个数组定义的单个元素的字节,如果用int定义,则加的是4字节,也就是指向了数组向后偏移一个位置的元素。
而我们假如对数组的数组名进行取地址再自加,则这个指针进行自加,则加的是这个数组总共的字节大小,因为对数组的数组名进行取地址则是指向这个数组整体的指针。
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a[5] = {5,6,7,8,9};
int *p = NULL;
p = a + 2;
printf("*p = %d\n",*p);
p = (int *)(&a + 1) - 1;
printf("*p = %d\n",*p);
return 0;
}
如上代码,很容易知道打印的第一个*p的值为7,因为指向第一个元素的指针向后移动了2*4=8个字节,指向了a[2]为7。
而第二次打印出的值为9,如下图
剖析一下,先是给数组名a进行取地址运算,则 &a指向的是这个数组整体的地址,进行加1,则加了20个字节,则指向了紧跟这个数组之后的地址,但不在这个数组内。后来又对这个指针进行类型强制转换,变为int *型的指针,再减1,则减得是4个字节,就又指向了这个数组最后一个元素a[4],则为9。
2 指针指向字符串
先看一段代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
char str[] = "hello world";
char *p = "hello world";
printf("str = %s\n",str);
printf("sizeof(str) = %ld\n",sizeof(str));
printf("*p = %s\n",p);
printf("sizeof(p) = %ld\n",sizeof(p));
return 0;
}
运行结果
同为hello world 12个字符,一个存在数组内,一个被指针指向,在64位系统内指针位8字节,而这个字符串位12个字节,则肯定是不可能存进指针的,那么这个p指向的字符串指向哪里呢
在c语言中有专门存一些字符串常量的地方,则这个p指向的是一个 常量!!!则p指向的是这个字符串常量的首地址 。
那我尝试加14和15行的代码,改变这个*p的字符串为how are you
看看运行结果
执行结果在附加代码的地方直接爆出了段错误,则无疑证明了,该处不可修改,则常量怎么能修改呢