1、const 修饰变量
用 const 定义常变量的方法
const int a = 10;
int const a = 10;
这两个语句是一样的,const 关键字的位置和数据类型的位置的前后没影响,它只修饰a这个变量,它和其他的修饰符一样
- 用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。并且 const 修饰的变量在定义的时候就给它赋初值
- 用 const 修饰的变量,无论是全局变量还是局部变量,生存周期都是程序运行的整个过程。全局变量的生存周期为程序运行的整个过程这个是理所当然的。
- 而使用 const 修饰过的局部变量就有了静态特性,它的生存周期也是程序运行的整个过程。我们知道全局变量是静态的,静态的生存周期就是程序运行的整个过程。但是用 const 修饰过的局部变量只是有了静态特性,并没有说它变成了静态变量。
2、const 修饰指针
//以下两者等价,表示 *p 不可变。*p 表示的是指针变量 p 所指向的内存单元里面的内容,
//此时这个内容不可变,而指针变量p的值是可变的
const int *p
int const *p
//此时 const 修饰的是 p,所以 p 中存放的内存单元的地址不可变,而内存单元中的内容可变。
//即 p 的指向不可变,p 所指向的内存单元的内容可变;
int * const p
//*p 和 p 都被修饰了,那么 p 中存放的内存单元的地址和内存单元中的内容都不可变;
const int * const p
3、const 修饰函数
3.1const 修饰在函数名前面
const char * GetString(void);
const int GetInt(void);
const float GetFloat(void);
const double GetDdouble(void);
如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针;
const char * GetString(void);
//如下语句将出现编译错误:
//char *str = GetString();
//正确的用法是
const char *str = GetString();
3.2const 修饰在函数名前面
在函数名后面表示是 C++ 常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。
- const 对象只能访问 const 成员函数,而非 const 对象可以访问任意的成员函数,包括 const 成员函数;
- const 对象的成员是不可修改的,然而 const 对象通过指针维护的对象却是可以修改的;
- const 成员函数不可以修改对象的数据,不管对象是否具有 const 性质.它在编译时,以是否修改成员数据为依据,进行检查;
- 然而加上 mutable 修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的 const 成员函数是可以修改它的;
4.const 修饰函数参数
- 值传递:实参是传递的值,并非地址,形参的值发生改变,实参不受影响;即创建新变量,分配新空间,复制一份值保存起来
- 址传:实参是传递的地址,并非值,形参的值发生改变,实参会跟着一起改变(因为实参和形参都是指向同一块内存地址);
void StringCopy (char*str, const char *strSource);
- 如果函数参数采用“指针传递”或”引用传递",那么加 const 修饰可以防止意外地改动该指针,起到保护作用。
- 如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加 const 修饰
- 如果参数作为输出参数,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能(因为有 const 修饰之后,不能改变他的值)。
- const char* str, str本身是常量指针,指向一个char类型对象,指针str不能被修改,但它指向的char*对象仍然可以修改
- 也可以定义为char* const str,str指针本身不能修改,但它指向的char*仍可以修改
- 如果将str定义为const char* const str,那么str和它指向的对象都将是常量
此时既不能修改str指针,也不能修改它指向的char对象