const限定符
1. 关键字:const
C++中,有个const关键字,该关键字可用来修饰变量、指针、函数等,用关键字const修饰的东西,其内容不可更改。因此,这个关键字const被叫做限定符,它限定了声明的含义。
2. 使用const声明常量
用const来修饰的变量,其值不可更改。通常,我们会将const变量叫做常量,C++中常用const声明常量的方式来替代使用#define宏定义声明常量。
使用const创建常量的通用格式如下:
const type name = value;
/*
type :为该常量的类型
name :为该常量的符号名称;
value:为常量的值;
*/
注意,在声明中对常量进行初始化,如果在声明常量时没有提供值,那该常量的值将不确定且无法修改。下面通过几个例子说明(笔者的例子是通过scons命令调用电脑自带的g++进行编译)。
(1)按正确格式声明并初始化ct_a,可正确输出ct_a的值,代码及运行结果如下:
void val_test1(void)
{
const int ct_a = 100; //使用const声明常量并初始化
cout << "ct_a的值为: " << ct_a << endl;
}
编译运行结果:
ct_a的值为: 100
(2)声明常量ct_a,但不进行初始化,代码及编译结果如下:
void val_test2(void)
{
const int ct_a; //使用const声明常量不初始化
cout << "ct_a的值为: " << ct_a << endl;
}
编译结果:
error C2734: “ct_a”: 如果不是外部的,则必须初始化常量对象
可见编译器会报错,提示进行初始化。
(3)声明常量ct_a且不进行初始化,但进行赋值操作,代码及编译结果如下:
void val_test3(void)
{
const int ct_a; //使用const声明常量不初始化
ct_a = 11; //给常量赋值
cout << "const变量ct_a的值为: " << ct_a << endl;
}
编译结果:
error C2734: “ct_a”: 如果不是外部的,则必须初始化常量对象
error C3892: “ct_a”: 不能给常量赋值
上面调试结果报了两个错误,一是常量要进行初始化,二是不可进行常量赋值。所以说,通过const限定符来声明常量,必须在声明时进行初始化。
3. const与指针
const用于指针的方式有两种,其一是让指针指向一个常量对象,其二是将指针本身声明为常量。
(1)指向常量的指针
声明一个指向常量的指针pt_a,pt_a指向的类型是const int类型,这并不是说它所指向的值本身是一个常量,而是对pt_a指针来说这个值是常量,指针不能修改它的值。换句话说,*pt_a的值为const,不能被修改。
void pt_test1(void)
{
int a = 10; //声明变量a并初始化为10
const int *pt_a; //声明指针pt_a,指向const int类型
pt_a = &a; //指针pt_a指向常规变量a,即把常规变量a的地址赋给指针
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译运行结果:
*pt_a的值为: 10
pt_a指向a,如果变量a本身不是const变量,则可以通过符号名称修改自己的值;如果变量a是const变量,那它实际也就是一个常量,不能通过符号名称修改自身的值。
void pt_test2(void)
{
int a = 10; //声明变量a并初始化为10
const int *pt_a = &a; //声明指针pt_a,指向const int类型,并初始化
*pt = 15; //改变指针所指向的值
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译结果:
error C3892: “pt_a”: 不能给常量赋值
void pt_test3(void)
{
int a = 10; //声明变量a并初始化为10
const int *pt_a = &a; //声明指针pt_a,指向const int类型,并初始化
a = 15; //改变变量值
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译运行结果
*pt_a的值为: 15
void pt_test4(void)
{
const int a = 10; //声明const变量a并初始化为10,常量
const int *pt_a = &a; //声明指针pt_a,指向const int类型,并初始化
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译运行结果:
*pt_a的值为: 10
void pt_test5(void)
{
const int a = 20; //声明const变量a并初始化为20,常量
const int *pt_a = &a; //声明指针pt_a,指向const int类型,并初始化
a = 25; //通过变量名改变变量值
*pt_a = 25; //改变指针所指向的值
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译结果:
error C3892: “a”: 不能给常量赋值
error C3892: “pt_a”: 不能给常量赋值
通过以上例子可看出,指向常量的指针,可以指向const或非const变量,但不可修改其所指向的值。如果指针指向的值本身是一个常规变量,那可通过变量自身来改变这个值,如果指针指向的值本身就是一个const变量,那这个值将无法更改。
常规指针不能指向const变量。 如下所示:
void pt_test6(void)
{
const int a = 20; //声明const变量a并初始化为20,常量
int *pt_a; //声明常规指针pt_a,指向int类型
pt_a = &a; //常规指针指向a
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译结果:
error C2440: “=”: 无法从“const int *”转换为“int *”
note: 转换丢失限定符
(2)const指针
前面声明的指向常量的指针pt_a,只能防止pt_a所指向的值被指针修改,但并不能防止更改pt_a本身的值,也就是说可以赋给pt_a一个新地址。可以将pt_a改成指向变量b,但仍然无法使用pt_a改变b的值。
void pt_test7(void)
{
int a = 10; //声明变量a并初始化为10
int b = 20; //声明变量b并初始化为20
const int *pt_a; //声明指针pt_a,指向const int类型
pt_a = &a; //指针pt_a指向变量a
cout << "*pt_a的值为: " << *pt_a << endl;
pt_a = &b; //指针pt_a指向变量b
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译运行结果:
*pt_a的值为: 10
*pt_a的值为: 20
可以使用const指针,使得指针的值固定(指针的值初始化后不可更改)。声明const指针时,关键字const位置与声明指向常量的指针稍微有些不同,声明const指针时必须同时初始化,否则将无法再更改指针的值,如下:
void pt_test8(void)
{
int a = 10; //声明变量a并初始化为10
int * const pt_a = &a; //声明const指针pt_a,指向int类型,并初始化
cout << "*pt_a的值为: " << *pt_a << endl;
}
编译运行结果:
*pt_a的值为: 10
void pt_test9(void)
{
int a = 10; //声明变量a并初始化为10
int b = 20; //声明变量b并初始化为10
int * const pt_a; //声明const指针pt_a,指向int类型
pt_a = &a; //指针pt_a指向变量a
cout << "*pt_a的值为: " << *pt_a << endl;
pt_a = &b; //指针pt_a指向变量b
cout << "*pt_a的值为: " << *pt_a << endl;
}
error C2734: “pt_a”: 如果不是外部的,则必须初始化常量对象
error C3892: “pt_a”: 不能给常量赋值
error C3892: “pt_a”: 不能给常量赋值
如果有需要,也可以声明指向常量的const指针:
const int * const pt_a; //声明const指针pt_a,指向const int类型
(后续更新……)