-
先说说我对编译器对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++一书的笔记和自己后来的部分总结 由于水平有限 错误在所难免 请不吝指正
-
" src="http://student.csdn.net/ucenter/data/avatar/000/03/91/02_avatar_small.jpg" />
回复#1
韩卫平(C/C++老师)
2009-04-27 21:37
写的不错
还应加加一点 const &可以引用一个临时变量。生存周期同变量周期
const int& x = 1;合法
int& x = 1;不合法
-
回复#2
李羽 2009-04-27 21:41
韩卫平(C/C++老师)
: 写的不错
还应加加一点 const &可以引用一个临时变量。生存周期同变量周期
const int& x = 1;合法
int& x = 1;不合法谢谢韩老师指出不足
学习了 去试试
-
回复#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,试了一下,编译是通过的。在我用它们为左值的时候才报错。
-
" src="http://student.csdn.net/ucenter/data/avatar/000/03/90/28_avatar_small.jpg" />
回复#5
普罗通信西安有限公司 肖舸(C/C++老师)
2009-04-29 12:02
写得好,我加精了。呵呵。
-
回复#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
-
回复#8
华南理工大学 刘雪赟(Java学生) 2009-12-05 17:20
学到了很多,谢谢啦
-
回复#9
南昌大学 陈旁(C/C++学生) 2009-12-05 22:42
const int a=5,
int Arry[a]={1,2,3,4,5};如果去掉const,会出错,为什么啊?
-
回复#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;
}
-
回复#11
南昌大学 陈旁(C/C++学生) 2009-12-06 22:45
CAS 吕泰昌(C/C++学生): C99标准规定了,可以使用变量表达式作为数组下标,这种数组叫做可变长数组。但是大多数编译器不支持这个特性,GCC支持了,不过跟C99还有点不一样。
但是你用const限定之