C++ primer 九 指针和 const

        将const用于指针有一些很微妙的地方(指针看起来总是很微妙),我们来详细探讨一下。可以用两种不 同的方式将const关键字用十指针。第一种方法是让指针指向一个常最对象,这样可以防止使用该指针来修改所指.14的值,第二种方法是将指针本身声明为常最,这样可以防止改变指针指向的位置。下面来看细节。

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

int age= 39;

const int * pt =&age;

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

*pt+= 1; // INVALID because pt points to a const inc_

cin >> *pt; // INVALID for the same reason

        现在來看一个微妙的问题。pr的声明并不意味着它指向的值实际上就足一个常量,而只是意味着对pt 而言,这个值是常量:例如,pt指向agc,而age不是const。可以直接通过age变量来修改age的值,但不能使用pt指针来修改它:

*pt= 20; II INVALID because pt points- to a const int

age= 20; If VALID because age is not declare^to be const

        以前我们将常规变最的地址陚给常规指针,而这里将常规变量的地址陚给指陆const的指针。因此还有两种可能:将const变量的地址賦给指向const的指针、将const的地址賦给常规指针。这两种操作都可行吗?第一种可行,但第二种不可行:

const float g_earth = 9.80;

const float * pe = tg_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指针。如果读者非要这样做,可以使用强 制类甩转换来突破这种限制。

       如果将指针指向指针,则情况将更复杂。假如涉及的是一级间接关系,则将非const指针陚给const指针是可以的:

int age= 39? // age++ is a valid operation

int * pd= &age; // *pd = 41 is a valid operation

const int * pt=pd; // *ptr = 42 is an invalid operatic

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

const int **pp2; 

int *p1;

const int n = 13;

pp2 = &p1// not aliowed,but suppose it were.

*pp2 = &nr // valid, both const, but sets pi to point at n 

*pi=10; // valid, but changes const n

        上述代码将非const地址(&p1)陚给了const指针(pp2)因此可以使用p1来修改const数据。因此,仅当只有一层间接关系(如指针指向基本数据类型)时,可以将非const地址或指针陚给const指针。
        注意:如果数据类型本身并不是指针,則可以将const数据或非const数据的地址賦给指向const的指 针,但只能将非const數据的地址蚊给非const指针。

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

const int monthstl2 = {31,28,31,30,3£,30, 31, 31,30,31,30,31};

则禁止将常量数组的地址陚给非常量指针将意味着不能将数组名作为参数传递洽使;丨i非常竜形参的函数:

int sum(int arr[],int n);

int j=sum(months,12);

上述函数调用试阁将const栺针(mbnths)赋给非const指针(arr\编译器将禁止这种函数调用。

为说明另一个微妙之处,请看下面的声

int age = 39;

consct int * pt = &age;

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

int sage= 80;

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

但仍然不能使用pt来修改它指向的值(现在为80)。

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

int sloth * 3;

const int * ps = &sloth; // a pointer t〇- const int

int * const finger= &sloth; // a const pointer co int

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

如果愿意,还可以声明指向const对象的const指针:

double trouble=2.3;

const double*const stick=&trouble;

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

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

void show_array(const double art[], int n) ;

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值