C++基础之const

2023-11-12

C++中什么是常量

常量:在程序运行期间不能发生改变的变量,常量不限制类型,但是在定义之后值不可修改

c++中定义常量有两种方法

  1. 使用宏定义#define预处理器(来自C语言)
    #define DEF_WINDOW_WIDTH 720
  2. 使用const关键字
    const int DEF_WINDOW_WIDTH 720;

const的4种用法

  1. 修饰变量,将变量定义成常量
  2. 修饰引用,一般用于对函数的形参(常引用),避免了函数内对值的更改
  3. 修饰函数,表示修饰函数的返回值、成员函数后面加const说明函数内不会修改成员变量
  4. 修饰指针,分为两种(指针自身是常量和指针指向了一个常量)
const修饰变量
#include<iostream>
 class Test_Class {
private:
	const int a = 9;
	int       b =10;
	const int c;//1.没有赋值,构造函数需要对其进行初始化
	int       d;
public:
	Test_Class():c(0){//构造函数初始化常量c的值
		std::cout << __FUNCTION__ << " b=" << b << " a="<<a << std::endl;
		b++;
		//a++;//2.错误 常量无法修改
	};
	int GetValueA(){
		std::cout << __FUNCTION__ << std::endl;
		return a;
	};
	int GetValueBConst() const{
		std::cout << __FUNCTION__ << std::endl;
		return b;
	}; 
};
int main()
{
	Test_Class t_class;//普通对象,可以调用全部成员函数
	const Test_Class c_t_class;//常量对象
	std::cout << t_class.GetValueA() << std::endl;
	//std::cout << c_t_class.GetValueA() << std::endl;//3.错误,常量对象,不可以调用非常成员函数
	std::cout << c_t_class.GetValueBConst() << std::endl;
	return 0;
}
const修饰引用

引用只是个别名

  • 常量引用,无法进行修改
void Func(){
	char        ch = 'a';
	const char& c_ch = ch;
	char&       d_ch = ch;
	std::cout << ch << std::endl;//a
	std::cout << c_ch << std::endl;//a
	ch = 's';
	std::cout << ch << std::endl;//s
	std::cout << c_ch << std::endl;//s
	//c_ch = 't';错误
	d_ch = 't';
	std::cout << ch << std::endl;   //t
	std::cout << c_ch << std::endl; //t
}
  • const修饰函数的引用形参,与前一个类似,允许输入参数为const修饰的值(常量引用或常量)或右值
void func(int& a){
    std::cout << a << std::endl;
}
void func_const(const int& a){
    std::cout << a << std::endl;
    //a++;//错误,const 不允许修改形参
}
func(11);//错误
func_const(11);//正确
const修饰函数
  • 函数声明末尾加const,说明该成员函数内不能修改成员变量。
#include<iostream>
class Test_Class {
private:
	 int a = 9;
public:
	Test_Class() {
		std::cout << __FUNCTION__ << " a=" << a << std::endl;
	};
	int GetValueA(){
		std::cout << __FUNCTION__ << std::endl;
		a++;
		return a;
	};
	int GetValueBConst() const{
		std::cout << __FUNCTION__ << std::endl;
		//a++;//错误,常量函数不可修改成员变量
		return a;
	};
};
int main()
{
	Test_Class       t_class;
	std::cout << t_class.GetValueA() << std::endl;
	std::cout << t_class.GetValueBConst() << std::endl;
}
  • 修饰函数的返回值,防止函数返回值被修改(归根其实是const修饰指针or引用)
#include<iostream>
const char* Const_TestFun(){
	char* array = new char[4];
	array[0]    = 'a';
	array[1]    = 'b';
	array[2]    = 'c';
	array[3]    = '\0';
	return array;
}

