C++中普通指针、常量指针以及指向常量的指针的用法详解

目录

普通指针

指针的定义

获取对象的地址

注意事项及错误示范

利用指针访问对象

指向常量的指针

常量指针

普通指针

指针的定义

允许在一条语句中定义多个指针,其形式是将声明符写成 *d ,其中d是变量名

int *ip1, *ip2; //ip1和ip2指向int型对象的指针 
double dp1, *dp2; //dp1是定义的double型对象,dp2是指向double型对象的指针

double d1;
double* dp3 = &d1; //正确,初始值是double型对象的地址
double* dp4 = dp3; //正确,初始值是指向double对象的指针
double* dp5 = &dp3; //错误,dp3本身就是指针类型,其初始值就是某个对象的地址,直接赋给指针dp5即可,不需要使用取地址符&

获取对象的地址

指针存放某个对象的地址。要想获取该地址,需要使用取地址符 &

int ival = 6;
//对指针p进行初始化,初始值是int型对象ival的地址
int* dp = &ival; //dp存放ival变量的地址,或者说p是指向变量ival的指针
cout << p << endl; // 000000A72BF9F8A4 每次执行内存地址都会变化

注意事项及错误示范

  • 引用不是对象,没有实际的地址,所以不能定义指向引用的指针

  • 不能用int型变量来初始化指针(需要加取地址符&),这与引用的初始化不同。

  • 将指针的初始值指向另一个指针,不需要使用取地址符&

double* dp4 = dp3; //正确,初始值是指向double对象的指针
double* dp5 = &dp3; //错误,dp3本身就是指针类型,其初始值就是某个对象的地址,直接赋给指针dp5即可,不需要使用取地址符&
  •  所有指针的类型都要与它所指向的对象的类型相匹配
double d1;
double* dp = &d1; //正确
double* dp2 = dp; //正确

// int* pi = dp; //错误,指针pi的类型与指针dp的类型不匹配
// int *pi = &d1; //错误,不能将double型对象的地址赋给int型指针

利用指针访问对象

  • 使用解引用符( * ),来访问对象
int ival = 12;
int* dp = &ival;
//利用指针访问对象,使用解引用
//由解引用符*得到指针dp所指对象,输出12
cout << *dp << endl;
  • 对指针解引用会得出所指的对象,可以经由这个规则,对指针所指的对象进行操作

  • 由解引用符*得到指针所指对象,可经由对指针解引用(如 *dp) 来对所指对象进行赋值操作

#include <iostream>
using namespace std;

int main() {
	int ival = 12;
	/*
	对指针dp进行初始化,三种说法:
	1.指针dp存放了变量ival的地址
	2.指针dp是指向int型对象ival的指针
	3.指针dp的初始值是变量ival的地址
	*/
	int* dp = &ival;
	//利用指针访问对象,使用解引用
	cout << *dp << endl;
	*dp = 3; //由解引用符*得到指针dp所指对象,即可经由dp为变量ival赋值
	cout << "ival = " << ival << endl;
	cout << "*dp(利用指针访问对象)" << *dp << endl;
	return 0;
	system("pause");
}

指向常量的指针

要想存放常量对象的地址,只能使用指向常量的指针,并且不能通过该指针去改变其所指对象的值,但是可以重新给该指针赋值,并且可以令其指向非常量的对象

#include <iostream>
using namespace std;

int main() {

	/*
	从右往左阅读,得出cptr只是一个指向常量的指针,并不是常量指针
	故cptr的值(存放在指针中的地址)可以改变
	*/
	double pval = 4.2;
	const double pi = 3.14;
	// double* ptr = &pi;//错误
	const double* cptr = &pi; //cptr只是一个指向常量的指针
	//*cptr = 42;//错误
	
	cout << "cptr指向常量pi时所存放的地址为:" << (int)cptr << endl;
 	cptr = &pval; //重新为指向常量的指针赋值
	cout << "cptr指向非常量pval时所存放的地址为:" << (int)cptr << endl;
	
	const double* const pip = &pval; //正确
	//double* const cpip = &pi; //错误

	const double* p1 = &pval; //正确

	return 0;
	system("pause");
}

常量指针

  • 把 * 写在const前面 用以说明指针是一个常量

  • 因为指针是对象(引用不是),所以允许将指针本身定义为常量。常量指针必须初始化,一旦初始化完成,它的值(存放在指针中的那个地址)就不能改变了(注意与指向常量的指针做对比)

  • 指针本身是一个常量,并不意味着不能通过指针去修改所指对象的值,常量指针可以指向常量对象,也可以指向非常量对象

    • 如果常量指针指向的对象是一个常量,则常量指针的值(存放的那个地址)和所指对象的值都不能被改变

    • 如果常量指针指向的对象是一个非常量对象,那么就可以通过常量指针去修改所指对象的值

int errNum = 0;
const double pi = 3.14159;
double pval = 4.2;

//curErr指向的是一个非常量对象
int * const curErr = &errNum; //curErr是常量指针,其值不能被改变

//pip指向的是一个常量
const double *const pip = &pi; //pip是一个指向常量对象的常量指针(从右往左来理解)
double *const pip = &pi; //错误,常量指针指向常量对象时,类型修饰应该是const double

const double* const cpi = &pval; //正确
  • 常量指针不能用于初始化普通指针,普通指针可以用于初始化常量指针

    int ival = 42;
    int* p1 = &ival;
    const int* const p3 = p1; //正确,普通指针可以用于初始化常量指针
    int* p4 = p3; //错误,常量指针不能用于初始化普通指针

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值