文字常量编译之后在代码区,不可寻址。
常变量可以寻址。
运行时常变量并不是放在只读内存中。而是和一般变量一样放在数据区。
所以运行时如果能够获得常变量的地址,一样可以通过特殊的途径对它们进行修改。
1 #include<iostream> 2 using namespace std; 3 void ShowValue(const int & i){ 4 cout<<i<<endl; 5 } 6 int main(){ 7 const int j = 5; 8 int *ptr; 9 void * p=(void *)&j; 10 ptr = (int *)p; 11 (*ptr)++; 12 ShowValue(j); 13 cout<<j<<endl; 14 } 15 输出: 16 6 17 5
其实j已经是6 但是直接输出j时,编译器会有一定的优化,将j直接变成数字5进行输出。
const使用位置比较灵活:
一般来说,除了修饰一个类的成员函数外,const不会出现在一条语句的最后。
const int p 与 int const p 一样,放在类型之前之后都可以。
int const *p 与 int *const p 不相同,前者修饰int 后者修饰int * ,前者表示p指向的是只读int 整形量 但是p指针是可以修改的。后者表示指针p本身不能够修改。
int const *p :为常指针,指向常量的指针。
int *const p:为指针常量,指指针本身就是常量。
解释:
int const **P : p所指向的类型为int const *(一个常指针,指向只读int整形常量)
int * const*p :p所指向的类型为int * const (一个指针常量)
所以以上两种赋值时,会有一定的讲究。
const对象和对象的const成员
const修饰的对象为常对象,而用const修饰的成员函数为常函数,在常函数中不能修改任何的成员变量。
通过常对象,只能调用常函数。
1 #include<iostream> 2 using namespace std; 3 class A{ 4 private: 5 int num; 6 public: 7 A(){num = 5;} 8 void disp(); 9 void disp() const; 10 void set(int n){num = n;} 11 12 }; 13 void A::disp()const{ 14 cout<<"const disp()"<<endl; 15 } 16 void A::disp(){ 17 cout<<"disp()"<<endl; 18 } 19 int main(){ 20 A al; 21 al.set(3); 22 al.disp(); 23 A const a2; 24 a2.disp(); 25 } 26 输出的内容: 27 disp() 28 const disp()
用const修饰函数的参数和函数的返回值
目的是让程序更健壮
1、用const修饰函数的参数时,主要是将别引用的变量和对象声明为常量。
2.当函数返回的是一个普通数据,而不是引用时,用const修饰函数的返回值没有太大的意义。
常见的const误解:
1、用const修饰的变量的值一定是不能改变的,在一些特殊情况下,可能需要临时改变一下常变量的值,而且这也是可以做到的。
2、常引用或常指针,只能指向常变量。这也是一个极大的误解。引用被声明为常引用(或指针被声明为常量的指针),只能说明不能通过该引用(或该指针)去修改被引用对象(或被指向单元)的值。至于被引用对象原来是什么性质,或者是否会被其他引用修改,是无法由常引用(或常指针)来决定的。