1,关于 const 的疑问:

1,const 什么时候为只读变量,什么时候是常量;

1,const 从 C 到 C++ 进化的过程中得到了升级,const 在 C++ 中不仅仅像在 C 中声明一个只读变量,其在 C++ 中完全可以得到一个常量;

2,const 常量的判别准则:

1,只有用字面量初始化的 const 常量才会进入符号表;

1,这里是字面量初始化 const 常量,不是 const 常引用;

2,得到了真正意义上的常量;

2,使用其他变量初始化的 const 常量仍然是只读变量;

1,编译器在编译期间不可能知道变量初始化时候的值;

2,得到只读变量;

3,被 volatile 修饰的 const 常量不会进入符号表;

1,volatile 表示声明的标识符是易变的;

2,这个可能的易变性也许不在当前编译的文件中,发生在外部;

3,外部相当于在其它文件中,比如多线程、中断等;

4,每次访问 volatile 修饰的标识符时,因为是易变的,所以应该到内存中直接读取;

5,意味着被 volatile 修饰的标识符不可能进入符号表;

6,意味着当 volatile 和 const 同时修饰一个标识符时,得到的是只读变量,不可能进入符号表;

7,const 此时的意义说明在当前的文件或者当前的作用域当中,volatile 和 const 一起修饰的标识符不能出现在赋值符号的左边;

(4),在编译期间不能直接确定初始值的 const 标识符,都被作为只读变量处理;

3,const 引用的类型与初始化变量的类型:

1,相同:初始化变量成为只读变量;

2,不同:生成一个新的只读变量;

4,const 典型问题分析编程实验:

1,main.cpp 文件:

 #include <stdio.h>

 int main()
{
const int x = ;//直接得到值,进入符号表,但是还是会为 x 分配空间,只不过这个空间 x 没有用而已;
const int& rx = x;//rx代表只读变量,这个变量是编译器为x分配而没有使用的空间;引用代表变量的别名,而变量代表一段内存空间的别名,所以引用代表一段内存空间的别名; int& nrx = const_cast<int&>(rx); //消除 rx只读属性,和rx 代表的内存空间相同; nrx = ; 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 int y = ; // 只读变量;
int* p = const_cast<int*>(&y); //y被 const修饰,取到的地址也有 const 属性,这里将地址只读属性去掉; *p = ; printf("y = %d\n", y);
printf("p = %p\n", p); const int z = y; // y 是变量,得到只读变量; p = const_cast<int*>(&z); *p = ; printf("z = %d\n", z);
printf("p = %p\n", p); char c = 'c';
char& rc = c;
const int& trc = c; // char 类型默认转换为 int;const 引用初始化类型不同,将得到新的只读变量,所以改变 rc 和 trc 没有丝毫关系; rc = 'a'; printf("c = %c\n", c);
printf("rc = %c\n", rc);
printf("trc = %c\n", trc);
printf("&c = %p\n", &c);
printf("&rc = %p\n", &rc);
printf("&trc = %p\n", &trc); return ;
}

2,输出结果:

 x =   // 进入符号表,编译期间就是 1;
rx =
nrx =
&x = 0xbfb1a708//为const修饰的标识符分配空间,通过指针或引用使用;
&rx = 0xbfb1a708
&nrx = 0xbfb1a708
y =
p = 0xbfb1a6fc
z =
p = 0xbfb1a6f4
c = a
rc = a
trc = c // 原始的赋值结果;
&c = 0xbfd1242f
&rc = 0xbfd1242f
&trc = 0xbfd12408 // 新开辟的空间;

5,关于引用的疑问:

1,引用与指针有什么关系,如何理解“引用的本质就是指针常量”;

6,指针和引用分析:

1,指针是一个变量:

1,值为一个内存地址,不需要初始化,可以保存不同的地址;

2,通过指针可以访问对应内存地址中的值;

3,指针可以被 const 修饰成为常量或者只读变量;

2,引用只是一个变量的新名字:

1,对引用的操作(赋值,取地址等)都会传递到代表的变量上;

1,新名字是一段内存空间的代号;

2,引用是给已经存在的合法内存空间一个新的代号;

2,const 引用使其代表的变量具有只读属性;

3,引用必须在定义时初始化,之后无法代表其它变量;

1,身份证号代表一个人,不能复用;

2,一个车牌号就代表一个车,不能复用;

3,因为是指针常量,所以不能代表其它变量;

7,从 C++ 不同角度分析引用:

1,从使用 C++ 语言的角度来看:

1,引用与指针没有任何的关系;

2,引用是变量的新名字,操作引用就是操作对应的变量;

2,从 C++ 编译器的角度来看:

1,为了支持新概念,“引用”必须要一个有效的解决方案;

2,在编译器内部,使用指针常量来实现“引用”;

3,因此“引用”在定义时必须初始化;

8,在工程项目开发中:

1,当进行 C++ 编程时,直接站在使用的角度看待引用,与指针毫无关系,引用就是变量的别名;

2,当对 C++ 代码进行调试分析时,一些特殊情况,可以考虑站在 C++ 编译器角度看待引用;

3,下面代码正确吗?

 int a = ;
int b = ;
int* pc = new int();
int& array[] = [a, b, *pc];

