指针与const

1、将const用于指针有一些很微妙的地方,可以用三种不同的方式将const关键字用于指针。

方法一:让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值

首先,声明一个指向常量的指针pt:

int age = 39;
const int *pt = &age;

该声明指出,pt指向一个const int,因此不能使用pt来修改这个值。换句话说,*pt的值为const,不能被修改:

*pt = 20;//INVALID because pt points to const int
cin>>*pt;//INVALID for the same reason

pt的声明并不意味着它指向的值实际上是一个常量,而只是意味着对pt而言,这个值是常量。例如,pt指向age,而age不是const。可以直接通过age变量来修改age的值,但是不能用pt指针来修改它:

*pt = 20;//INVALID because pt points to a const int
age = 20;/VALID because age is not declared to be const

以前我们将常量的地址赋值给常规指针,而这里将常规变量的地址赋给指向const 的指针。因此还有两种可能:将const变量的地址赋给指向const的指针、将const的地址赋给常规指针。这两种操作第一中可行,第二种不可行。

const float g_earth = 9.80;
const float *pe = &g_earth;//VALID

const float g_moon = 1.63;
float *pm = &g_moon;//INVALID

 对于第一种情况而言,既不能使用g_earth来修改9.80,也不能使用pe来修改。C++禁止第二种情况的原因很简单——如果将g_moon的地址赋给pm,则可以使用pm来修改g_moon的值,这使得g_moon的const状态很荒谬,因此C++禁止将const的地址赋给非const指针。

方法二:将指针本身声明为常量,这样可以防止改变指针的位置。

请看下面的声明:

int age = 39;
const int *pt = &age;

第二个声明中的const只能防止修改pt指向的值(这里为39),而不能防止修改pt的值,也就是说,可以将一个新的地址赋给pt:

int sage = 80;
pt = &sage;//okay to point to another location

但仍然不能使用const的方式使得无法修改指针的值(现在为80)。

第二种使用const 的方式使得无法修改指针的值:

int sloth = 3;
const int *ps = &sloth;//a pointer to const int
int * const finger = &sloth;//a const pointer to int

在最后一个声明中,关键字const的位置与以前不同。这种声明格式使得finger只能指向sloth,但允许使用finger来修改sloth的值。中间声明不允许使用ps来修改sloth的值,但允许ps指向另一个位置。简而言之,finger和*ps都是const,而*finger和ps不是。

方法三:指向const对象的const指针:

double trouble = 2.0E30;
const double * const stick = &trouble;

其中,stick只能指向trouble,而stick不能用来修改trouble的值。简而言之,stick和*stick都是const。 

2、指针指向指针的情况

假如涉及的是一级间接关系,则将非const指针赋给const指针是可以的。

int age = 39;//age++ is valid operation
int *pd = &age;//*pd = 41 is a valid operation
const int *pt = pd;//*pt = 42 is an invalid operation

然而,进入两级间接关系时,与一级间接关系一样将const和非const混合的指针赋值方式将不再安全。如果允许这样做,则可以编写这样的代码:

const int **pp2;
int *p1;
const int n = 13;
pp2 = &p1;/not allowed,but suppose it were
*pp2 = &n;//valid, both const,but sets p1 to point at n

上诉代码将非const地址(&p1)赋给了const指针(pp2),因此可以使用p1来修改const数据。因此,仅当只有一层间接关系(如指针指向基本数据类型)时,才可以将非const地址或指针赋给const指针。

注意:如果数据类型本身并不是指针,则可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数据的地址赋给非const指针。

3、const与数组之间的关系

假设有一个const数据组成的数组:

const int months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

则禁止将常量数组的地址赋给非常量指针将意味着不能将数组名作为参数传递给使用非常量形参的函数:

int sum(int arr[], int n);//should have been const int arr[]
...
int j = sum(months, 12);//not allowed

上述函数调用试图将const指针(months)赋给非const指针(arr),编译器将禁止这种行为。

4、尽可能使用const的理由

将指针参数声明为指向常量数据的指针有两条理由:

一、这样可以避免由于无意间修改数据而导致的编程错误。

二、使用const使得函数能够处理const和非const实参,否则将只能接受非const数据。

5、const和函数之间的关系

通常,将指针作为函数参数来传递时,可以使用指向const的指针来保护数据:

void func(const double arr[], int n);

在该声明中使用const意味着func()不能修改传递给它的数组中的值。只要有一层间接关系,就可以使用这种技术。例如,这里的数组元素是基本类型,但如果它们是指针或指向指针的指针,则不能使用const。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
指针和const都是C++语言中非常重要的概念。 指针是一个变量,它存储了一个内存地址。通过指针,可以访问该地址处存储的数据。在C++中,我们使用*和&来声明和使用指针变量。 const关键字用于定义常量。在C++中,常量是不能被修改的值。使用const关键字可以使变量或函数参数成为常量。 指针和const可以一起使用,有以下几种情况: 1. const修饰指针变量,表示该指针变量指向的地址所存储的数据是常量,不能修改。 ```c++ const int* p; ``` 上述代码中,p是一个指向int类型常量的指针变量,即p指向的地址所存储的数据是常量,不能被修改。但是,指针变量p本身是可以修改的,可以指向其它地址。 2. 指针变量和const同时修饰变量,表示该变量是一个常量,同时指针变量也不能修改。 ```c++ int const* p; ``` 上述代码中,p是一个指向int类型常量的指针变量,同时p本身也是一个常量,不能被修改。 3. const修饰指针变量和指针变量所指向的数据类型,表示该指针变量和指针指向的地址所存储的数据都是常量,不能被修改。 ```c++ const int* const p; ``` 上述代码中,p是一个指向int类型常量的指针变量,同时p本身也是一个常量,不能被修改,指向的地址所存储的数据也是常量,不能被修改。 需要注意的是,const关键字的位置和使用方式会影响它所修饰的对象。在使用指针和const时,需要根据情况选择合适的修饰方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值