指针下标

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


        s.p = p;       //这一步,是将p的地址传递给s.p,所以,此时这两者共同指向s.i的地址,即都为&s.i

        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;

}



你可能感兴趣的:(C++,指针,学习心得)