关于 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_经典问题解析 一相关推荐

  1. 关于Visual C#.NET数据库开发经典案例解析(附光盘两张)(珍藏版)—的读后感...

    关于Visual C#.NET数据库开发经典案例解析(附光盘两张)(珍藏版)- 评论 读后感:里面的内容很经典,很实用 读后感:给初学者是好,但是是比较旧的了!VS2003 C/S的 读后感:< ...

  2. C语言计算日期间隔天数的经典算法解析

    C语言计算日期间隔天数的经典算法解析 网上看到一个计算日期间隔的方法,很高深,很巧妙.代码如下: #include <stdio.h> #include <stdlib.h> ...

  3. 深度学习经典网络解析图像分类篇(二):AlexNet

    深度学习经典网络解析图像分类篇(二):AlexNet 1.背景介绍 2.ImageNet 3.AlexNet 3.1AlexNet简介 3.2AlexNet网络架构 3.2.1第一层(CONV1) 3 ...

  4. 计算机算法讲解的ppt,智能计算几种经典算法解析.ppt

    <智能计算几种经典算法解析.ppt>由会员分享,可在线阅读,更多相关<智能计算几种经典算法解析.ppt(20页珍藏版)>请在装配图网上搜索. 1.智能计算几种经典算法解析,制作 ...

  5. [算法系列] 深入递归本质+经典例题解析——如何逐步生成, 以此类推,步步为营

    [算法系列] 深入递归本质+经典例题解析--如何逐步生成, 以此类推,步步为营 本文是递归系列的第三篇, 第一篇介绍了递归的形式以及递归设计方法(迭代改递归),;第二篇以递归为引子, 详细介绍了快排和 ...

  6. 计算机网络知识副标题,计算机统考常见题解答及经典题型解析.doc

    计算机统考常见题解答及经典题型解析 计算机统考常见问题解答 1.哪些学生需要参加统考? 答:教育部批准的试点高校和中央电大"人才培养模式改革和开放教育试点"项目中自2004年3月1 ...

  7. Java基础2019最新Java面试经典题解析

    Java基础2019最新Java面试经典题解析 1简述JVM.JRE.JDK的区别 JVM:java虚拟机 ,加载.class并运行.class JRE:java运行环境除了包含JVM以外还包含了运行 ...

  8. 阿里架构师强烈推荐《数据结构与算法经典问题解析》(PDF文档)

    前言: 小编整理了一份数据结构与算法经典问题解析核心知识点.覆盖递归和回溯.链表.栈.队列.树.优先队列和堆.队列.优先队列和堆.并查集ADT.排序.选择算法(中位数).散列.算法设计技术.分治算法. ...

  9. 硬核 阿里P8终于把(数据结构与算法经典问题解析)讲全了

    随着科学技术的发展,人工智能已经逐渐渗透到各个行业,这是一个相当有前景的专业领域. 其中,算法工程师这一职位更是非常火爆,在急缺大量人才的同时,也吸引了众多求职者,那么,初学者该如何学好算法呢? 算法 ...

最新文章

  1. MySQL远程用户授权
  2. logstash-input-jdbc 同步mysql数据到es
  3. 程序员抱怨:父母没文化没见识,当初努力学习远离看来是正确的
  4. python 3.8.0安卓_Python 3.8.0 正式版发布,新特性初体验
  5. Linux查看占用mem的进程脚本
  6. 仿美团酒店预订的html模板,jQuery手机端仿美团酒店预订日期选择插件
  7. Installing third-party firmware on x3-55 letv (by quqi99)
  8. Juce Programming Tutorial by haydxn 教程分享
  9. RaspberrIPCam – Full HD IP Camera based on Raspberry Pi
  10. 魔方基础公式--三阶四阶
  11. 应用于大数据分析的工作流调度系统
  12. 论文图片格式要求具体有哪些?
  13. 【TcaplusDB知识库】TcaplusDB进程启动介绍
  14. Android fstab学习
  15. 英语口语练习四十七之幸福满满的词语
  16. 基于51单片机的节日彩灯
  17. 免认证的 php短信接口代码
  18. python 提取视频中的音频 | Python工具类
  19. SQL server用户
  20. 统计字符串中不同字符个数

热门文章

  1. microsoft visual c++ 编译c语言,Microsoft Visual C++ 程序的部署方法
  2. ubuntu mysql双主热备配置_MySql双主热备配置
  3. java jtable导出txt_如何将jtable中的文本数据保存到文件中
  4. 一道二叉树的题目--后序遍历+中序遍历确定二叉树
  5. 新员工入职自动加入所在部门的邮件组。
  6. Java(19)JDBC
  7. Atitit.解决org.hibernate.DuplicateMappingException: Duplicate class/entity mapping
  8. 浅析继承关系中的方法调用
  9. 10个经典的哲学小故事
  10. SpringBoot报错couldn‘t check if tables are already present using metadata: