常量
有些变量,因为程序需要,不能在编程过程中对其进行修改,则用"const"关键字修饰即可,如下:
const int iTest = 100;或者 int const iTest = 100;
这称为常量。一经定义后,便不能再修改。以上两种定义都是合法的!
const 引用
对于上面的常量,因为其数据不能修改,所以其对应的引用,也要不能修改,这样的引用,则为const 引用,如下:
const int& rTest = iTest;
如果定义一个普通的引用指向iTest,例如 int& rTemp = iTest;编译器会直接报错。原因很简单,既然定义了const int对象,则说明不想在程序中修改这个变量,而普通引用是可以修改值的,这与最初的声明违背了,报错很合理!
指针和const
既然有const 引用,是不是也有const 指针?答案是肯定的,但是,有一些区别。
引用一经定义,其指向便不能修改。但是指针不同,普通指针定义了后,是可以修改指向的,例如下面的代码:
int iValue_1 = 100;
int iValue_2 = 50;
int& rValue = iValue_1; //定义后,rValue就是iValue_1
rValue = iValue_2; //这里不是修改rValue的指向,而是将iValue_2的值赋给rValue,会导致iValue_1跟着改变
int *pValue = &iValue_1;
pValue = &iValue_2; //pValue指向是iValue_2的地址
因此,指针会更复杂。
1、常量指针
与引用一样,既然有常量存在,就必须要有指向常量的指针,要求不能通过这个指针修改对应的常量数值,于是,常量指针应运而生。
对于常量 const int iTest = 100;其对应的指针定义应该如下:
const int *pTest = &iTest; 或者 int const *pTest;
这两者是等价的!这与常量的定义非常类似,可以理解为,const 修饰的是“*pTest”,即是一个常量对应的指针。
常量指针,其指向是可以修改的,但是不能通过它改变其对应的变量的数值。
常量,必须用常量指针!
如下:
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
const int ciValue_1 = 100;
const int ciValue_2 = 50;
const int *pTest = &ciValue_1;
cout << *pTest << endl;
//*pTest = 30; //无法通过编译
pTest = &ciValue_2; //改变了指向
cout << *pTest << endl;
system("pause");
return 0;
}
执行结果如下:
为什么要叫做“常量指针”,而不称为指向常量的指针呢?因为这种形式定义的指针,是可以指向普通(非常量)变量的,如下:
int _tmain(int argc, _TCHAR* argv[])
{
int iValue_1 = 100;
int iValue_2 = 50;
const int *pTest = &iValue_1;
//*pTest = 30; //无法通过编译
pTest = &iValue_2;
std::cout << *pTest << std::endl;
system("pause");
return 0;
}
与前面代码唯一的区别, pTest指向的不是常量,而是普通的变量,只不过依然不能通过这个指针来修改变量的值。
从pTest的角度来看,其指向的,就是一个常量(因为无法通过pTest来改变数值),所以称之为常量指针,即一个常量的指针。
2、指针常量
上面介绍的指针,只是不能修改指针指向的变量数值,指针本身的指向可以被修改,那有没有指向一旦指定后,便不能修改的指针呢?
功能如此强大的C++,肯定是有的,这就是指针常量,即指针本身是常量。
需要注意:指针常量,一旦定义,必须立即初始化。
形如“int* const cpTest ;”这种定义是非法的,无法通过编译。合法的定义应该如下:
int iValue_1 = 7;
int* const cpTest = &iValue_1;
指针常量,其指向一旦定义后便不能再修改,但是其值可以被修改。
如下:
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
int iValue_1 = 7;
int iValue_2 = 3;
int* const cpTest = &iValue_1;
//cpTest = &iValue_2; //无法通过编译
*cpTest = 15; //可以修改值
cout << *cpTest << endl;
system("pause");
return 0;
}
执行结果如下:
可以看出来,指针常量,指向的是普通的变量(非常量)。
如果尝试将此指针常量,指向常量,会发现编译不过:
原因很简单,通过这个指针,是可以修改对应的变量的值,这与常量的定义相冲突!
如果想要一个指向常量的且本身不能修改指向的指针,就会引出下一个概念,指向常量的指针常量。
3、指向常量的指针常量
指针的定义,就是将前两种合起来,类似 “const int* const pTest = ...”的形式。
指向常量的指针常量,一旦定义,必须立即初始化,且不能修改指针指向,也不能通过指针修改对应变量的值。
某种意义上来说,“指向常量的指针常量”这个描述不太合理,因为这种形式的指针,是可以指向普通(非常量)变量的,如下:
int _tmain(int argc, _TCHAR* argv[])
{
int iValue_1 = 100; //普通(非常量)变量
int iValue_2 = 50;
const int* const pTest = &iValue_1;
//*pTest = 30; //无法通过编译
//pTest = &iValue_2; //无法通过编译
system("pause");
return 0;
}
但是,如果叫做“常量指针常量”又有些不妥,所以干脆站在指针本身的角度出发,叫做这个名字。