【高质量C++/C总结4】C++常量总结-const

高质量C++/C编程指南(附录C :C++/C试题的答案与评分标准)   附录C :C++/C试题的答案与评分标准 一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10分)   请写出 BOOL  flag 与“零值”比较的 if 语句。(3分) 标准答案:     if ( flag )     if ( !flag ) 如下写法均属不良风格,不得分。     if (flag == TRUE)       if ( 阅读详情

说在开始:

我提炼了《C++ Primer》、《侯捷C++》、《高质量程序设计指南——C/C++语言》等资料中的重要部分,并总结成此博文。其中涉及到许多我个人对C++的理解。

作者:尹豆(憨豆酒),联系我yindou97@163.com,熟悉图形学,图像处理领域,本章代码: https://github.com/douysu/computer-graphics-notes

内容介绍

C++/C的常量分为两种,分别为字面常量和符号常量。

字面常量:程序中出现的各种进制的字符,数字,地址等等都是字符常量,这在不过多介绍。有一点需要注意,一段程序中可能存在相同的常量,这样就增加的内存的消耗,有的编译器是支持变量合并的,如果编译器支持最好打开,可以减少内存消耗。

符号常量:符号常量分为(1)宏(2)const定义的常量。 宏在程序编译前就进行了代码替换,说到底宏就是一种特殊的字面常量。这里着重介绍const修饰的常量。

如何定义常量

	const int WIDTH = 20;
	const int HEIGHT = 20;
        #define SKY_LENGTH = 10;

在《Google C++编程规范》中,严格规定C++/C中的常量应当全部大写,容易区分。

在C++程序中应尽量使用const修饰常量,在后面的博客中还会介绍const的一些其他用途,只要需要预防数据修改时都可以使用const,例如const修饰函数参数,const修饰成员函数等等。正如大家所说的“Use const whenever you need”。

const较#define的优势

const的变量相比#define宏具有很多优势。

(1)首先#define宏在程序中往往会造成不可预知的错误,因为宏只是进行字符替换,不会进行类型的安全检查,并且字符替换时可能会产生意料不到的逻辑错误。

(2)其次,#define宏在程序中是不可调试的,也就是无法使用debug中的中断进行调试,但是可以对const常量调试。

const常量的一些细节

(1)const类型常量内存分配情况

在C中,const定义的常量是不能修改的常量,因此会为其分配内存空间。在C++中,情况会有相应的改变,对于基本数据类型,如int,float。编译器会把其放到符号表中,因此不需要分配内存空间,而对于抽象数据类型和自定义的数据类型是需要分配内存空间的。

(2)const常量在运行时,可通过内存地址修改其值

如何理解这句话呢,看下面这段代码吧。

//Const_Changed.cpp
class Data
{
public:
	Data(int dIn):d_int(dIn) {};
	int d_int;
};

int main() {
	const int WIDTH = 20;
	int* p = (int *)&WIDTH;
	cout << WIDTH << endl;//20
	*p = 10;
	cout << WIDTH << endl;//20


	const Data data(20);
	Data* d = (Data*)&data;//获取指针
	cout << data.d_int << endl;//20
	d->d_int = 10;
	cout << data.d_int << endl;//10
	cin.get();
}

通过以上代码可以看出:

  • 对于基本数据类型常量,编译器会重新再内存中创建一份拷贝,当通过指针去修改其值时,修改的只是其拷贝,并非是原始数据。

  • 但是,对于自定义类的const对象,可以通过获取指针的方式修改d_int值,也就是迂回修改。如若想防止此种情况产生,很简单,只需要在d_int声明前面加上一个const即可。 如若那么做,还会引出一个新的问题,这个在下面会介绍。

也就是说const符号只是编译时进行检查,来帮助程序员无意中会修改它的代码,而在运行时无法防止恶意的修改的。C++并没有提供指针的安全检查,这也就是C++指针危险性的,在后面中的内存管理等等地方还会更加多涉及到指针,也就是说,一个好的C++/C程序员一定会严格要求对指针的操作。

类中的非静态常量

类的静态常量在最后一部分提到。在上面提到,如果不想通过指针修改d_int变量,可以在其前面加上一个const,这里的const int d_int就是类中的常量,这里有几点需要注意。

(1)非静态的const数据成员是属于每一个类对象的。

(2)不能再类中初始化非静态常量,只能在类的构造函数的初始化列表中进行。只能通过此种方式初始化。

//Const_Class.h
class Const_Class
{
public:
	Const_Class(int input) :c_int(input) {};
	const int c_int;
};

如若想初始化,只能使用枚举enum了。

实际编程中的应用

常量在项目中经常被使用,但是其值几乎不变,通常是一些常用的属性,例如在吃鸡中,地图的大小,一局游戏的时间等等。

在开始之前,有一点需要介绍,C++中const符号常量定义的默认连接类型为static,所以在头文件有无static都无所谓,但在C中不同。这里参考的为高质量程序设计一书。各种方法如下所列:

(1)直接在头文件中定义常量并初始化。如:

//ConstantDef.h
const int WIDTH = 12;

//main.cpp
#include <iostream>
#include "ConstantDef.h"
using namespace std;
int main()
{
	cout << WIDTH << endl;
	cin.get();
}

使用时只需要在相应编译单元include即可。

(2)在头文件中声明中添加关键字extern,在某个编译单元(cpp)中定义并初始化

在C++中声明和定义是完全两件不同的事情。C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译。为了将程序分为许多文件,则需要在文件中共享代码,例如一个文件的代码可能需要另一个文件中中定义的变量。

为了支持分离式编译,C++允许将声明和定义分离开来。变量的声明规定了变量的类型和名字,即使一个名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。定义则负责创建与名字关联的实体,定义还申请存储空间。

参考:extern关键字的作用http://www.cnblogs.com/broglie/p/5524932.html

//ConstantDef.h
extern const int WIDTH;//仅声明变量

//ConstantDef.cpp
#include "ConstantDef.h"
extern const int WIDTH=12;//声明并定义

//main.cpp
#include <iostream>
#include "ConstantDef.h"
using namespace std;
int main()
{
	cout << WIDTH << endl;
	cin.get();
}

其实无论在哪个编译单元中声明并定义都是可以的,我这里方便,就只在头文件对应的编译单元定义实现了。

(3)如果是整型变量直接使用enum进行初始化即可。

(4)定义一个公用类,其中包括static const数据成员并初始化,或者定义枚举类型。

//Constant.h
class Constant
{
public:
	static const int ALL_TIME;
	enum
	{
		TIME = 20
	};
};

//Constant.cpp
#include "Constant.h"
const int Constant::ALL_TIME=20;

//main.cpp
#include <iostream>
#include "Constant.h"
using namespace std;
int main()
{
	cout << Constant::ALL_TIME << endl;
	cin.get();
}

几种常用方法的优缺点

方法二、四

  • 优点:

(1)每一个单元访问的都是唯一的。怎么理解这句话呢?以方法一为例,在需要的地方include对应的头文件,这样相当于在每个编译单元上方又重新声明定义了一次常量,也就是说整个程序中存在多个同名的常量,只是在不同的编译单元罢了,而方法二和方法四在整个程序中只存在一个常量。

(2)修改初值后只会影响自己的头文件和编译单元。 这也很好理解,方法一和三都是重新再头部声明了,也就是include的头文件的编译单元都会重新编译。

  • 缺点:
    维护不方面。当需要修改值时或者变量的名字时,不仅要修改头文件而且还要修改编译单元,需要修改两次。

方法一、三

  • 优点

维护方便,只需要修改一处。

  • 缺点

(1)修改值时会影响到许多编译单元,需要重新编译。

(2)也就是上面所讲的情况,每一个编译单元中都会有拷贝的内容,浪费存储空间。

林锐-高质量c/c++编程指南 返回主页高质量C++/C编程指南文件状态[ ] 草稿文件[√] 正式文件[ ] 更改正式文件 文件标识: 当前版本: 1.0作 者: 林锐 博士完成日期: 2001年7月24日版 本 历 史版本/状态 作者 参与者 起止日期 备注V 0.9草稿文件 林锐 2001-7-1至2001-7-18 林锐起草V 1.0正式文件 林锐 2001-7-18至2001-7-24 朱洪海审查V 0.9,林锐修正草 阅读详情

相关推荐

RPG MV游戏数据修改指南:从JSON解析到脚本进阶

游戏数据修改是游戏开发与逆向工程中的常见实践,其核心原理在于解析和操作游戏资源文件。许多现代游戏引擎采用结构化数据格式(如JSON)存储游戏配置,这为外部修改提供了可能。通过理解文件结构、数据格式与游戏逻辑的关联,开发者或爱好者可以调整游戏平衡、修复问题或实现个性化定制,这不仅能深化对游戏设计机制的理解,也具备实际的技术学习价值。本文以基于Web技术栈的RPG Maker MV(RPG MV)引擎为例,其游戏数据多以明文JSON存储,结构清晰。文章将具体阐述如何安全地修改角色属性、物品效果、敌人数据及技能公

weixin_29001419的博客 403

C++编程之命名空间、const常量

1、C++命名空间 解决命名冲突,保证数据一致性 可以放变量、函数、结构体、类等 必须声明在全局的作用域下 命名空间可以嵌套命名空间 命名空间是开放的,随时可以给其中添加新成员 namespace B { int m_A = 100; } ... namespace B { int m_B = 200; } void test() { cout<<"B下的m_A...

Marble_ccp的博客 1万+

Containerd容器运行时的私有仓库镜像推送push和镜像拉取问题解决

向/etc/containerd/config.toml配置添加如下配置,然后重启containerd。向/etc/containerd/config.toml配置添加如下配置,然后重启containerd。通过crictl为k8s拉取镜像如下所示。可以通过ctr命令进行镜像推送。往私有仓库推送镜像如下。

Bulut0907 1万+

C/C++的const常量总结

“所谓常量,就是在代码运行过程中值恒定不变的标识符,该标识符的值可以是一个常数,也可以是字符串。”在C/C++中,通常使用define宏定义或者const来定义常量,比如:#define...

shandianfengfan的博客 1597

量化爬虫实战:手把手教你搞定同花顺问财的hexin-v参数(附JS逆向思路与Cookie Hook技巧)

本文详细解析了如何通过JS逆向技术获取同花顺问财平台的`hexin-v`参数,包括Cookie Hook技巧和完整解决方案架构。从环境搭建到参数定位,再到生成逻辑逆向,手把手教你突破数据获取限制,为量化交易提供可靠数据支持。

weixin_42557803的博客 398

安卓ai自动化脚本 Yyds.Auto实现 示例 纯ai图像识别自动点击脚本

纯ai识别实现自动化脚本

专注安卓前沿科技 4780

c语言const常量用法,C++ const常量在多文件编程中的3种用法

《C++多文件编程是什么》一节提到,多文件编程中代码的划分原则是:将变量、函数或者类的声明部分存放在 .h 文件,对应的实现部分放在 .cpp 文件中。值得一提得是,此规律适用于大部分场景,但本节要讲的 const 常量是一个例外。我们知道,用 const 修饰的变量必须在定义的同时进行初始化操作(除非用 extern 修饰,本节后续会讲解)。与此同时,C++ 中 const 关键字的功能有 2 ...

weixin_39719585的博客 1150

【乐企文件生成工程】关于乐企文件生成工程的详细介绍

发票文件生成方式有两种思路:1、根据已有的OFD模板,动态替换ofd模板内容;之后将ofd转pdf(局限:单行问题不大)详情可以在此处了解2、根据html模板动态占位:该工程就是这种方式 ,目前效果良好,可看下图。拿去即用的源码!无任何保留,当然也并不是所有票种都支持(时间有限、精力有限、已经连着转了,要冒烟了…)

九七的博客 2030

定义常量的时候,所有字母都要大写

<br />定义常量的时候,所有字母都要大写<br /> <br />定义常量的时候,所有字母都要大写<br /> <br /> <br />public static final String TIP = "定义常量的时候,所有字母都要大写";

LiuMang专栏 4371

【技能】伪真openclaw主动式智能体—告别‘巨婴’AI工具人:体验主动智能体的魅力

摘要: 传统AI常因被动执行、缺乏闭环而令人抓狂。Proactivity主动执行能力将AI从"指令跟随者"升级为"主动合伙人",具备预判需求、自动推进、断聊恢复、问题自解等能力。其核心原理在于建立AI专属工作体系(持久化内存、动态任务层、临时缓存层、归档复盘层),通过7步闭环(感知触发→状态恢复→边界校验→方案探索→动作决策→执行落地→状态留存)确保安全高效。

海兰 207

ESP32-CAM 赋能 AI 视觉巡检小车:自主避障与目标追踪实现全解析

本文基于 ESP32-CAM 实现了低成本 AI 视觉巡检小车的核心功能,硬件成本<100 元,兼顾自主避障与目标追踪。算法升级:移植 YOLOv5nano 量化模型(INT8),提升目标检测精度(如识别巡检场景中的 “异常物体”“人员”);无线拓展:通过 MQTT 协议将巡检图像、距离数据上传到阿里云 / 腾讯云,实现远程监控;多传感器融合:增加温湿度(DHT11)、红外测温(MLX90614)模块,扩展巡检维度;路径规划:结合 SLAM 算法,实现自主建图与路径巡检。

weixin_42300449的博客 367

高质量C/C++编程指南

本文档参考《高质量C++ C编程指南》及自己的心得编写,如有侵权,立刻删除!定义文件有三部分内容:(1)定义文件开头处的版权和版本声明;(2)对一些头文件的使用;(3)程序的实现体(包括数据和代码)假设定义文件的名称为header.cpp,定义文件的结构参见如下://版权和版本说明见2.1.1,此处省略#include "header.h" //引用头文件...//全局函数的实现体...//类成员函数的实现体...

weixin_72852519的博客 3533

RTCA DO-160G标准详解:航空电子设备的全面环境适应性测试指南

第二章的主要目的是提供标准中使用的术语和定义。了解这些术语对于准确理解标准的要求至关重要,特别是在技术实施过程中。RTCA DO-160G 涉及多个学科的知识,包括航空、电子、电磁学和机械工程,因此需要确保使用的术语在所有学科中具有一致的定义。为了确保测试人员和工程师在执行测试时对所有条件和要求的理解一致,RTCA DO-160G 标准中定义了大量术语。环境应力:指的是设备在操作过程中可能遇到的外部物理或化学条件,包括温度、湿度、振动等。电磁干扰(EMI)

qq_41854911的博客 5276

第五章 C++/C常量===高质量程序设计C++/C语言 林锐

符号常量:                 1.用#define定义的宏常量  进入编译阶段前就被替换成多代表的字面常量,所以本质是字面常量                  2.用const定义的常量                  C语言中,const定义的是不能让你个修改的量,会给它分配存储空间(外链接)                   C++中,基本数据类型的常量,

yao____yao的专栏 1116

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

《高质量C++/C编程指南》读书笔记之一

《高质量C++/C编程指南》------作者林锐博士 作者在前言中所讲的关于编程老手与编程高手以及结合自己的经历,给我们讲述了关于编程质量的重要性以及必须对于其质量的重视。 1.知错就改。 2.经常温故而知新。 3.坚持学习,天天向上。 从这里面抽取精华,对其加以整理,形成自己的笔记,在后面的学习过程中可以加以巩固。 ——————————————————————————————————

hgj125073的专栏 1024

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

高质量C++/C编程指南(五)常量

一、为什么需要常量? 二、const与#define的比较 三、常量定义规则 四、类中的常量

Exp.Joker 348

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Objective-C中const常量是外连接的

<br /><br />    前几天老师要求实现一个iphone上的“吃豆人”小游戏,给一下午加一晚上的时间。由于粟的设计很合理,且没有考虑太多、太复杂的情况(如 pacman 吃了 magic dot 后所有ghost的速度应该变慢),总体上没遇到什么太大的困难——只是在开发过程中曾遇到一个很诡异的错误:<br />    为了遵循DRY原则,我把公用常量(ghost的数量)定义放在了一个define.h文件中,让大家都去import该文件。<br />    当时我的常量定义是这样写的:<br /> 

ChengTian看过的风景 6667

【高质量C/C++】5.常量

高质量C/C++编程,常量的定义和使用规则,让你写出高质量代码

weixin_52811588的博客 725

林锐C语言--高质量C/C++编程(第五六章)

【规则 5-3-1】需要对外公开的常量放在头文件中,不需要对外公开的常量在定义文件的头部。为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。【规则 5-3-2】如果某一常量与其它常量密切相关,应在定义中包含这种关系,而不应给出一些孤立的值。例如。

千月星跡 931

C与C++中的const终极对比指南

本文对比分析了C和C++中const关键字的差异。C语言的const仅表示"只读变量",不能作为编译时常量;而C++的const具有更严格的语义,可作为编译时常量使用。主要差异体现在:指针/引用修饰、函数参数、类成员函数、链接性等方面。C++还扩展了constexpr、mutable、const_cast等特性。文章通过大量代码示例揭示了两者在全局变量、数组大小、函数重载等场景下的不同行为,并提供了最佳实践建议。掌握这些差异对编写跨语言程序和高质量代码至关重要。

弘羽 998

学习笔记之高质量C++/C编程指南

高质量C++/C编程指南 http://man.lupaworld.com/content/develop/c&c++/c/c.htm 高质量C++/C编程指南(附录 C :C++/C 试题的答案与评分标准) http://www.warting.com/program/201111/38402.html http://www.360doc.com/content/10...

weixin_34221112的博客 441

高质量C++/C编程指南

转载自:             高质量C++/C编程指南         文件状态 [  ] 草稿文件 [√] 正式文件 [  ] 更改正式文件 文件标识:   当前版本: 1.0 作    者: 林锐 博士 完成日期: 2001年7月24

qiantuo1234的专栏 1337

《高质量C++编程指南》第5章~常量--【优秀的编程思想】

目录 第5章 常量 5.1 为什么要使用常量 5.2 const 与 #define的比较 5.3 常量定义的规则 5.4 类中的变量 第5章 常量 C语言用#define来定义常量,称为宏常量 C++语言除了#define外还可以用const来定义常量 5.1 为什么要使用常量 (1)程序的可读性 (2)程序很多地方输入同样数字或者字符串,难保不发生错误 (3)...

王博(Kings)的博客 1804

【转贴】对《高质量程序设计指南--C++/C第二版》的探讨

《高质量程序设计指南——C++/C(第二版)》的读书心得             作者:fang_rk    写这篇文章是出于一个偶尔的原因:读计算机系的女友即将升入研究生三年级,她说想要看看这本书。她是个C/C++门外汉,看此书只是为了应付找工作时可能被问到的题目。我觉得有必要指出这本书中的错误,但显然她没有心思坐下来与我讨论书中的大部分内容,况且我的学历只有本科,人微言轻啊(学历真是太重要了,

阿宝 2518
上一篇: 【Shader特效10】体积雾特效的使用
下一篇: 【高质量C++/C总结5】const常用用法-提高程序的健壮性
尹豆(douysu)
博客等级 码龄9年 151粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值