提示:可以将代码复制下来,加上头文件以及main函数在编译器食用效果更佳!
// 从引用开始 &
// 顾名思义 , 引用就是为你已经定义好了的变量起一个别名
// 谨记 使用引用为你的变量起别名时一定要确保那个那边是真实存在且被初始化过的
//EX:
int val_Oldname = 10;
//使用 & , val_Newname 与 val_oldname是完全相同的,唯一不同的仅仅只是名字
int val_Newname = val_Oldname;
//cout << val_Oldname << endl << val_Newname << endl;
// 指针 *
// 与引用类似 , 指针也实现了对其它对象得分间接访问 , 但是二者还是有很大的区别
// 1: 指针本身就是一个对象 , 可以进行赋值和拷贝(如果指针存在且被初始化过,是否
// 可以通过 & 去引用指针?) , 而且指针可以在其生命周期内先后指向不同的对象
// 2: 指针无需在定义时赋初值,但指针若是未经初始化,则会随机指向一个不确定的地址
// 定义指针时应使用 *ptr_name 的形式 , ptr_name表示变量名 , 若在一条语句中想要定义多个
// 指针 , 那么每个指针都必须带上*
// EX:
int* prt_1, * ptr_2; //定义两个int类型的指针
double* prt_3, * ptr_4; // 定义两个double类型的指针
// 获取对象的地址(指针即是地址 , 相当于获取对象的指针,又或者说创造一个指向对象的指针?)
// 需要用到取地址符的操作 &
int val = 10;
int* ptr_val = &val; // ptr_val中存放的是val的地址
//cout << ptr_val << endl; // 输出:000000E7476FF9F4
// 如果指针指向一个对象,则允许使用解引用符 (*)来访问该对象
//cout << *ptr_val << endl ; //输出: 10
// 解引用符操作仅仅只适用于那些明确了指向某个已存在的对象的指针
//定义一个空指针
int* ptr_null = nullptr;
int *ptr_5 = nullptr; //定义一个空指针
int val_1 = 10; // 定义一个变量
ptr_5 = &val_1; // 初始化ptr_5,使其指向val_1
int* ptr_6 = nullptr; //定义一个空指针
ptr_6 = ptr_5; //使ptr_6 与 ptr_5 指向同一个地址 val_1
//void*是一种特殊的指针,可以存放任意对象的地址
// 联系上文我们所提出的问题 , 既然指针也是一个对象,那么是不是引用也可以直接去引用指针?
// 我们已知 , 引用并不是一个对象 , 所以不会存在指向引用的指针,无需证明
int val_2 = 10;
int* ptr_7 = nullptr;
int*& ref_prt_7 = ptr_7; // 定义一个引用名字叫 ref_ptr_6 , 指向 ptr_6
ref_prt_7 = &val_2; //为引用赋值 , 相当于 ptr_6指向 val_2
cout << *ptr_7 << endl;
// 对常量的引用
const int val_c = 10; //引用常量
const int& ref_val_c = val_c; //此时ref_val_c 不可被修改,也不可指向别的变量
//(非常量引用不可以引用常量?)
//int& ref_val_Nc = val_c; // 这一步是错误的,证明上面的问题,若非常量引用引用常量
// 可能会丢弃 const 那么这个值就会允许被修改,违背了const的初衷
//此法可用来修改常量引用
int val_3 = 10;
int& ref_val_3 = val_3;
int const& ref_val_3_01 = val_3;
cout << ref_val_3_01 << endl;// 输出10
ref_val_3 = 0;
cout << ref_val_3_01 << endl;//输出0
// const与指针
// 常量必须由常量指针指向 , 常量指针也可以指向非常量
const double val_4 = 3.14;
//double* prt_vsl_4 = &val_4;//错误: 常量必须由常量指针指向
const double* ptr_val_4 = &val_4; //正确
double val_5 = 2.1; //非常量
const double* ptr_val_5 = &val_5; //正确: 常量指针也可以指向非常量
//(还是有点不理解 const * 和 * const的区别~~~~~)
// const * 为一个顶层const , 因此指针本身就是一个常量,不可以被修改
// * const 为一个底层const , 因此允许改变指针的值
//常量表达式: 值不会改变(const),在编译过程中就能得到结果(明确赋值)
// constexpr , 且用constexpr做数据类型名的函数叫constexpr函数,其返回的值是一个常数
constexpr int val_6 = 10; // val_6为一个常量表达式
const int val_7 = 10; //val_7 也为一个常量表达式
int val_8 = 10; //val_8 不为一个常量表达式,即使在编译过程中已知val_8的值,但其值可以改变
// 不符合常量表达式的定义,因此,他不为一个常量表达式
// 指针和引用也可以被定义为constexpr但其必须被初始化,constexpr仅对指针或引用
//有效,并不包括其所指向的对象