2009年3月9日星期一

【原】关于const修饰符的问题

对const修饰符的使用一直感觉疙疙瘩瘩的,因为用的不是很多。上周写了个小程序,搞清楚了它的用法。话不多说,先贴程序。
  1. const int n = 10;
  2. const char * pszTemp = "a";
  3. char const * pszTemp2 = "c";
  4. char * const pszTemp3 = "b";
  5. const char * const pszTemp4 = "e";
  6. pszTemp = "d";
  7. pszTemp2 = "e";
  8. pszTemp3 = "f";
  9. pszTemp4 = "f";
  10. lstrcpy(pszTemp, "d");
  11. lstrcpy(pszTemp2, "d");
  12. lstrcpy(pszTemp3, "d");
  13. lstrcpy(pszTemp4, "f");

把这段程序拿到VC6的环境下编译,会发现编译出错。第8、9、10、11和13行都有错误。我们先从第2行开始分析。第2行定义了一个名叫pszTemp 的字符串指针,const放在char *之前,表明它是一个指向常量的指针变量,它指向的常量值不可以改变,所以第10行会编译出错,但是它保存的地址却可以改变,所以我们仍然可以通过改变它指向的地址来改变它的值。第3行同第2行。第4行定义了一个常指针,表明它本身是常量,而不是它指向的对象声明为常量。所以第8行出错,而第12行却可以通过。第5行是定义了一个指向常量的常指针,所以无论是对它指向的值的改变还是指针本身值的改变都是不允许的。因此,第9行和13行写法都是错误的。
下面再贴几行代码,有兴趣的读者可以指出其中出错的行数。

  1. const int *pAge = new int(1);
  2. int const *pAge2 = new int(2);
  3. int * const pAge3 = new int(3);
  4. const int * const pAge4 = new int(4);
  5. *pAge = n;
  6. *pAge2 = n;
  7. *pAge3 = n;
  8. *pAge4 = n;
  9. pAge = &n;
  10. pAge2 = &n;
  11. pAge3 = &n;
  12. pAge4 = &n;

3 条评论:

  1. 算是比较基础的东西了,不过不弄清楚还是不行的...

    回复删除
  2. 这就是常量指针和指针常量的区别,我把我的理解综合成两点:
    1)常量指针,即“常量的指针”,首先它是一个指针,其次它是一个指向常量的指针,它指向的内容不可修改;指针常量,首先它是一个常量,其次它又是一个指针,它自身的值不可修改。
    2)关于解读带有const关键字的语句,对于初学者有人总结出一个便于记忆的方法值得推荐,从后往前读(*代表pointer to),如const char *pszTemp就是pszTemp is a pointer to const char(C++标准里const放char前后是一样的),char * const pszTemp就是pszTemp is a const pointer to char,意义便一目了然。
    其实只要搞清楚常量指针和指针常量的意思就ok了,没必要太过于纠缠由它们组成的更加复杂的语法...

    回复删除