[c++]常量指针和指针常量区别

1.指向const对象的指针 (常量指针)

const double *cptr;

这里的cptr是一个指向double类型const对象的指针,const限定了cptr指针所指向的对象类型,而并非cptr本身。也就是说cptr本身并不是const。在定义时不需要对它进行初始化,如果需要的话,允许给cptr重新赋值,使其指向另一个const对象。但不能通过cptr修改其所指对象的值:

*cptr=40;//报错,*cptr应该是const类型

把一个const对象的地址赋给一个普通的,非const对象的指针也会导致编译时的错误:

const double pi=3.14;
double *ptr=π//报错:ptr是一个普通指针
const double *cptr=π//OK: cptr是一个指向const对象的指针

也不能使用void指针保存const对象的地址,而必须使用const void类型的指针保存const对象的地址:

const int universe=40;
const void *cpv=&universe;//OK
void *pv=&universe;//报错:universe是const常量

允许把非const对象的地址赋给指向const对象的指针,例如:

double dval=3.14;
const double *cptr=&dval;//OK:但是不能通过cptr来修改dval的值

尽管dval不是const对象,但任何企图通过指针cptr修改其值的行为都会导致编译时的错误。cptr一经定义,就不允许修改其所指向对象的值。如果该指针恰好指向非const对象时,同样必须遵循这个准则。

然而,事实是可以修改const指针所指向的值,这一点尝尝容易引起误会。

double dval=3.14159;
const double *cptr=3.14159;//报错:cptr是指向const对象的指针
const double *cptr=&dval;//OK: 允许把非cosnt对象的地址赋给指向const对象的指针 
double *ptr=&dval; //OK:ptr指向dval
*ptr=2.72;//OK: ptr是普通指针可以修改
cout<<*cptr<<endl;//OK:输出2.72

在上例中,指向const的指针cptr实际上指向了一个非const对象。尽管它所指的对象并非const,但仍不能使用cptr修改该对象的值。本质上说,由于没有方法分辨cptr所指的对象是否为const,系统会把它所指的所有对象都视为const。

如果指向const的指针所指向的对象并非const,则可直接给该对象赋值或间接地利用普通的非cosnt指针修改其值:毕竟这个值不是const。只要的是要记住:不能保证指向const对象指针所指对象的值一定不可以修改

在实际的程序中,指向const的指针常用作函数的形参。将形参定义为指向const的指针,以此确保传递给函数的实例对象在函数中不因为形参而被修改。

2.const指针 (指针常量)

除指向const对象的指针外,C++语言还提供了const指针——本身的值不能修改:

int errNumb=0;
int *const curErr=&errNumb;//指针curErr是一个常量

上述定义语句读作 curErr是指向int型对象的const指针。与其他const量一样,const指针的值不能修改,这就意味着不能使curErr指向其他对象。任何企图给const指针赋值的行为都会导致编译时的错误。并且与任何const量一样,const指针也必须在定义时初始化。
当然尽管指针本身是const的事实并没有说明是否能使用该指针修改它所指向对象的值。指针所指对象的值能否修改完全取决于该对象的类型。例如curErr指向一个普通的非常量int型对象errNumb,则可使用curErr修改该对象的值:

if(*curErr){
*curErr=10;//OK: 此时errNumb值被修改为10
}

3.指向const对象的const指针

定义如下:

const double pi=3.14159;
const double *const pi_ptr=&pi;

本例中,既不能修改pi_ptr所指向对象的值,也不允许修改该指针的指向(即pi_ptr中存放的地址值)。读作pi_ptr首先是一个const指针,其指向double型的const对象。


下面给出一个C++上的例子:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a=10;
	int b=20;
	int e=40;
	const int* d=&b;//常量指针 
	cout<<"d:"<<d<<" "<<*d<<" "<<b<<endl;
	//*d=20; 不能通过常量指针来修改变量的值
	b=30; //可以通过修改常量指针指向的对象值 来修改常量指针的值 
	d=&e;//同时常量指针可以指向任意其他地址  
	cout<<"after d:"<<d<<" "<<*d<<" "<<b<<endl;
	
	
	int* const c=&a;//指针常量 
	cout<<"c:"<<c<<" "<<*c<<" "<<a<<endl;
	//c=&e; 对于指针常量 不能修改其指向的地址 
	
	*c=15; //但是可以通过指针来修改变量的值 
	
	cout<<"after c:"<<c<<" "<<*c<<" "<<a<<endl;

	return 0;
} 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值