• C++指针


    指针

    是一种数据类型 用来指向一个变量的地址

    int a=10;
        a=20;
        int b=100;
        int* p= &a;
        p=&b;
        printf("%p
    ",&b);//%p表示指针 0x7ffee5633874
        //printf("%X
    ",p);//p是一个地址,%X 16进制输出
        cout<<p;//0x7ffee5633874
    

     p是int*类型的,*p代表p地址的值,p代表着一个地址
    通过指针修改变量的值

    *p=200;
        printf("%d
    ",b);//200
        printf("%d
    ",*p);//200
    

    sizeof()指针类型在内存中的大小

    在64(32)位的机器里,无论什么类型的指针大小都是8(4)个字节,因为存的都是地址,内存地址都是无符号整型的。

    cout<< sizeof(p)<<endl;//8
        cout<< sizeof(double*)<<endl;//8
        cout<< sizeof(short*)<<endl;//8
        cout<< sizeof(int*)<<endl;//8
        cout<< sizeof(char*)<<endl;//8
        cout<< sizeof(float*)<<endl;//8
    

    野指针

    是指向一个未知的内存空间,可能在读写的时候发生错误

    指针变量也是变量,是变量就可以任意赋值,不要越界即可(64位机器 为8字节)

    但是,任意数值赋值给指针变量没有意义,因为任意数值的地址可能时未知的(操作系统不允许操作此指针指向的内存区域),野指针不会直接引发错误,操作野指针指向的内存区域才会出问题。

    int a=10;
        int* p=&a;
        //指向内存编号为0xff00的内存地址
        //内存0-255是系统保留的,不能读,也不能写
        p=0xff00;//该地址是未知的内容空间
        *p=100;
        printf("%d
    ",*p);
    

    空指针

    就是指向内存编号为0 的空间,操作该内存空间会报错,一般情况空指针用于条件判断

    int* p;
        p=NULL;
        *p=100;
        printf("%d
    ",*p);
        if(p!=NULL)
        {
            //free();
        }
    

    万能指针

    int a=10;
        void* p=&a;
        *(int *)p=100;//将p强转成int*类型 再在前面加上*,就是取出p地址指向的值 ;再赋值,改变a的值
        cout<<a;//100
        //cout<<*p;//这样写不行,因为p还是void*类型
        cout<<*(int*)p;//100
    
    int arr[10]={0};
        void* p=arr;
        *(int*)p=100;
        *((int*)p+4)=200;
        cout<<arr[0]<<" "<<arr[4];//100 200
    

    const修饰指针

    1.通过指针修改const修饰的常量

    方法是:把常量的地址给指针,通过修改指针的值,来改变常量的值

    const int a=10;
    printf("%d ",a);//10
    int* p=(int*)&a;//将const int*转换为int* 否则报错
    *p=100;
    printf("%d ",a);//100
    printf("%d ",*p);//100

    2.如果const修饰int*不能改变指针变量指向的内存地址的值,但是可以改变指针指向的地址

    int a=10,b=100;
        printf("%d
    ",a);//10
        const int* p;
        p=&a;
        //*p=100;//不能改变指针变量指向的内存地址的值 因为*p被const修饰着
        p=&b;//但是可以改变指针指向的地址
        printf("%d
    ",*p);//100
    

     3.const修饰指针变量 能改变指针变量指向地址的值 但不能改变指针指向的地址

    int a=10,b=100;
        int *const p=&a;
        //p=&b;//不能改变p的地址值 因为p被const修饰着
        *p=100;
        printf("%d
    ",*p);//100
    

     4.const修饰指针类型也修饰指针变量 那么不能通过一级指针改变指针指向的地址,也不能通过一级指针修改指针指向的值

    用二级指针可以修改

    int a=10;
        int b=20;
        const int* const p=&a;
        //p=&b;
        //*p=100;
        printf("%d
    ",*p);
    

    意思就是不能改变const后面修饰的东西的值

    指针和数组、指针运算

    数组名是数组的首地址 这是一个常量 arr==&arr[0]

    1.指向数组的指针 当操作指针的时候,间接操作了数组

    int arr[10]={0};
        printf("%p
    ",arr);
        printf("%p
    ",&arr[0]);
        //p=arr;[数据类型*] 变量名
        int* p=arr;
        for(int i=0;i<10;i++) {
            printf("%d
    ", p[i]);
            printf("%d
    ",*(p+i));
        }
    

     数组名和指针的区别:

    数组名通过sizeof可以求出数组的大小,指针只包含数组的首地址信息

    int arr[10]={0};
        int* p=arr;
        cout<<sizeof(arr);//40=10*(4字节)
        cout<<sizeof(p);//4
    

     指针实现冒泡排序

    void bubble(int* p,int len)
    {
        for(int i=0;i<len-1;i++)
        {
            for(int j=0;j<len-i-1;j++)
            {
                if(*(p+j)>*(p+j+1))
                    swap(*(p+j),*(p+j+1));
            }
        }
    }
    int main()
    {
        int arr[10]={0,7,8,1,25,4,2,9,5,3};
        int* p=arr;
        bubble(p,10);
        for(int i=0;i<10;i++)
            cout<<*(p+i)<<" ";
        return 0;
    }
    

     用指针实现字符串翻转

    void rev(char* arr)
    {
        int len=strlen(arr);
        char* p1=arr;
        char* p2=&arr[len-1];
        while (p1<p2)
        {
            char temp=*p1;
            *p1=*p2;
            *p2=temp;
            p1++;
            p2--;
        }
    }
    int main()
    {
        char c[10],d;
        int i=0;
        while ((d=getchar())!='
    '){
            c[i++]=d;
        }
        rev(c);
        printf("%s",c);
        return 0;
    }
    

    指针数组

    int a=10;
        int b=20;
        int c=30;
        int* arr[]={&a,&b,&c};
        //arr[0]==&a;arr[1]==&b;arr[2]==&c;
        printf("%d
    ",*arr[0]);//10 注意:[]的优先级大于* 所以不用写成*(arr[0])
        *arr[2]=200;
        printf("%d
    ",c);//200 通过指针数组修改值
        char* arr[]={"hello","www","com"};
        printf("%c
    ",*arr[0]);//"hello"
        printf("%c
    ",*arr[1]);//"www"
        printf("%c
    ",*(arr[0]+1));//"hello"中e
    

    多级指针

    int a=10;
        int* p=&a;//一级指针存的是a的地址,*p代表a的值
        int**pp=&p;
        *pp=&a;
        **pp=20;//二级指针存的是一级指针的地址 **pp代表一级指针的值
        int***ppp=&pp;//三级指针存的是二级指针的地址 **ppp存的是二级指针的值
        //*ppp==pp==&p;
        //**ppp==*pp==p=&a;
        //***ppp==**pp==*p==a;//多级指针以此类推
  • 相关阅读:
    使用CURL来自动登录并下载东西
    Linux使用dmidecode来查看机器有几根内存插槽,哪个槽上有内存
    电源功率不够会导致Linux启动出奇怪的现象 文件系统访问不正常
    html中border的属性设置
    javascript关于数组合并的——非比寻常
    javascript关于数组合并的——非比寻常
    你在坚持午睡吗?
    你在坚持午睡吗?
    优秀有价值的博客收藏列表(持续更新)
    优秀有价值的博客收藏列表(持续更新)
  • 原文地址:https://www.cnblogs.com/zuiaimiusi/p/11494784.html
Copyright © 2020-2023  润新知