Const 问题 ( 自我总结,仅供参考 )

    constchar *const * keywords

    constchar const * keywords

    constchar *const keywords

    constchar const keywords

请问以上四种定义,所得出的变量有什么区别,各代表什么?(请从维数、用途等方面简要说明)

 

1.指向const对象的指针   
const int *p;   (自我理解》》》也就是const int *p中 p还是指针变量而不是常量,只不过p所指向的那个是const 而已!!!!!在定义时 不 需要 对它进行初始化!)(EASY:指针可以指向不同常量,但是被指向的常量的值是不能变的!!!)
                Root>>> p可以指向不同的内存单元;但是每个内存单元中的值是不能变的!!!
这个p是一个指向int类型const对象的指针,const限定了指针p所指向的类型,而并非p本身。也就是说p本身并不是const。在定义时不需要对它进行初始化,还可以给p重新赋值,使其指向另一个const对象。但不能通过p修改所指向对象的值。
示例1:int a=0; p=&a; 可以。
示例2:*p=20; 不可以。

<><><><><><><><>
int i1 = 30;
int i2 = 40;
const int *pi = &i1;
pi =&i2;            
i2 =80;             --------->>>>>结论》》》const int *p指向的是常量;不能通过  量 改量;只能通过内存改量(相当注意)
15
printf("%d\n", *pi);   
<><><><><><><><>

结论》》》》》》》》这种指向const对象的指针只是限制不能修改p指向对象的数值,而不是限制p指向什么对象。!!!!!!!!!!!


把一个const对象的地址赋给一个不是指向const对象的指针也是不行的。
示例3:const int b=10;
      int*p2=&b;       //error    (因为声明是不相容的!!!)
      const int *p3=&b; //ok

结论》》》》》》》》因为变量b有const修饰,不能被修改。但指针p2是一个普通的指针,可以修改指向对象的值,两种声明矛盾,所以不合法。而指向const对象的指针不允许修改指针指向对象的数值,所以这种方式合法。



2.const指针    int *const p4形式:Root>>>指针p4是常量指针;一旦指向一个内存后就不能改变了;但是内存中的值可以改变!!!

     int c=20;
     int *const p4=&c;

指针p4称为const指针。它和指向const对象的指针恰好相反,它不能够修改所指向对象,但却能够修改指向对象的数值。另外,这种指针在声明时必须初始化。


3.指向const对象的const指针      const int *const dp 形式: 分解一下也就是先把  constdp作为整体;就是  整体 所指向的内存中的值是常量(不可变);再是int *const dp说明  dp 是常量指针;只能指向单一内存; 以上条件结合就是:指针dp既不能修                                  改指向的对象,也不能修改只想对象的值。 

    const int d=30;
    const int *const dp=&d;

指针dp既不能修改指向的对象,也不能修改只想对象的值。 

const int ic = 20;  和   int const ic =20;  是完全一样的;  之后的值是不能改变的!!!

请注意  const int 那个放在前面  哪个放在后面都是一样的!!!const int *pi 与 int const *pi 是一样的......


现在分析来源:
         

解释:(精辟)
const char *const * keywords 
keywords是1个普通的指针,指向1个指向  常量  的   常量指针

const char const * keywords 
=char const * keywords 
keywords是1个普通的指针,指向1个char常量

const char *const keywords 
keywords是1个常量指针,指向1个char常量

const char const keywords  常量指针只想一个常量;也就是 keywords 就是常量
=const char keywords
keywords是1个char常量
 

 


》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

  const 的 更强悍的作用:可以修饰函数的参数、返回值,甚至函数的定义体!!!!!
 
      
        《《《  const 修饰函数参数: 》》》
 
  ( 1).                          
       原则: 只能用于函数的  参数输入 领域;如果参数作输出作用,坚决不能用,不然会失
              去输出功能的

              例如:    char*Strcpy(char *copyTo, const char *copyFrom);
                                            
              //因为 copyFrom 是不可能改变的,所以加上 const 修饰会更有保障
              //如果给 copyTo 也加上const;那么在函数执行体中copyTo是改变不               //了的咯,因为他
 
               const 型的,所以也应正了上面的原则;;;;

 
  ( 2 ). 如果参数的传递是 “值传递”,那么无需加上 const来保护,因为函数会自动产生临时变量来复制此参数,

       
              你就是加上了 const 也是枉然的,因为函数之后调用的是 复制参数,已经不是原参数咯! O(∩_∩)O~

              例如: void Fun( int x ); 不要写成 void Fun( const int x)  // 是没有任何意义的


  ( 3 ). 对于非内部的数据类型而言,也就是用户自己定义的数据类型,例如: voidFun(A x); A 是自己定义的数据
        
        类型;显然这样的传递是很浪费时间的;因为函数还要产生临时参数拷贝,对临时对象的构造,复制和析构都
       
        会浪费时间,所以我们想到了用 “引用传递”;改成 void Fun(A &a);因为引用传递的参数其实本质上和原
     
        参数是一摸一样的(前面已经讲过); “引用传递” 只不过是 相当于 原参数的 绰号而已,叫原名或是 绰
       
        号都是叫的同一个人; 总之“引用传递” 只是借用了一下参数的 别名而已;不需要什么 临时对象... ...

        所以很节约时间;但是 a 的值有可能被改变的,所以此处加上 const 好,最终形式  voidFun(constA &a);

 
   总结:const修饰参数的原则:((★)(★)(★))((★)(★)(★))((★)(★)(★))

        对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传

        递”,目的是提高效率。例如将 void Func(A a) 改为void Func(const A&a)。

        对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。

        否则既达不到提高效率的目的,又降低了函数的可理解性。例如 void Func(int x) 不

        应该改为 void Func(const int &x)。

  
         《《《  const 修饰函数函数返回值: 》》》

 
    ( 1 ).如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返
         
          回值只能被赋给加 const 修饰的同类型指针。 
 
          例如:
                const char *Str(... ...)

                返回值: char *str =Str;       // 错误
                         
                         const char *str = Str;  // 正确

    ( 2 ).同样如果函数的返回值是 “值传递”,那么用 const 是没哟意义的额 ,因为返回的同样被临时的对象复制
         
          ,最终调用的是复制返回值而不是原有的,所以不需要加上 const。。。不要把函数 int GetInt(void) 写
        
         成 const int GetInt(void)。同理不要把函数A GetA(void) 写成 const AGetA(void),其中 A 为用户自定

         义的数据类型。
 
 
         如果返回值不是内部数据类型,将函数 A GetA(void) 改写为 const A &GetA(void)

         的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的

        “拷贝”还是仅返回“别名”就可以了,否则程序会出错。

            
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                                《 关于 const 的其他一些问题 》


1. 在某些输出函数中;我们只是要把 class 中的信息输出而不想改变它;也可以用 const
 
   例如:  voidOutPut() const;  // 请注意 const的位置

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值