9,引用典型问题分析编程实验:

1,main.cpp 文件:

 #include <stdio.h>

 int a = ;

 struct SV
{
int& x;
int& y;
int& z;
}; int main()
{
int b = ;
int* pc = new int();
SV sv = {a, b, *pc}; // 结构体中的每个元素是引用就可以;
// int& array[] = {a, b, *pc}; //数组中的每个元素是引用就不可以;error: declaration of ‘array’ as array of references; C++ 天生要支持 C 语言,C 语言中数组中的每个元素在内存中是顺序存放的,地址是递增的,所以在 C++ 中也要兼容这个特性,而在 C++ 中唯有引用数组破快了这个特性,所以说 C++ 中不支持引用数组;&array[1] - &array[0] = ? Expected ==> 4; printf("&sv.x = %p\n", &sv.x);
printf("&sv.y = %p\n", &sv.y);
printf("&sv.z = %p\n", &sv.z); delete pc; return ;
}

2,输出结果:

&sv.x = 0x804a020

   &sv.y = 0xbffe92bc

   &sv.z = 0x9f97008

3,在开发中遇到奇怪的 bug,要站在编译器的角度考虑问题;

10,小结:

1,指针是一个变量;

2,引用是一个变量的新名字;

3,const 引用能够生成新的只读变量;

4,在编译器内部使用指针常量实现“引用”;

1,C++ 中为了兼容 C 语言中的所有特性,放弃了引用数组,这样会使得相邻元素的地址之差不是期望的;

5,编译时不能直接确定初始值的 const 标识符都是只读变量;

C++ 中的 const、引用和指针的深入分析的更多相关文章

  1. c++中的引用与指针的区别

    http://blog.csdn.net/lyd_253261362/article/details/4323691 c++中的引用与指针的区别 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存 ...

  2. 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

    [源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, con ...

  3. C++中引用与指针的区别(详细介绍)

    C++中引用与指针的区别(详细介绍) C++中的引用与指针的区别   指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一 ...

  4. C++ 中引用与指针的区别

    1.引用只是变量的一个别名,并不占用内存空间,而指针是一个变量,里面保存着被指向的变量在内存中的地址: 2 引用只能在定义时被初始化一次,之后不可变,而指针可变: 3 引用没有 const,指针有 c ...

  5. [ZZ]C++中,引用和指针的区别

    (1) 引用总是指向一个对象,没有所谓的 null reference .所有当有可能指向一个对象也由可能不指向对象则必须使用 指针. 由于C++ 要求 reference 总是指向一个对象所以 re ...

  6. 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针

      您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...

  7. c++中的const参数,const变量,const指针,const对象,以及const成员函数

    const 是constant 的缩写,“恒定不变”的意思.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.所以很多C++程序设计书籍建议:“Use const whe ...

  8. C、C++中引用与指针的区别

    1:引用的和指针在概念上的区别 引用是变量的别名,例如 int m; int &n=m; 引用作为一个别名.它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用 ...

  9. 【C++】C++中的引用与指针

    想必大家对C++中的指针都有所了解,但是什么是引用呢?C++11标准引入了“引用”的新功能. 引用 引用(reference):给对象起了另外一个名字,引用类型引用(refers to)另外一种类型, ...

随机推荐

  1. JVM(5)之 GC之标记

    开发十年,就只剩下这套架构体系了! >>>     堆分为年轻代和年老代.永久代是非堆内存,它又叫做方法区(一般的说法),主要存储已被加载的类信息.常量.静态变量.而该区域在java ...

  2. Vue PC端图片预览插件

    *手上的项目刚刚搞完了,记录一下项目中遇到的问题,留做笔记: 需求: 在项目中,需要展示用户上传的一些图片,我从后台接口拿到图片url后放在页面上展示,因为被图片我设置了宽度限制(150px),所以图 ...

  3. jsp页面必填项如何加红星号*

    1.加*号 并且设置*号大小 <span style="color:red; font-size: 20px">*</span>

  4. Mystery——团队作业——系统设计

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1 这个作业要求在哪里 https://edu.cnblo ...

  5. 解释ARP协议和RARP协议

    解释ARP(地址解析协议) 首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系. 当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主 ...

  6. bzoj 1001 原图最小割转化为对偶图最短路

    题目大意: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形 ...

  7. C# 枚举的声名和使用

    namespace xxxxxx { public enum EnumTextHAlign { Left = , Center = , Right = } } using xxxxxx;

  8. axios拦截器的使用方法

    很多时候我们需要在发送请求和响应数据的时候做一些页面处理,比如在请求服务器之前先判断以下用户是登录(通过token判断),或者设置请求头header,或者在请求到数据之前页面显示loading等等,还 ...

  9. Vue学习笔记-插槽基本使用

    为了让我们的组件更加具有扩展性,可以使用插槽 <div id="app"> <cpn> <span>返回</span> <in ...

  10. Struts2基础-1- 简单java类实现Action控制器

    Strut2中,Action可以不继承任何特殊的类或不实现任何特殊的接口,可以只编写一个普通的Java类作为Action类,只要该类含有一个返回字符串的无参的public方法即可!实际开发中,通常继承 ...