0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++中的const关键字介绍

jf_78858299 来源:QStack 作者: 月下西楼 2023-03-17 14:01 次阅读

前言

前一篇文章我们主要介绍了C++中的复合类型引用和指针,这篇文章我们将会主要介绍C++中const关键字。有时候我们想定义一个值不能被改变的变量,例如我们想使用一个变量存储buffer的大小,如果我们不希望这个值被改变,那么我们就可以使用const关键字。

const int bufSize = 512;

现在已经定义了一个const变量bufSize,如果想对const变量赋值就会报错

bufSize = 256 //会报错

const初始化

因为在我们创建一个const对象后就没有办法改变const对象的值,所以其必须被初始化。

const int j = get_size(); //可以运行时初始化
const int i = 42//可以在编译时初始化
const int k; //错误,k没有被初始化

正如之前我们多次提到的,一个对象的类型决定来其所有支持的操作,一个const类型可以使用绝大多数并不是全部非const类型的操作,唯一的限制就是我们使用的操作不能改变const对象的值,例如我们可以在算术表达式中将const类型的变量当作非const类型的变量使用,因为其没有改变const变量的值。

当一个const对象在编译期间就被一个常量初始化了,例如我们上述例子提到的bufSize在编译期间就被初始化为512,在编译期间编译器就会将所有使用到bufSize的地方替换为512。为了替换变量的值,编译器必须要知道变量的初始化结果,为了知道初始化结果,所有需要使用该变量的文件都需要定义该变量,为了支持这种用法,同时避免定义多个相同的变量,const变量对于文件来说是本地的,当我们定义在不同的文件中定义多个同名的const变量,它们表现起来就像我们在不同的文件定义了不同的变量。

但是有时候我们希望在不同的文件中共享同一个const变量,但是其初始化并不是一个常量,我们并不希望编译器为每一个文件生成单独的变量,而是希望想非const变量一样,我们希望在一个文件定义,然后在另一个文件声明且使用该const变量,这时候就要使用extern关键字

//file1.cc定义切初始化了一个const变量
extern const int bufSize = fcn();

//file1.h
extern const int bufSize;

指向常量的引用

正如其他的对象,我们也可以将一个引用绑定到一个const类型的对象,为此我们可以使用一个引用指向,不同于一般的引用,一个指向常量的引用无法改变该引用指向的对象,这也很好理解,因为该对象是一个常量,而常量一旦定义就无法更改。

const int ci = 1024;
const int &r1 = ci; //正确,引用和引用指向的对象都是常量
r1 = 42; //错误,r1指向的是一个常量,无法改变一个常量的值
int &r2 = ci; //错误,无法让一个非常量的引用指向一个常量

❝一些开发这习惯于将指向常量的引用简称为常量引用,这个简称看上去说的通,但是你需要记住这就是个简称,从技术的角度来说是没有常量引用的,因为一个引用不是一个对象,所以我们无法让一个引用本身是一个常量。

指向常量的引用未必指向一个常量

从之前的例子中我们可以看到指向一个常量的引用必须是一个常量引用,否则会报错,但是一个指向常量的引用不一定指向一个常量,只是不同通过该引用来改变该对象的值,这么说可能有点绕,可以用以下例子说明

int i = 42;
int &r1 = i; //r1是指向i的引用
const int &r2 = i; //r2是指向i的常量引用,但是不能通过r2改变i的值
r1 = 0; //r1是非常量引用,可以通过r1改变i的值
r2 = 0; //r2是常量引用,无法通过r2改变i的值

指针与常量

与引用相同,指针可以指向常量也可以指向非常量,同样指向常量的指针无法通过该指针来改变所指向的常量的值。

const double pi = 3.14; \\\\pi是一个常量,其值不可以改变
double *ptr = π //错误 ptr不是一个指向常量的指针,所以无法指向pi
const double *cptr = π //正确,cptr是指向常量的指针
*cptr = 42; //错误,cptr指向的是常量,其值无法改变

还是与引用相同,我们也可以让一个指向常量的指针指向一个非常量,但是不可以通过该指针改变该对象的值

double dval = 3.14;
cptr = &dval; //正确,但是无法通过cptr改变dval的值

常量指针

与引用不同,指针本身是一个对象,所以其本身可以是常量,常量指针与其他的常量性质是相同的,常量指针必须初始化,且一旦初始化该指针持有的地址也将不会改变,那么该如何声明一个指针呢,那就是在*后加上const,例子如下

int errNumb = 0;
int *const curErr = &errNumb; //curErr是一个常量指针,将会一直指向errNumb
const double pi = 3.1425926;
const double *const pip = π //pip是一个常量指针且指向一个常量

常量表达式

常量表达式是指其返回值在编译阶段就能计算出来且不会改变的表达式,一个对象是否是常量表达式取决于其类型和初始化结果,例子如下