char* TestFun(){
	char* array = new char[4];
	array[0]    = 'a';
	array[1]    = 'b';
	array[2]    = 'c';
	array[3]    = '\0';
	return array;
}
int main(){
	const char* s = Const_TestFun();
	char*       p = TestFun();
	//*s  = 'n';错误,不能修改返回值
	cout << s << endl;
	*p = 'n';
	cout << p << endl;
}
const修饰指针
  • 指针常量:就是指针本身是常量,进一步解释:指针的值(内存地址)是常量,不能改变,但内存地址对应的元素是可以通过指针改变的。(本质上是一个指针类型的常量)
int * const p
  • 常量指针:就是指向常量的指针,进一步解释:定义时不需要对它进行初始化,指针指向了常量,它指向的值不能发生改变,但可以通过原有的声明来修改。(本质上是一个指针)
int const * p;
const int *;

仔细阅读以下例子

#include<iostream>
int main(){
	int        a = 10;
	int        b = 20;
	int        e = 40;
	
	const int* d_ptr = &b; //常量指针
	cout << "d_ptr:" << d_ptr << " " << *d_ptr << " " << b << endl;
	//*d_ptr=20; 不能通过常量指针来修改变量的值
	b = 30; //可以通过修改常量指针指向的对象值 来修改常量指针的值
	d_ptr = &e; //同时常量指针可以指向任意其他地址
	cout << "after d_ptr:" << d_ptr << " " << *d_ptr << " " << b << endl;

	int* const ptr_c = &a; //指针常量
	cout << "ptr_c:" << ptr_c << " " << *ptr_c << " " << a << endl;
	//ptr_c=&e; 对于指针常量 不能修改其指向的地址
	*ptr_c = 99; //但是可以通过指针来修改变量的值
	cout << "after ptr_c:" << ptr_c << " " << *ptr_c << " " << a << endl;
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++基础之const 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • sheel脚本

    sheel脚本 sheel脚本 sheel脚本 sheel脚本的工作方式有两种 交互式和批处理 交互式 用户输入一条就立即执行 批处理 由用户实现编写好一个完整的sheel脚本 sheel会一次执行脚本中诸多命令 脚本中不仅会用到一般的li
  • 测试用例设计方法之等效类,边界值

    概念 等价类划分是一种黑盒测试方法 把无限的测试变成有限的测试 把所有可能的输入数据 即程序的输入域划分成若干等价类 然后从每一个等价类中选取少数具有代表性的数据作为测试用例 依据需求将输入 特殊情况下会考虑输出 划分为若干个等价类 从等价
  • 红帽linux认证有哪些方向

    红帽Linux认证有以下几个方向 RHCSA 红帽认证系统管理员 该认证是红帽认证中的初级认证 主要考察考生对Linux系统管理的掌握程度 包括系统安装 文件系统管理 用户和组管理 网络管理等 RHCE 红帽认证工程师 该认证是红帽认证中的
  • 高德地图定位

    高德地图开放平台 获取key 获取key值后 将其在index html中引入 然后来到App vue下 即根组件下 一进项目就可以获取定位 所以在钩子函数created 中实现定位功能
  • OpenAi 嵌入

    什么是嵌入 OpenAI 的文本嵌入衡量文本字符串的相关性 嵌入通常用于 搜索 结果按与查询字符串的相关性排序 聚类 其中文本字符串按相似性分组 推荐 推荐具有相关文本字符串的项目 异常检测 识别出相关性很小的异常值 多样性测量 分析相似性
  • 2018-2019-2 网络对抗技术 20165322 Exp2 后门原理与实践

    2018 2019 2 网络对抗技术 20165322 Exp2 后门原理与实践 目录 实验准备 后门概念 常用后门工具 实验内容与步骤 使用netcat获取主机操作Shell cron启动 使用socat获取主机操作Shell 任务计划启
  • 阿里带火的中台到底是什么?白话中台战略

    作者 王健 ThoughtWorks首席咨询师 十多年国内外大型企业软件设计开发 团队组织转型经验 一直保持着对技术的热爱 热衷于技术分享 目前专注在企业平台化转型 中台战略规划 微服务架构与实施 大型遗留系统服务化改造 敏捷精益转型 以及
  • IOS工程添加目录

    问题 ios工程和资源工程是分开的 需要将工程外的一个文件夹导入到ios工程中 以前是直接拷贝一份放在frameworks runtime src proj ios mac中 这样操作的缺点就是 修改了公共的资源后 还需要再修改ios工程下
  • 微信小程序的computed的使用

    1 官方参考地址 computed 微信开放文档 qq com 2 自定义组件component和behaviors component参考地址 自定义组件 微信开放文档 qq com behaviors参考地址 behaviors 微信开
  • Solidity中引入的SPDX是什么

    Solidity中引入的SPDX是什么 起因 Solidity 0 6 8 要求引入 SPDX 许可证 否则会出现警告 Warning SPDX license identifier not provided in source file
  • MyBatis万能插入语句

    MyBatis万能插入语句 前言 最近需要做一个动态新增数据的接口 表名 列名 数据都是动态传进来的 需要一个接口就可以把所有表数据新增成功 第一种方式 首先看Mapper dao层 接口 插入数据 param tableName 表名 p
  • linux 解压所有以zip结尾的文件_Linux的压缩/解压缩文件处理 zip & unzip

    Linux的压缩 解压缩命令详解及实例 压缩服务器上当前目录的内容为xxx zip文件 zip r xxx zip 解压zip文件到当前目录 unzip filename zip 另 有些服务器没有安装zip包执行不了zip命令 但基本上都
  • C++中vector的使用

    向量std vector是一种对象实体 能够容纳许多各种类型相同的元素 包括用户自定义的类 因此又被称为序列容器 与string相同 vector同属于STL Standard Template Library 中的一种自定义的数据类型 可
  • VTK“静态编译”与“动态编译”的区别:

    静态编译 与 动态编译 的区别 静态编译就是在编译的时候把所有的模块都编译进可执行文件 exe 里去 当启动这个可执行文件时所有的模块都已加载进来 动态编译则是编译的时候需要的模块都没有编译进去 一般情况下可以把这些模块都编译成动态链接库D
  • exec族函数配合fork使用(linux系统编程)

    execl 函数配合fork 函数 在执行A程序的过程中去执行B程序 代码B 用来改文件中的数值 include
  • Google签名证书和base64密钥

    keystore重点说明 1 打包aab时 需要自己创建当前应用的keystore 这个是开发者的应用的keystore 以后上传这个应用都使用这个keystore 2 Google的签名证书 作用是当应用上传Google商店后 Googl
  • 运行时链接

    基本概念 运行时链接 是在程序运行时 而非编译时或加载时 将程序代码与其依赖的库代码进行链接的过程 动态链接在程序启动时或实际运行过程中通过API函数完成 这种方式的主要优点是它允许程序在运行时加载和卸载不同的库模块 从而实现更高的模块化和
  • 敏捷开发“松结对编程”实践之三:共同估算篇(大型研发团队,学习型团队,139团队,师徒制度,敏捷设计,估算扑克,扑克牌估算)

    转载自 http blog csdn net cheny com article details 6587277 本文是 松结对编程 系列的第三篇 之一 之二 之三 之四 之五 之六 之七 之八 此系列之九及之后文章请见栏目总目录 估算是经
  • 使用FFMPEG将WebM转为MP4或MKV

    PS5 自带的录像功能导出的格式是WebM 同时视频是HDR默认60帧 我们有时需要转成其他格式保存 下面两个命令可以将其转成mkv或者mp4格式 ffmpeg i test webm vf zscale t linear npl 100
  • C++基础之const

    C 中什么是常量 常量 在程序运行期间不能发生改变的变量 常量不限制类型 但是在定义之后值不可修改 c 中定义常量有两种方法 使用宏定义 define预处理器 来自C语言 define DEF WINDOW WIDTH 720 使用cons