前言
接上篇,继续来学习C++,本篇内容大概有 引用,inline 和 nullptr。
引用不是新定义一个变量,而是给已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量公用一块内存空间。
类型 & 引用别名 = 引用对象 ;
int main()
{
int a = 10;
int& b = a;//这里b是a的别名
//也可以给b去别名
int& c = b;
int& d = c;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
int main()
{
//int& b; 必须初始化
int a = 10;
int& b = a;
int c = 9;
b = c;// b=c => a=c ?
return 0;
}
引用作为函数参数:
void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 1, y = 9;
cout << x << " " << y << endl;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}
引用作为函数返回值:
例如,在栈数据结构中,我们取栈顶数据后直接修改:
int& STTop(ST& rs)
{
assert(rs.top > 0);
return rs.a[rs.top];
}
int main()
{
cout << STTop(st1) << endl;
STTop(st1) += 10;
cout << STTop(st1) << endl;
return 0;
}
可以引用一个 const 对象,但是必须用 const 引用。const 引用也可以引用配套对象,(对象的访问权限在引用过程中可以缩小,但是不能放大)。 const 引用需要注意:类似(int& rb = a*3; double d = 13.14; int& rd=d;)这样一些情况下 a*3的结果保存在一个临时变量中,int& rd = d也是类似,(在类型转换中会产生一些临时对象存储中间值,也就是 rd 与 rd引用的都是临时对象,而C++规定临时对象具有常性,所以这里就对权限进行了放大,必须要常引用才行)。 这里所说的临时变量就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象(C++中把这个未命名的对象叫做临时对象)。
int main()
{
const int a = 10;
//这里对a访问的权限放大
//int& ra = a;
const int& ra = a;
//这里 改变const定义的常量
//ra++;//ra = 0;
int b = 1;
const int& rb = b;
//const 修饰 引用rb 不能修改常量
//rb++;
return 0;
}
类型转换:
int main()
{
int a = 10;
const int& ra = 30;
// 编译报错: “初始化”: 无法从“int”转换为“int &”
// int& rb = a * 3;
const int& rb = a * 3;
double d = 12.34;
// 编译报错:“初始化”: 无法从“double”转换为“int &”
// int& rd = d;
const int& rd = d;
return 0;
}
C++中指针和引用,在实践中它们相辅相成,功能有重叠性,但是它们也各有自己的特点,互相不可替代。
C语言实现宏函数也会在预处理的时候展开,但是宏函数实现很复杂并且容易出错,且不方便调试,C++设计inline目的就是代替C的宏函数。
inline不建议声明和定义分离到两个文件,分离会导致连接出错。(inline被展开,就没有了函数的地址,链接时会报错)。
VS中debug版本默认不展开inline,(方便调试),如果想要进行展开可以进行一下设置
在C语言中,空指针是NULL,但是其实NULL是一个宏(在stddef.h)中
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#include<iostream>
using namespace std;
void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int* ptr)
{
cout << "f(int* ptr)" << endl;
}
int main()
{
f(0);/*本想通过f(NULL)调用指针版本的f(int*)函数,
但是由于NULL被定义成0,调用了f(intx)。*/
f(NULL);
f((int*)NULL);
//f((void*)NULL);
// 编译报错:error C2665: “f”: 2 个重载中没有一个可以转换所有参数类型
// f((void*)NULL);
f(nullptr);
return 0;
}
感谢各位大佬支持