zoukankan      html  css  js  c++  java
  • [转载][c++]C++中指针常量和常量指针的区别

    在复习C++基础时被常量指针和指针常量搞混了,这篇博文对比介绍了这两个的不同

    原文地址:https://www.cnblogs.com/lizhenghn/p/3630405.html

    ----------------------我是正文分割线----------------------------------------

         在C++学习使用过程中,每个人都不可避免地使用指针,而且都或多或少的接触过常量指针或指针常量,但是对这两个的概念还是很容易搞糊涂的。

    本文即是简单描述指针常量和常量指针的区别。

    常量指针

      定义:

              又叫常指针,可以理解为常量的指针,也即这个是指针,但指向的是个常量,这个常量是指针的值(地址),而不是地址指向的值。

         关键点:

              1.常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;
              2.常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;
              3.指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址;

     代码形式:

              int const* p;  const int* p;

    指针常量

        定义:

             本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。 

        关键点:

              1.它是个常量!
              2.指针所保存的地址可以改变,然而指针所指向的值却不可以改变;
              3.指针本身是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化;

      代码形式:

             int* const p;

    指向常量的常指针

      定义:

         指向常量的指针常量就是一个常量,且它指向的对象也是一个常量。

       关键点:

            1.一个指针常量,指向的是一个指针对象;

            2.它指向的指针对象且是一个常量,即它指向的对象不能变化;

       代码形式:

            const int* const p;

    那如何区分这几类呢? 带两个const的肯定是指向常量的常指针,很容易理解,主要是如何区分常量指针和指针常量:

    一种方式是看 * 和 const 的排列顺序,比如
         int const* p; //const * 即常量指针
         const int* p; //const * 即常量指针
         int* const p; //* const 即指针常量
    还一种方式是看const离谁近,即从右往左看,比如
         int const* p; //const修饰的是*p,即*p的内容不可通过p改变,但p不是const,p可以修改,*p不可修改;
         const int* p; //同上
         int* const p; //const修饰的是p,p是指针,p指向的地址不能修改,p不能修改,但*p可以修改;

    看代码

    //-------常量指针-------
        const int *p1 = &a;
        a = 300;     //OK,仍然可以通过原来的声明修改值,
        //*p1 = 56;  //Error,*p1是const int的,不可修改,即常量指针不可修改其指向地址
        p1 = &b;     //OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;
    
        //-------指针常量-------//
        int*  const p2 = &a;
        a = 500;     //OK,仍然可以通过原来的声明修改值,
        *p2 = 400;   //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化
        //p2 = &b;     //Error,因为p2是const 指针,因此不能改变p2指向的内容
        
        //-------指向常量的常量指针-------//
        const int* const p3 = &a;
        //*p3 = 1;    //Error
        //p3 = &b;    //Error
        a = 5000;    //OK,仍然可以通过原来的声明修改值

    在实际应用中,常量指针要比指针常量用的多,比如常量指针经常用在函数传参中,以避免函数内部修改内容。

    size_t strlen(const char* src); //常量指针,src的值不可改变;
    char a[] = "hello";
    char b[] = "world";
    size_t a1 = strlen(a);
    size_t b1 = strlen(b);
    虽然a、b是可以修改的,但是可以保证在strlen函数内部不会修改a、b的内容。

    既然讲到了指针,那顺便说一下空指针、野指针的问题。
    空指针就是保存地址为空的指针,使用指针时必须先判断是否空指针,很多问题都是这一步导致的。
    野指针是在delete掉指针之后,没有置0,导致指针随意指向了一个内存地址,如果继续使用,会造成不可预知的内存错误。

    另外指针的误用很容易造成BUG或者内存泄漏。

    看代码

    //-------空指针-------//
        int *p4 = NULL;
        //printf("%d",*p4); //运行Error,使用指针时必须先判断是否空指针
    
        //-------野指针(悬浮、迷途指针)-------//
        int *p5 = new int(5);
        delete p5;
        p5 = NULL; //一定要有这一步
        printf("%d",*p5);  //隐藏bug,delete掉指针后一定要置0,不然指针指向位置不可控,运行中可导致系统挂掉
        
        //-------指针的内存泄漏-------//
        int *p6 = new int(6);
        p6 = new int(7); //p6原本指向的那块内存尚未释放,结果p6又指向了别处,原来new的内存无法访问,也无法delete了,造成memory leak
  • 相关阅读:
    实验六:空间耗尽故障
    实验四 :重置root密码
    实验三:误删boot恢复
    实验二: grub引导故障修复
    实验一 :MBR扇区故障系统备份与还原
    chapter07
    chapter06
    chapter05
    转-SQL数据库中把一个表中的数据复制到另一个表中
    Howto: 如何通过IIS7为ArcGIS Server配置反向代理系统架构
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9216904.html
Copyright © 2011-2022 走看看