const int max_files = 20; //是
const int limit = max_files; //是
int staff_size = 27; //不是,因为其类型不是const
const int sz = get_size(); //不是,因为get_size()需要在运行时才能计算出来

constexpr

在一个大型的系统中有时候我们很难去确定初始化的结果是否是常量表达式,也许我们定义来一个常量并且用一个我们以为的常量表达式去初始化,但是一些场景下我们需要一个常量表达式但是最后返回不是一个常量表达式,那么一个对象在定义和使用的情况并不一致。在新标准下为了解决这个问题,提供了constexpr关键字,如果一个变量被constexpr修饰,那么编译器将会检查该变量是否是一个常量表达式。

constexpr int mf = 20; //20是常量表达式
constexpr int limit = mf + 1; //mf + 1是常量表达式
constexpr int sz = size(); //正确,如果size constexpr函数,这个之后文章会介绍

指针与constexpr

需要注意的是如果我们定义一个指针在constexpr表达式中,那么constexpr是作用于指针,而不是指针指向的值。

const int *p = nullptr; //p是一个指向常量的指针
constexpr int *q = nullptr; //q是一个常量指针
constexpr const int *cptr = nullptr; //cptr是一个常量指针,且指向一个常量
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • buffer
    +关注

    关注

    2

    文章

    120

    浏览量

    30015
  • C++
    C++
    +关注

    关注

    22

    文章

    2104

    浏览量

    73482
  • CONST
    +关注

    关注

    0

    文章

    43

    浏览量

    8148
收藏 人收藏

    评论

    相关推荐

    C语言关键字const的几种用法

    本期来讲解一个C语言的关键字——const
    发表于 06-21 11:05 1560次阅读
    <b class='flag-5'>C</b>语言<b class='flag-5'>关键字</b><b class='flag-5'>const</b>的几种用法

    C++中常用关键字详解(2)

    C++,volatile是一个关键字,用于修饰变量,告诉编译器该变量的值可能在程序流程之外被意外修改,因此编译器不应该对该变量进行优化(如缓存变量值或重排指令顺序)。
    发表于 08-08 16:15 309次阅读

    DSP编程技巧之17---非常“关键”的关键字

      使用cregister关键字,当我们定义的该类型的对象与C28x的标准的控制寄存器匹配时,编译器会自动产生相关的代码去控制对应的寄存器,使得我们可以在高级编程语言C/C++
    发表于 08-20 11:38

    C++笔记010:C++C的扩展——register关键字增强

    的地址在C语言里面是会出错的。同样的代码我们放到C++编译环境下,发现编译是通过的!在C++依然支持register关键字
    发表于 08-11 12:34

    嵌入式软件编程关键字的用法和原理

    ,但是某些关键字,例如const、static、extern和volatile等,在不同的场合具有不同的含义,而且某些用法晦涩难懂,为此本文详细介绍这些关键字的用法及其背后的原理。
    发表于 06-20 07:37

    关键字static的作用是什么

    嵌入式面经1.关键字static的作用是什么2.关键字const是什么含意?3.const和宏定义的区别4.关键字volatile有什么含意
    发表于 11-09 07:23

    嵌入式程序员常见的const、static、volatile关键字

    嵌入式程序员const、static、volatile三个关键字的朴素认识摘要:在C语言程序编写const、static
    发表于 12-21 06:08

    C++语言基础讲解视频标识符与关键字

    C++语言基础讲解视频标识符与关键字,喜欢的朋友可以下载来学习。
    发表于 01-14 15:31 7次下载

    C++Cconst关键字有何差别?

    C++Cconst关键字有何差别?
    的头像 发表于 02-03 14:51 1784次阅读

    C++const和引用的讨论

    今天给大家分享一下这段时间学习c++的总结学习:c++里面的const关键字和引用。
    的头像 发表于 12-24 15:35 815次阅读

    C++mutable关键字详解与实战

    mutable关键字详解与实战 在C++mutable关键字是为了突破const关键字的限制,
    的头像 发表于 09-10 09:23 5525次阅读

    浅谈C++的mutable关键字

    C++11推出了一种特殊的关键字:mutable用于修饰类变量。它的作用是标注该变量一定会被修改,因此也就不是const类型。目的是为了使这些成员变量在被
    的头像 发表于 04-15 11:13 3756次阅读

    C语言|const关键字介绍

    最近看别人的项目, 发现const使用比较多, 通过使用const来保护变量, 这篇推文就来简单回顾一下相关知识!
    的头像 发表于 05-25 15:11 515次阅读

    const关键字应用总结

    C++const关键字的用法非常灵活,而使用const将大大改善程序的健壮性
    的头像 发表于 05-26 09:06 545次阅读

    浅析C语言中的regiseter关键字

    C语言中重要的关键字有很多,static const extern我们之前都讲过,还有一个在面试中出现的频率也比较高:register。
    的头像 发表于 08-25 17:10 1083次阅读
    浅析<b class='flag-5'>C</b>语言中的regiseter<b class='flag-5'>关键字</b>