const关键字总结

1.const 对象

const int a = 5;
或
int const a = 5;
说明:

1)const对象由const关键字修饰。const对象的值一旦定义就不能修改,因此,const对象必须在定义时初始化。

2)const关键字和类型名称无顺序要求,可以将const写在int前,也可以写在int后

3)必须用字面值、常量表达式(在编译时即已知其值的变量可视为常量表达式)初始化const对象,例如:

int a = 5, b;
const int c1 = 5; //ok 字面值常量
const int c2 = a; //ok a在编译时已知结果,在此处可视为常量表达式
const int c3 = c1; //ok 常量
const int c4 = a*5; //ok 由于a是编译时已知结果的,所以可以认为是一个常量表达式
const int c5 = b; //error b在编译时无确定值
2.在全局作用域中定义的const对象默认具有文件级作用域,而非const对象默认具有全局作用域:
//a.cpp代码内容如下:
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

extern int a;
extern const int b;

int main()
{
	cout<<a<<endl;
	cout<<b<<endl;

	while(1)
	{
		//ignore
	}
	return 0;
}

//b.cpp代码内容如下:

int a = 5;
const int b = 10;
在windows环境下命令行编译a.cpp和b.cpp并链接它们(VC2012编译器)

cl -EHsc a.cpp b.cpp

此时你会发现,编译不通过,报错如下:

“无法解析对外部符号const int b的引用”

这就是因为b是文件作用域的对象,它在b.cpp文件之外不可见。我们可以使用extern关键字使其变为全局对象:

//修改b.cpp代码如下:

int a = 5;
extern const int b = 10;

再次编译,顺利通过,生成一个名为a.exe的可执行程序,运行它,我们可以看到正确输出数字5和10。

说明:

通过上面的例子我们可以看到,非const对象默认就具有全局作用域(我的说法:它们默认是extern的),而const对象默认为文件级作用域,要使它们具有全局作用域,必须在定义时用extern关键字修饰

3.指向const对象的指针(不可通过其修改所指对象,但本身可被修改的指针):

int a = 5;
const int b = 10;
	
int *pA = &a; //正确
int *pB = &b; //错误,b是const对象,因此pB也必须用const修饰

将上面pB的定义修改如下,再次编译:

const int *pB = &b; //正确

有趣的是,我们改写代码如下,再次编译,发现竟然也正确通过:

int a = 5;
const int b = 10;
	
int *pA = &a;
const int *pB;
pB = &b;
这是神马情况?不是说const 修饰的对象必须在声明时即给定初始值吗?这里貌似颠覆了这个规则。这里如果让你纠结了,那肯定是你还没有深刻理解const修饰的指针的正确涵义:const修饰的指针的正确涵义是“ 不可通过该指针修改其所指向的对象的值,而该指针本身不是const的”。我们可以如下实验:

int a = 5;
const int b = 10;
int c = 15;
	
const int *p1 = &a; //正确。声明时即给定初始值(声明时给定初始值,声明即是定义)
*p1 = 100; //错误,不能通过const修饰的指针修改其指向的对象

const int *p2; //正确。仅仅声明,而没有给定初始值(未给定初始值的申明不是定义,要注意区分)。如果const修饰的不是指针,必须用定义式
p2 = &a; //正确。可以给const修饰的指针赋值。即,可以改变const指针指向的地址值
p2 = &b; //正确。可以用const对象的地址值为const修饰的指针赋值
p2 = &c; //正确。也可用非const对象的地址值为const修饰的指针赋值
*p2 = 100; //错误,不能通过const修饰的指针修改其指向的对象

4.const指针(本身不可被修改,但可以通过其修改所指对象的指针):

如果要使指针本身是const的,可以如下定义该指针:

int a = 5;
int b = 10;
	
int *const p = &a;
p = &b; //错误,const类型的指针不能修改
*p = 100; //正确,虽然const 类型的指针不能修改,但其指向的对象如果是非const的,则可以通过const类型的指针进行修改

5.指向const对象的const指针(本身不能被修改,且不能其修改所指对象的指针)

如果需要一个本身不能被修改,且不能通过其修改所指对象的指针,我们可以如下定义该指针:

int a = 5;
int b = 10;

const int *const p; //错误,指向const对象的const指针必须初使用定义式声明
const int *const p = &a; //正确
p = &b; //错误,不可修改指向const对象的const指针
*p = 100; //错误,不可通过指向const对象的const指针修改所指对象

6.绑定const对象的引用必须也是const修饰的

const int a = 5;
int &r1 = a; //错误,绑定const对象的引用必须也是const修饰的
const int &r2 = a; //正确

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值