const和指针的结合

21 篇文章 1 订阅

const和指针的结合

在定义一个const指针常量的时候,不同位置的const产生的结果也是不同的。

首先我们需要知道,一个普通的指针是不能指向一个常量的地址的:

#include <stdio.h>

int main()
{
	const int a  = 10;
	int* p = &a;
}

上面的代码编译时无法通过的,这是因为a是一个常量,而如果我们把a的地址泄露给了一个普通的指针p,就相当于我们可以通过*p来间接修改a内存的值,这就有违背使用常量的初衷。但我们用一个常指针指向一个普通的变量是允许的。

要定义一个可以指向常量地址的指针,就需要用到const和指针的结合。

const和一级指针结合

const和一级指针的结合有三种方式:

  1. const int *p;int const *p;(这两条代码的效果是一致的)
  2. int * const p;
  3. const int * const p;int const * const p;

第一种方式的const修饰的是*p,就相当于我们无法再通过 *p来修改 p指向变量的值了,如在上面的代码中,我们要定义指向常量的指针,就可以用这种方式定义。
第二种方式的const修饰的是p,相当于我们无法再改变p的指向,如面向对象编程中的this指针。
第三种方式就是第一种方式和第二种方式的结合。

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	int a;
	const int* p1 = &a;
	int* const p2 = &a;
	const int* const p3 = &a;

	cout << typeid(p1).name() << endl;
	cout << typeid(p2).name() << endl;
	cout << typeid(p3).name() << endl;
}

在这里插入图片描述
上面程序的运行结果中,我们可以看到,第二种方式定义的指针,const和指针的类型是没有关系的,因此,第二种方式定义的指针赋值给一个普通的指针肯定也是可以的。
通过上面的分析我们可以知道:

  • const int a = 10; int *p = &a;int a; const int* p1 = &a; int* p2 = p1;用一个普通的指针指向一个const修饰的量是不允许的
  • int a; const int *p = &a;用一个const指针指向一个普通的变量是可以的
  • int a; int* const p1 = &a; int *p2 = p1;是允许的

const和二级指针结合

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	int a = 10;
	int* p1 = &a;
	const int** p2 = &p1;
}

上面的代码能不能编译通过呢?按照我们之前对一级指针的分析, int* p1; const int *p2 = p1;是允许的,那const int** p2 = &p1;是不是也可以呢?
答案是不行的:
在这里插入图片描述
这里解释以下错误的原因:
二级指针p2涉及三个表达式:p2、*p2、**p2
const修饰的是 **p2,**p2的值不能修改,但是 *p2的值是可以修改的。

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	int a = 10;
	int* p1 = &a;
	const int** p2 = &p1;
	const int b = 20;
	*p2 = &b;
}

分析上面的代码,假设可以编译通过,如果我们把 *p2指向一个常量的地址,那么就可以通过 *p1 修改 常量b的值,也就是把一个常量的地址泄露给了一个普通的指针,这是不允许的。

要使编译可以通过,我们可以这样修改,把p1声明为const int* p1 = &a;,这样我们就不能通过 *p1修改值了;或者把p2声明为const int* const * p2 = &p1;这样 *p2就不能被修改,就不会发生上面的错误了。

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	int a = 10;
	const int* p1 = &a;
	const int** p2 = &p1;
}
#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	int a = 10;
	int* p1 = &a;
	const int* const * p2 = &p1;
}

其他const和二级指针结合的情况可以用和一级指针结合的情况来分析,这里就不再赘述。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值