【C++】 12_经典问题解析 一
关于 const 的疑问
const 什么时候为只读变量?什么时候为常量?
const 常量的判别标准
- 只有用字面量初始化的 const 常量才会进入符号表
- 使用其它变量初始化的 const 常量仍然只是制度变量
- 被 volatile 修饰的 const 常量不会进入符号表
在编译期间不能直接确定初始值的 const 标识符,都被作为只读变量处理。
const 引用的类型与初始化变量的类型
- 相同: 初始化变量为只读变量
- 不同: 生成一个新的只读变量
编程实验: const 典型问题分析
#include <stdio.h>/*** 使用常量初始化 const 引用,得到只读变量,进入符号表*/
void code_1()
{const int x = 1;const int& rx = x; // rx 只读变量int& nrx = const_cast<int&>(rx);nrx = 5;printf("x = %d\n", x);printf("rx = %d\n", rx);printf("nrx = %d\n", nrx);printf("&x = %p\n", &x);printf("&rx = %p\n", &rx);printf("&nrx = %p\n", &nrx);
}/*** 被 volatile 修饰的 const 标识符仍为只读变量,不会进入符号表*/
void code_2()
{volatile const int y = 2; // y为只读变量int* p = const_cast<int*>(&y);*p = 6;printf("y = %d\n", y);printf("p = %p\n", p);
}/*** 使用变量初始化的 const 标识符仍为只读变量,不会进入符号表*/
void code_3()
{int y = 0;const int z = y; // z 为只读变量int*p = const_cast<int*>(&z);*p = 7;printf("z = %d\n", z);printf("p = %p\n", p);
}/*** const 引用的类型与初始化变量类型不同那个,得到一个新的只读变量*/
void code_4()
{char c = 'c';char& rc = c;const int& trc = c; // trc 为只读变量rc = 'a';printf("c = %c\n", c);printf("rc = %c\n", rc);printf("trc = %c\n", trc);
}int main()
{code_1();printf("--------\n");code_2();printf("--------\n");code_3();printf("--------\n");code_4();return 0;
}
输出:
x = 1
rx = 5
nrx = 5
&x = 0xbfaf2cac
&rx = 0xbfaf2cac
&nrx = 0xbfaf2cac
--------
y = 6
p = 0xbfaf2cac
--------
z = 7
p = 0xbfaf2ca8
--------
c = a
rc = a
trc = c
关于引用的疑问
引用与指针有什么关系? 如何理解”引用的本质就是指针常量“?
指针是一个变量
- 值为一个内存地址
- 通过指针可以访问对应内存中的值
- 指针可以被 const 修饰成为常量或者只读变量
引用只是一个变量的新名字
- 对引用的操作(赋值,取地址等)都会传递到代表的变量上
- const 引用使其代表的变量具有只读属性
- 引用必须在定义时初始化,之后无法代表其它变量
从使用 C++ 语言的角度来看
- 引用与指针没有任何的关系
- 引用是变量的新名字,操作引用就是操作对应的变量
从 C++ 编译器的角度来看
- 为了支持新概念 ”引用“ ,必须有一个有效的解决方案
- 在编译器内部,使用指针常量来实现 ”引用“
- 因此 ”引用“ 在定义时必须初始化
在工程项目开发中
- 当进行 C++ 编辑时,直接站在使用的角度看待引用,与指针毫无关系,引用就是变量的别名
- 当对 C++ 代码进行调试分析时,一些特殊情况,可以考虑站在 C++ 编译器的角度看待引用
下面的代码有问题吗?
int a = 1;
int b = 2;
int* pc = new int(3);
int& array[] = {a, b, c};
编程实验: 引用典型问题分析
test_1.cpp
#include <stdio.h>int a = 1; // 全局数据区struct SV
{int& x;int& y;int& z;
};int main()
{int b = 2; // 栈int* pc = new int(3); // 堆SV sv = {a, b, *pc};printf("&sv.x = %p\n", &sv.x);printf("&sv.y = %p\n", &sv.y);printf("&sv.z = %p\n", &sv.z);delete pc;return 0;
}
输出:
&sv.x = 0x804a020
&sv.y = 0xbf91ef4c
&sv.z = 0x873d008
test_2.cpp
#include <stdio.h>int a = 1; // 全局数据区int main()
{int b = 2; // 栈int* pc = new int(3); // 堆int& array[] = {a, b, *pc};delete pc;return 0;
}
输出:
In function ‘int main()’:
error: declaration of ‘array’ as array of references
C++ 中为什么不支持引用数组呢?
C 数组是内存中的一块连续的存储空间,每个元素在内存顺序相邻存放,C++需要遵守并支持。当数组中的每个元素为引用即引用数组,破坏了这一特性。
小结
- 指针是一个变量
- 引用是一个变量的名字
- const 引用能够生成的新只读变量
- 在编译器内部使用指针常量实现 ”引用“
- 编译时不能直接确定初始值的 const 标识符都是只读变量
以上内容参考狄泰软件学院系列课程,请大家保护原创!
【C++】 12_经典问题解析 一相关推荐
- 关于Visual C#.NET数据库开发经典案例解析(附光盘两张)(珍藏版)—的读后感...
关于Visual C#.NET数据库开发经典案例解析(附光盘两张)(珍藏版)- 评论 读后感:里面的内容很经典,很实用 读后感:给初学者是好,但是是比较旧的了!VS2003 C/S的 读后感:< ...
- C语言计算日期间隔天数的经典算法解析
C语言计算日期间隔天数的经典算法解析 网上看到一个计算日期间隔的方法,很高深,很巧妙.代码如下: #include <stdio.h> #include <stdlib.h> ...
- 深度学习经典网络解析图像分类篇(二):AlexNet
深度学习经典网络解析图像分类篇(二):AlexNet 1.背景介绍 2.ImageNet 3.AlexNet 3.1AlexNet简介 3.2AlexNet网络架构 3.2.1第一层(CONV1) 3 ...
- 计算机算法讲解的ppt,智能计算几种经典算法解析.ppt
<智能计算几种经典算法解析.ppt>由会员分享,可在线阅读,更多相关<智能计算几种经典算法解析.ppt(20页珍藏版)>请在装配图网上搜索. 1.智能计算几种经典算法解析,制作 ...
- [算法系列] 深入递归本质+经典例题解析——如何逐步生成, 以此类推,步步为营
[算法系列] 深入递归本质+经典例题解析--如何逐步生成, 以此类推,步步为营 本文是递归系列的第三篇, 第一篇介绍了递归的形式以及递归设计方法(迭代改递归),;第二篇以递归为引子, 详细介绍了快排和 ...
- 计算机网络知识副标题,计算机统考常见题解答及经典题型解析.doc
计算机统考常见题解答及经典题型解析 计算机统考常见问题解答 1.哪些学生需要参加统考? 答:教育部批准的试点高校和中央电大"人才培养模式改革和开放教育试点"项目中自2004年3月1 ...
- Java基础2019最新Java面试经典题解析
Java基础2019最新Java面试经典题解析 1简述JVM.JRE.JDK的区别 JVM:java虚拟机 ,加载.class并运行.class JRE:java运行环境除了包含JVM以外还包含了运行 ...
- 阿里架构师强烈推荐《数据结构与算法经典问题解析》(PDF文档)
前言: 小编整理了一份数据结构与算法经典问题解析核心知识点.覆盖递归和回溯.链表.栈.队列.树.优先队列和堆.队列.优先队列和堆.并查集ADT.排序.选择算法(中位数).散列.算法设计技术.分治算法. ...
- 硬核 阿里P8终于把(数据结构与算法经典问题解析)讲全了
随着科学技术的发展,人工智能已经逐渐渗透到各个行业,这是一个相当有前景的专业领域. 其中,算法工程师这一职位更是非常火爆,在急缺大量人才的同时,也吸引了众多求职者,那么,初学者该如何学好算法呢? 算法 ...
最新文章
- MySQL远程用户授权
- logstash-input-jdbc 同步mysql数据到es
- 程序员抱怨:父母没文化没见识,当初努力学习远离看来是正确的
- python 3.8.0安卓_Python 3.8.0 正式版发布,新特性初体验
- Linux查看占用mem的进程脚本
- 仿美团酒店预订的html模板,jQuery手机端仿美团酒店预订日期选择插件
- Installing third-party firmware on x3-55 letv (by quqi99)
- Juce Programming Tutorial by haydxn 教程分享
- RaspberrIPCam – Full HD IP Camera based on Raspberry Pi
- 魔方基础公式--三阶四阶
- 应用于大数据分析的工作流调度系统
- 论文图片格式要求具体有哪些?
- 【TcaplusDB知识库】TcaplusDB进程启动介绍
- Android fstab学习
- 英语口语练习四十七之幸福满满的词语
- 基于51单片机的节日彩灯
- 免认证的 php短信接口代码
- python 提取视频中的音频 | Python工具类
- SQL server用户
- 统计字符串中不同字符个数
热门文章
- microsoft visual c++ 编译c语言,Microsoft Visual C++ 程序的部署方法
- ubuntu mysql双主热备配置_MySql双主热备配置
- java jtable导出txt_如何将jtable中的文本数据保存到文件中
- 一道二叉树的题目--后序遍历+中序遍历确定二叉树
- 新员工入职自动加入所在部门的邮件组。
- Java(19)JDBC
- Atitit.解决org.hibernate.DuplicateMappingException: Duplicate class/entity mapping
- 浅析继承关系中的方法调用
- 10个经典的哲学小故事
- SpringBoot报错couldn‘t check if tables are already present using metadata: