我对const修饰符应用的理解

  • 先说说我对编译器对const处理的理解:const修饰符定义一个常量,const变量在整个程序中只有一个拷贝。编译器会跟踪所有用到这个常量的地方,一旦发现任何一个操作可能会改变这个它是常量这个属性,那么这个操作就是不合法的:
        const int val =10;
        int* pTemp=&val;              //不合法,因为用户可能试图通过pTemp指针改变val这个常量的值,这样就改变了val是一个常量的属性

    当对指针或者引用使用const修饰符的时候,根据const的位置有俩种不同的含义:
    1 当const在类型名前,表示指针或者引用所指向的值不能通过间接引用指针或者通过引用来改变
      const int val = 10;
      const int *constp = &var;       //OK.但是*constp不能作为赋值运算的左操作数出现
      int* ptemp = constp;             //不合法,因为不能保证temp指针不会试图去修改它所指向的数据的值
      const int &constr = var ;       //OK.但是constr不能作为赋值运算的左操作数
      int&  rtemp = val;              //不合法,因为val是常量,而rtemp不能保证不会试图修改val的值
      在这里。修改变量val的值是不合法的,因为val已经声明为常量。间接的修改也是不合法的,者并不是因为val是常量,而是因为指针(或引用)变量定义为指向常量。对于指向常量的指针或者引用,间接的修改时不合法的,即使它指向一个非常量的值,例如:
      int val = 10;
      const int *constp =&val;        //*constp任然不能作为赋值运算的左操作数出现
      const int &constr = val;        //constr 不能作为赋值运算的左操作数出现

    2 当const在类型名后指针名之前出现,表示指针式常量,它可以被间接引用,它所指向的数据的值可以改变,但是指针所指向的地址不能改变,这类指针应该在定义时初始化,因为如果在定义时没有初始化,那么这个指针就会毫无意义,因为以后再也不能赋值了。
       int val =10;                 
       int *const constp=&val;         //val变量的地址值将伴随整个constp的生命周期
       *constp = 20;                   //合法的,constp所指的数据的值可以改变
       constp=NULL                    //语法错误,因为指针是常量,它做指向的地址不能改变

       int* pTemp = constp;            //合法的,都可以间接修改变量的值。

    const在函数声明中的应用
       const对函数的返回值以及参数的修饰作用可以参考上面的内容。
       在类中声明的const成员变量,只能通过类构造函数的成员初始化列表初始化:具体可参看成员初始化列表和构造函数体类初始化的不同
       const类型的类对象只能调用const成员函数

       在类成员函数常见到const用在参数列表后函数体前
       这种情况下 该成员函数的生命和定义中都要使用这个const;
       这样的成员函数不能修改类的数据成员不能在函数中调用其它的非const成员函数

    主要是看core c++一书的笔记和自己后来的部分总结  由于水平有限  错误在所难免 请不吝指正

  • 李羽

    回复#2

    李羽 2009-04-27 21:41

    韩卫平(C/C++老师): 写的不错
    还应加加一点 const &可以引用一个临时变量。生存周期同变量周期
    const int& x = 1;合法
    int& x = 1;不合法

    谢谢韩老师指出不足
    学习了  去试试

  • 南昌大学 梁乃华(C/C++学生)

    回复#3

    南昌大学 梁乃华(C/C++学生) 2009-04-28 22:29

    int val = 10;
      const int *constp =&val;        //*constp任然不能作为赋值运算的右操作数出现
      const int &constr = val;        //constr 不能作为赋值运算的右操作数出现
    疑问?*constp任然不能作为赋值运算的右操作数出现。constr 不能作为赋值运算的右操作数出现.
    它们不可以作为赋值运算的右操作数出现??
    我用vc6.0,试了一下,编译是通过的。在我用它们为左值的时候才报错。

  • 李羽

    回复#4

    李羽 2009-04-29 09:26

    对不起 写错 确实是左操作数   因为作为右操作数是不会改变改变val的值的    对不起

  • 李羽

    回复#6

    李羽 2009-04-29 13:37

    普罗通信西安有限公司 肖舸(C/C++老师): 写得好,我加精了。呵呵。

    谢谢 肖老师   嘿嘿

  • CAS 吕泰昌(C/C++学生)

    回复#7

    CAS 吕泰昌(C/C++学生) 2009-12-05 13:53

    const关键字在C语言中的作用仅仅是限定 不可以通过const变量来修改内存数据,但是可以通过别的方式,例如指针指向const变量然后再修改内存中的值。
    但对于const关键字的优化gcc和g++的处理还有些不一样(以下对C/C++的描述可缩小范围为gcc/g++的描述)。
    例如以下代码:
    Code:
       1. #include   
       2.   
       3. int main()  
       4. {  
       5.     const int a = 100;  
       6.     int *p = (int *)&a;  
       7.     (*p)=1;  
       8.     printf("%d",a);  
       9.     return 0;  
      10. }   
    在gcc下编译运行通过,输出1。
    在g++下编译运行通过,输出100。调试过程中发现在printf("%d",a);这句的时候没有从内存中读取a的值,而是直接用100这个字面常量。这就是const关键字优化的结果,如果定义的时候换成volatile const int a = 100; 用volatile关键字限定的话就输出的1。
    但是使用O2开关优化的时候,采用gcc/g++ (GCC) 3.4.5 (mingw-vista special)时,无论gcc还是g++都是输出100,加了volatile关键字也不起作用了。在gcc/g++ (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)中只要加入volatile,输出就是1。看来不同版本的编译器,不同的系统还有不一致的情况。所以这个结果提醒我们,不要试图修改const变量值,保不准会出现什么问题。
    http://student.csdn.net/space.php?uid=53444&do=blog&id=17766

  • CAS 吕泰昌(C/C++学生)

    回复#10

    CAS 吕泰昌(C/C++学生) 2009-12-06 07:42

    南昌大学 陈旁(C/C++学生): const int a=5,
    int Arry[a]={1,2,3,4,5};如果去掉const,会出错,为什么啊?

    C99标准规定了,可以使用变量表达式作为数组下标,这种数组叫做可变长数组。但是大多数编译器不支持这个特性,GCC支持了,不过跟C99还有点不一样。
    但是你用const限定之后就是常量表达式,对这个支持的编译器还是很多的。
    下面的代码在gcc/g++ (GCC) 3.4.5 (mingw-vista special) 中可用,输出结果是404
    #include
    int main()
    {
            int a = 100;
            int b[++a];
            printf("%d",sizeof(b));
            return 0;
    }

  • 南昌大学 陈旁(C/C++学生)

    回复#11

    南昌大学 陈旁(C/C++学生) 2009-12-06 22:45

    CAS 吕泰昌(C/C++学生): C99标准规定了,可以使用变量表达式作为数组下标,这种数组叫做可变长数组。但是大多数编译器不支持这个特性,GCC支持了,不过跟C99还有点不一样。
    但是你用const限定之

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值