const 限定修饰符
与CONST相关的指针的问题就两个 ,即分清楚两个概念。
1、指向CONST对象的指针
作为CONST对象,在编译器理解来是一个常量,是一个不允许被修改的值,如果用普通定义的指针来指向的话,编译器会报错。所以定义了一种指向CONST对象的指针。
定义形式:
const double *cptr;
cptr 是一个指向double 类型的const 对象的指针,我们可以从右往左把这个定义读为
cptr 是一个指向double 类型的被定义成const 的对象的指针。此中微妙在于cptr 本
身不是常量,我们可以重新赋值cptr 使其指向不同的对象但不能修改cptr 指向的对象
例如:
const double *pc = 0;
const double minWage = 9.60;
// ok: 不能通过pc 修改minWage
pc = &minWage;
double dval = 3.14;
// ok: 不能通过pc 修改dval
// 虽然dval 本身不是一个常量
pc = &dval; // ok
dval = 3.14159; // ok
*pc = 3.14159; // 错误
const 对象的地址只能赋值给指向const 对象的指针,例如pc, 但是指向const 对象的
指针可以被赋以一个非const 对象的地址,例如
pc = &dval;
虽然dval 不是常量,但试图通过pc 修改它的值仍会导致编译错误,因为在运行程序
的任意一点上编译器不能确定指针所指的实际对象。
在实际的程序中,指向const 的指针常被用作函数的形式参数,它作为一个约定来保证
被传递给函数的实际对象在函数中不会被修改,例如
// 在实际的程序中, 指向常量的指针
// 往往被用作函数参数
int strcmp( const char *str1, const char *str2 );
2、const 指针指向一个const 或一个非const 对象
我们可以定义一个const 指针指向一个const 或一个非const 对象,例如
int errNumb = 0;
int *const curErr = &errNumb;
curErr 是指向一个非const 对象的const 指针,我们可以从右拄左把定义读作curErr
是一个指向int 类型对象的const 指针,这意味着不能赋给curErr 其他的地址值,但可以
修改curErr 指向的值。
下面的代码说明我们可以怎样使用curErr
do_something();
if ( *curErr ) {
errorHandler();
*curErr = 0; // ok: 重置指针所指的对象
}
试图给const 指针赋值会在编译时刻被标记为错误
curErr = &myErrNumb; // 错误
指向const 对象的const 指针的定义就是将前面两种定义结合起来例如
const double pi = 3.14159;
const double *const pi_ptr = π
在这种情况下pi_ptr 指向的对象的值以及它的地址本身都不能被改变,我们可以从
右往左将定义读作pi_ptr 是指向被定义为const 的double 类型对象的const 指针;
/****************************************************************************************************/
/*这个程序探讨的所有指针问题都只是基本数据类型,并没有讨论到函数指针和类指针*/
#include<iostream>
using namespace std;
void main()
{
int a=1,b=2;
int * p1,* p2;//只是普通的指针,只能指向普通的数据类型的对象的地址;
const int c=3,d=4;
const int *p3,*p4;//指向整型的,被定义成为const常量的对象的地址的指针;
int * const e=&a;//指向普通整型对象的地址,被定义成为const常量的指针;
const int * const f=&c;//指向const的常量对象的地址,被定义成为const常量的指针;
/*普通指针的赋值*/
p1=&a;
p2=&b;
cout << “—普通指针的赋值—” << endl;
cout << *p1 << endl;
cout << *p2 << endl;
cout << “——————————————-” << endl;
/*指向整型的,被定义成为const常量的对象的地址的指针*/
p3=&c;
p4=&d;
cout << “—指向整型的,被定义成为const常量的对象的地址的指针—” << endl;
cout << *p3 << endl;
cout << *p4 << endl;
cout << “——————————————-” << endl;
p3=p4;//这种指针可以改变它所指向的对象的地址;
p4=&c;
cout << “—这种指针可以改变它所指向的对象的地址—” << endl;
cout << *p3 << endl;
cout << *p4 << endl;
cout << “———————————————-” << endl;
//*p3=1;
//error,但是这种指针不可以改变它所指向的对像的值,因为对象是一个CONST常量;
p3=&a;//这种指针也可以指向普通数据类型的对象;
cout << “—这种指针也可以指向普通数据类型的对象—“<< endl;
cout << *p3 << endl;
cout << “——————————————“<< endl;
//*p3=5;
//error,虽然此时p3所指向的对象a是一个非const的普通对象,但仍然是无法通过
//p3来改变a的值;
/*指向整型对象的地址,被定义成为const常量的指针*/
*e=48;
//*f=4;
//error,无法修改f所指向的const常量的对象的值;
}