C++ Primer学习笔记 - 10 - 基本内置类型 (五)

2.4节 const限定符

主要概念

  1. const限定符可以在编译层面防止对一个变量的值进行修改。
  2. 默认状态下const变量仅在文件内有效,并且定义时就必须进行初始化。
  3. 使用extern关键字可以仅声明,而在定义时再对其进行初始化。
  4. 使用extern关键字可以对一个变量在多个文件中进行声明,但仅在一个文件中进行定义,在使用时这些文件可以共用同一个变量。

练习

练习2.24:下面哪些句子是合法的?如果不合法,为什么?

const int buf; //不合法,没有extern关键字的const变量必须被初始化
int cnt = 0;//合法
const int sz = cnt;//合法
++cnt;++sz;//不合法,++cnt可以运行,++sz不合法。

2.4.1 const引用 2.4.2 指针和const

主要概念

  1. const修饰的变量也可以被引用,但是这个引用也必须是const修饰的。这个引用同样不能修改被引用的const变量。这被称为对常的引用(reference to const)。
  2. const引用有一种特殊情况,可以使用字面值常量进行初始化,其本质是编译器创建了一个临时的const变量(临时量,temporary),然后将这个const设置为对这个缓存的const变量的引用。例如:const int &a = 3.14;
  3. const引用可以引用一个非const对象,但是const对象只能被const引用引用。
  4. const修饰的变量也可以被指针指向,与引用相同,这个指针的类型也必须是const修饰的。
  5. const类型的指针可以指向非const类型的对象,但是如4条情况,const类型的对象的指针也必须是const类型的。
  6. 注意,在这条前,所有的const类型都是在基本内置类型之上形成的const,以int类型为例,新组成的类的类型是const int类,而下面这一条,它的类型是*const类。
  7. 由于指针本身也是一个对象,所以指针也可以被const修饰,此时写法与之前有区别:double *const p = 0;。两种类型写法对比如下 :
const int *p ;//这种写法声明的是一个指向const int类型的值的指针,事实上指针本身还是可以修改的
int *const p ;//这种写法声明的是一个指向int类型的变量的指针,它的本质是将指针声明为了const,所以在声明时必须对它进行定义

练习

  1. 练习2.27:下面哪些初始化是合法的?请说明原因
int i = -1,&r = 0; //不合法,&r必须引用一个int类型的变量
int *const p2 = &i2;//不合法,这里i2是一个const int 类型的变量,但p2是一个int型的指针,类型不匹配。
const int i = -1,&r = 0;//合法,i=-1是正常的语句,&r会引用一个临时量
const int *const p3 = &i2; //合法,i2和p3都是const int类型的值
const int *p1 = &i2;//合法,p1和i2都是const int的值
const int &const r2; //不合法,由于引用不是一个对象,所以不存在&const类型
const int i2 = i,&r = i;//合法,第一句是一个普通的const int类型变量的定义,第二句是一个对普通int值的const int 引用。
  1. 练习2.28:说明下面这些定义是什么意思,挑出其中不合法的
int i,*const cp ;//这里只进行了声明,声明了一个int型的i,和一个int型的const指针。这一行是不合法的,因为const指针在声明时必须被初始化。
int *pl,*const p2;//声明了一个int型的普通指针,这一部分是合法的;另外又声明了一个int型的const指针,与上一行一样同样的原因,也是不合法的。
const int ic,&r = ic; //声明了一个const int类型的变量ic,此时ic必须同时被显式定义,因此这部分是不合法的;后半部分是合法的。
const int *const p3;//声明了一个const int 类型的const指针,这里const指针必须在声明时显式定义,因此这是不合法的。
const int *p;//合法,声明了一个const int 类型的指针。
  1. 练习2.29:假设已有上一个练习中定义的变量,则下面哪些语句是合法的?说明原因:
i = ic;//合法,ic是const int类型,可以用于给int型赋值
p1 = p3;//不合法,p1是int类型指针,p3是const int类型。
p1 = ⁣//不合法,与上一行相同
p3 = ⁣ //不合法,p3是const指针,不能被赋值
p2 = p1;//不合法,p2是const指针,不能被赋值
ic = *p3;//不合法,ic是const 类型,不能被赋值

2.4.3 顶层const

主要概念

顶层const 表示指针本身是个常量,即int *const p的写法;
底层const 表示指针所指的对象是个常量,即const int *p的写法;
一个指针可以同时是顶层和底层const,即const int *const p
顶层和底层的核心区别在于这个变量本身能不能被修改。

练习

  1. 练习2.30:对于 下面这些语句,表说明 对象被声明成了顶层const还是底层const?
const int v2 = 0; //顶层const,因为这个变量的值不能被修改
int v1 = v2;
int *p1= &v1,&r1 = v1;
const int *p2 = &v2,//底层const
*const p3 = &i ,//既是顶层,又是底层
&r2 = v2;
  1. 练习2.31:假设已有上一个练习中所做的那些声明 ,则下面的哪些语句是合法的?
r1 = v2;//合法
p1 = p2;//不合法,必须同是底层或都不是底层才能进行赋值
p2 = p1;//合法
p1 = p3;//不合法,同上上行
p2=p3;//合法,都是底层const类型

2.4.4 constexpr表达式

主要概念

  1. 常量表达式(const expression)是指值不会改变并且在编译过程就能得到计算结果的表达式。
  2. 一个对象是不是常量表达式,由它的数据类型和初始值共同决定,必须是const类型、初始值也是一个常量,这个对象才是一个常量表达式。
  3. constexpr变量可以声明一个变量一定是一个常量,并且必须用常量表达式初始化。
  4. constexpr只能对字面值类型使用,算术类型、引用和指针都属于字面值类型。
  5. constexpr类型的指针一定是一个顶层const变量。

练习

练习2.32:下面的代码是否合法?如果非法,请设法修改正确。

int null = 0,*p = null;

答:
显而易见不合法,*p是指向int型变量的指针,所以应改为

int null=0,*p = &null;

不过如果是初始化一个空指针,可以像下面这样写:
int *p = nullptr;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值