---- 整理自狄泰软件唐佐林老师课程
文章目录
1. 关于 const 的疑问
- const :什么时候为只读变量?什么时候是常量?
1.1 const 常量的判别准则
- 只有用 字面量 初始化的 const 常量 才会进入 符号表
- 使用 其它变量 初始化的 const 常量仍然是 只读变量
- 被 volatile 修饰的 const 常量 不会进入符号表
- 在 编译期间不能直接确定初始值的 const 标识符 ,都被作为 只读变量 处理。
1.2 const 引用的类型和初始化变量的类型
- const 引用的类型和初始化变量的类型相同时:初始化的变量成为只读变量
- const 引用的类型和初始化变量的类型不同时:生成一个新的只读变量
#include <stdio.h>
int main()
{
const int x = 1; // 字面量,符号表中
const int& rx = x;
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);
return 0;
}
#include <stdio.h>
int main()
{
volatile const int x = 2;
int* p = const_cast<int*>(&x);
*p = 6;
printf("x = %d\n", x); // 被 volatile 修饰的 const 常量不会进入符号表
printf("p = %p\n", p);
const int y = x; // 在编译期间不能直接确定初始值的 const 标识符 ,
// 都被作为只读变量处理
p = const_cast<int*>(&y);
*p = 7;
printf("y = %d\n", y);
printf("p = %p\n", p);
return 0;
}
#include <stdio.h>
int main()
{
char c = 'c';
char& rc = c;
const int& trc = c; // const 引用的类型和初始化变量的类型不同时,
// 生成一个新的只读变量
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 0;
}
2. 关于引用的疑问
- 引用与指针有什么关系?如何理解 “ 引用的 本质 就是指针常量 ” ?
2.1 指针和引用的关系
- 指针是一个 变量
- 值为一个内存地址,不需要初始化,可以保存不同的地址
- 通过指针可以访问对应内存地址中的值
- 指针可以被 const 修饰成为常量或者只读变量
- 引用 只是一个变量的 新名字
- 对引用的操作(赋值、取地址等)都会 传递到代表的变量 上
- const 引用使其代表的变量具有 只读属性
- 引用 必须在定义时初始化,之后无法代表其它变量
2.2 使用角度和编译器角度
- 从使用 C++ 语言的角度来看:
- 引用和指针没有任何的关系
- 引用是变量的新名字,操作引用就是操作对应的变量
- 从 C++ 编译器的角度来看:
- 为了支持新概念 “引用” 必须要有一个解决方案
- 在编译器内部,使用指针常量来实现 “引用”
- 因此,“引用” 在定义时必须初始化
- 在工程项目开发中:
- 当进行 C++ 编程时,直接站在使用的角度看到引用,与指针毫无关系,引用就是变量的别名
- 当对 C++ 代码进行调试分析时,一些特殊情况,可以考虑站在 C++ 编译器的角度看待引用
2.3 问题
- 下面的代码有问题吗?
- C++ 中 不支持引用数组(因为数组元素的地址是 递增的)
#include <stdio.h>
int a1 = 1;
struct SV {
int& x;
int& y;
int& z;
};
int main()
{
int a2 = 2;
int* a3 = new int(3);
SV sv = {a1, a2, *a3};
int& array[] = {a1, a2, *a3};
printf("&sv.x = %p\n", &sv.x);
printf("&sv.y = %p\n", &sv.y);
printf("&sv.z = %p\n", &sv.z);
delete a3;
return 0;
}
#include <stdio.h>
int a1 = 1;
struct SV {
int& x;
int& y;
int& z;
};
int main()
{
int a2 = 2;
int* a3 = new int(3);
SV sv = {a1, a2, *a3};
// int& array[] = {a1, a2, *a3};
printf("&sv.x = %p\n", &sv.x);
printf("&sv.y = %p\n", &sv.y);
printf("&sv.z = %p\n", &sv.z);
delete a3;
return 0;
}