int *p = & ia[2];
int j = p[1]; //这边p[1]相当于是 *(p+1) 但是我们 指针 p 并不会改变原先的值,这也是和 p++ 所不同的地方
接下来,我们来分析一个例子,大家会更加明白一点
#include<iostream>using namespace std;
struct S
{
int i;
int *p;
};
int main()
{
S s;
int *p = &s.i;
p[0] = 4; //这边实际上是 *(p+0) = 4,实际上就是 给 s.i赋值为 4;
p[1] = 3; //这边实际上为 *(p+1) = 3,因为p指向的是s.i,所以p+1之后所指向为s.p 即 s.p = 0x3 注意 s.p是指针哦,指针所指的地址为0x3,但这个地址并不是这个程序向系统申请得到的空间,如果此时对0x3这个地址进行取值,赋值操作的话,就会报 Segmentation fault (core dumped) ,如果学过内存装载的话,我们可以知道 3 这个地址存储的是系统的信息,且普通用户是无法进行访问的。
cout<<"s.i:"<<s.i<<endl;
cout<<p[1]<<" "<<s.p<<endl; // 输出为s.i:4 3 0x3
cout<<s.p<<" "<<p<<" "<<&s.i<<endl; //测试输出为0xbf8c6548 0xbf8c6548 0xbf8c6548
s.p[1] = 1; //这一步,是*(s.p+1)=*(p+1)=1,这样写会让我们很头疼,因为s.p指向p,p+1又回到了s.p,如果大家有点晕的话,就这么看*(p+1)=1 了,也就是说将s.p的指针指向了地址为0x1,刚才也分析了,但这个地址并不是这个程序向系统申请得到的空间,如果此时对0x1这个地址进行取值,赋值操作的话,就会报 Segmentation fault (core dumped),所以我们要小心了,此时s.p是指向了0x1
cout<<s.p<<endl; // 0x1
s.p[0] = 2 //这一步会报错!!!!Segmentation fault (core dumped) 因为这一步相当与是 *((int *)1) = 2,这是完全不被允许的,就好像这个不是你的东西,却硬要去拥有改变它,0x1这个地址上的东西是不能动的,如果学了信息安全的话,会更加明白这一点了
return 0;
}