Chinaunix首页 | 论坛 | 博客
  • 博客访问: 233104
  • 博文数量: 35
  • 博客积分: 659
  • 博客等级: 上士
  • 技术积分: 357
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-01 21:16
文章分类
文章存档

2012年(12)

2011年(23)

分类: C/C++

2011-09-06 16:06:41

关于const 限定符
最近学习c++遇到了const 这个有限制作用的关键字,难点在于与指针一起搭配时的,const所限定的对象。查了些书,有些心得,分享如下。

   .const 在*号的左边时, const 修饰的是指针所指向的对象.也就是说cptr 指向的是一个常量,无法通过改变指针来改变常量的值。但是cptr可以任意指向一个 type 类型的对象(有const修饰的,无const 修饰的对象都可以),即cptr的值可以改变,*cptr的值无法改变。
     小结:const 在*号的左边时限制:
      *cptr被限制:cptr 可以任意指向指定类型的值,但是不能用*cptr修改指向的值;
eg: const double *cptr; //这里cptr指向的是 double类型的常量.
            const double pi = 0;     
            const double *cptr; //此处const可以不初始化
            double const *cptr; //correct,与上条语句相等,只要const 在*左边,意义就不变
            cptr = π //correct
            *cptr = 1;  //error: assignment of read-only location ‘* cptr’
                     cptr 指向的是一个常量,无法通过改变指针来改变常量的值。
    需要注意的地方:
     1.const type *cptr 可以指向一个非const 修饰的type 类型的对象(它自以为指向的是const 修饰的type类型的对象),但是任何企图用*cptr来改变这个非const修饰的type类型的对象,都会导致编译错误,因为 此处cptr 将这个非const修饰的type
类型的对象,当做const修饰的type类型的对象来处理了。
 
        eg:  double tmp = 0;
 const double *cptr ;
     cptr = &tmp; //correct
     *cptr = 1; //error: assignment of read-only location ‘* cptr’
/*可以通过其他的方式来改变cptr的值,
( 方法一:直接对非const 修饰的type 类型的量进行修改。
方法二:间接的用非指向const的指针来修改)此处的tmp不是const修饰的,所以可以修改tmp的量,然后让*cptr重新指向tmp即可;*/
           tmp++; //correct
     cptr = &tmp; //correct
     double *ptr  = &tmp; //correct
     *ptr = 2;        //correct

 
      2.不允许用一个不指向const类型的指针指向一个const 修饰的对象(有点绕,举个例子)
const double pi = 0;
double *ptr = π  //error:invalid conversion from ‘const double*’ to ‘double*’
const double *cptr  = π //correct

      3.void *类型的指针虽然很强大,但是不能用void *来指向一个const 修饰的对象.
eg: const double pi = 0;
            void *pointer = π //error: cannot convert ‘const double’ to ‘void*’ in initialization
    const void *pointer_v = π //correct



    .const 在*号的右边时,const 修饰的就是这个指针,即这个指针是常指针,需要初始化,并且指向一个值时,就不能再指向另一个值,及时指向的另一个值也是这个值也不行。
小结const 在*号的右边时的限制
cptr是常指针,指向的对象唯一,不能改变。
所指对象的值视对象的类型来判断是否能改变。
eg:double *const cptr; //error: uninitialized const‘cptr’
   double tmp = 0;
   double *const cptr = &tmp; //correct


    .指向const 对象的const指针。(上述两种指针的结合)
若是要让常指针指向一个常量,则必须在*的左边加
const,用来说明常指针指向的是一个const 修饰的常量;
     小结当*的两边都有const时:const的限制最大!
    cptr 的指向唯一,需要初始化,初始化后,不能再指向其他的量,且不能通过*cptr来改变指向的对象的值(可以视指向的对象的类型来判断是否能用其他的方法改变).

eg :
const double pi = 0;
double *const cptr = π //invalid conversion from ‘const double*’ to ‘double*’
                const double *const cptr = π //correct
double const *const cptr = π //correct
               /*此处const double*const cptr = &pi与
                 duble const *const cptr = &pi一样,
                 只要const 在*右边即可*/


难度升级
四.const指针和typedef
   给出下列语句:
typedef string *pstring;
const pstring cstr;
    你认为这是一个怎样的指针呢?我相信大多数人和我一样,认为:
const pstring cstr = const *string cstr;const 在*左边,即这是一个指向常量的指针.但这是错误的。
    正确的应该是:
     const pstring cstr =  string *const cstr; 
     const在*的右边,即这是一个常指针,指向的是string类型的对象。
     需要注意的是 #define 和 const的区别, #define 是替代,而typedef是翻译。
因为此处用的是typedef,所以const 修饰的是指针。即cstr是一个常指针(const 在pstring 的左边或者右边都是一样的).

关于const还可以参考:
        
          

阅读(1473) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

KakitChen2012-04-17 21:35:14

jiapei100: 很显然,有诸多错误
1) eg: const *double cptr; //这里cptr指向的是 double类型的常量.
const* double cptr;在GCC下不合法。
如果GCC不合法,那么MS VC应该也很.....
非常感谢指正错误!
1)我用g++重新测试了, const *double ptr;确实不行,用const double *ptr才对.
2) 恩 按照代码的意思 确实是要把"非"去掉

再次感谢!

jiapei1002012-04-17 06:03:06

很显然,有诸多错误
1) eg: const *double cptr; //这里cptr指向的是 double类型的常量.
const* double cptr;在GCC下不合法。
如果GCC不合法,那么MS VC应该也很难合法。
2)2.不允许用一个不指向const类型的指针指向一个非const 修饰的对象(有点绕,举个例子)
应该去掉“非”字!