我们有时候在看数据结构相关书籍时,经常会看到这样的写法:
void StackInit(ST& ps)
{
assert(ps);
ps.a = NULL;
ps.top = 0;
ps.capacity = 0;
}
注意,这里的&可不是表示取地址。如果你把它理解为取地址,那就在错误的路上狂奔,且一去不返了。
相信大家在学习C语言时,也被指针折磨过不少。可能都出现过野指针等,这些失误让我们不胜其烦。
其实,编写书籍的老师,使用“&”这个符号,就是为了减少指针的使用。“&”在这里,是C++中的“引用”。
但是,这对于一些没有了解过相关语法的同志,那又成了一个坑。毕竟,C语言里面的“&”可是代表着“取地址”。
那么,我们接下来就来好好说道说道,“&”到底是个什么东西。
我们在学习C语言的指针部分时,会经常性用到这样一个符号——“&”。
我们把它叫做“取地址”。
#include
int main()
{
int a = 0;
int* p = &a; //&a取出a的地址,p是一个指针变量,p中存放a的地址
printf("%d\n",*p);
return 0;
}
相信大家对于“取地址”这个用法已经很熟悉了。
我们简单写一下栈的初始化和销毁,以此来显示指针与&的具体应用。
#include
#include
#include
#include
#include
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
int main()
{
ST st;
StackInit(&st); //对栈进行初始化,需要传址
StackDestroy(&st);
return 0;
}
在C++中,“&”表示的是引用,也可以理解为取别名。
就像《武林外传》中的白展堂,他有另外一个名字:盗圣。那么盗圣就是他的别名。提到白展堂是在说他,提到盗圣也是在说他。
#include
using namespace std;
int main()
{
int a = 100;
int& aa = a; // 引用定义
//& - 引用 (不是取地址)
//aa 与 a 地址相同
//引用 必须在定义的时候初始化
// 一个变量可以有多个引用
//引用一旦引用一个实体,再不能引用其它实体
int b = 100;
int& bb = b;
int& bbb = b;
int& b2 = bb;
return 0;
}
注意:
//引用做参数
//叫做:传引用(不是传值也不是传地址)
void Swap(int& aa, int& bb)
{
int tmp = aa;
aa = bb;
bb = tmp;
}
int main()
{
int a = 100;
int b = 130;
//int& aa = a;
//int& bb = b;
Swap(a, b);
printf("%d %d", a, b);
return 0;
}
//常引用
int main()
{
权限放大,不行
//const int a = 100; //权限是只读
//int& aa = a; //权限是读写
//可行,权限不变
const int a = 100;
const int& aa = a;
//权限缩小,可行
int b = 100;
const int& bb = b;
return 0;
}
如果想多了解一些C++,那么可以将下面的内容了解一下。
引用返回:不会生成拷贝返回,直接返回引用。
如果函数返回时,出了函数的作用域,如果返回对象还在(还没还给系统),则可以使用引用返回;
如果已经还给系统了,则必须使用传值返回。
引用的作用主要体现在传参和传返回值:
1、引用传参和传返回值,有些场景下面,可以提高性能(大对象+深拷贝对象)
2、引用传参和传返回值,输出型参数和输出型返回值。 也就是说,有些场景下面,形参的改变可以改变实参
有些场景下,引用返回 可以改变返回对象。
当我们了解了“&”就是“引用”(取别名)时,那我们学习数据结构就会更得心应手了。
祝大家能在学习编程这条路上一马平川,一片光明。