关于c++中引用发明的猜想
- 什么是引用
- 引用怎么用
- 我们为什么需要引用
- 怎么就发明引用了呢
阅读之前注意:
本文阅读建议用时:52min
本文阅读结构如下表:
项目 | 下属项目 | 测试用例数量 |
---|---|---|
什么是引用 | 定义、基础应用 | 2 |
引用怎么用 | 临时变量、静态变量、已有变量 | 4 |
我们为什么需要引用 | 进阶应用 | 1 |
怎么就发明引用了呢 | 无 | 0 |
什么是引用
在C++中,引用是已定义变量的别名。 —— [ 维基百科 ]
什么是引用.之一(定义)
我们先来看一个最简单的例子
#include<iostream>
using namespace std;
void main()
{
int a=10;
int &b=a;
printf("a=%d,b=%d\n",a,b);
system("pause");
}
上面的代码块中,b就是a的引用。根据官方解释,引用是已定义变量的别名。可以看到,a是已定义的变量,那么b就是a的引用,b是a的别名,即b相当于a,两者的地址是一样的,有着相同的内存空间,那么可以推断,修改b也就能够修改a,下面是修改后的代码1.
什么是引用.之二(基础应用)
#include<iostream>
using namespace std;
void main()
{
int a=10;
int &b=a;
printf("a=%d,b=%d\n",a,b);
b=11;
printf("a=%d,b=%d\n",a,b);
system("pause");
}
运行即可看到修改后a和b输出的是同样的结果,因为a和b都是同一块内存空间的名字,所以修改了b也就修改了a2.
引用怎么用
引用用法.之一(临时变量,仅测试用)
#include<iostream>
using namespace std;
int myf1()
{
int a=11;
return a;
}
int &myf2()//引用做返回值
{
int a=12;//函数内部的临时变量
return a;
}
int *myf3()//myf2和myf3其实是类似的
{
int a=13;
return &a;
}
void main()
{
int m = myf1();
printf("m:%d\n", m);
int &n = myf2();//有警告但返回未出错,本来是应该出错,出现乱码的,因为临时变量已经消亡,返回出来的地址执行*操作取到的应该是乱码
printf("n:%d\n", n);
int x = myf2();//有警告,返回未出错,编译器看到是引用会自动执行一个*操作
printf("x:%d\n", x);
int *y = myf3();
printf("y:%d\n", *y);
system("pause");
}
引用用法.之二(静态变量)
#include<iostream>
using namespace std;
int &myf4()
{
static int a = 14;//静态变量,函数返回时数据未被销毁
return a;
}
void main()
{
int z = myf4();
printf("z:%d\n", z);
system("pause");
}
#include<iostream>
using namespace std;
int &myf5()//引发思考:什么是链式编程?
{
static int a = 15;//由实验结果可知静态变量只初始化一次,除非有另外赋值
//a = 15;
return a;
}
void main()
{
myf5() = 16;//把静态变量赋值为16
int g = myf5();
printf("%d\n", myf5());
int t = myf5();
printf("g:%d\n", g);//因为不会再初始化,打印出来的g是16
printf("t:%d\n", t);
system("pause");
}
引用用法.之三(已有变量)
int &myf6(int &a)//变量地址已有,不会出错
{
a++;
return a;
}
void main()
{
int b = 12;
b = myf6(b);
printf("b:%d\n", b);
int c = myf6(b);
printf("b:%d c:%d\n", b, c);
int &d = myf6(b);
printf("d:%d\n", d);
system("pause");
}
从上面引用的三种用法来看,引用和变量的生存周期有很大的关系,通常来说临时变量不应该做引用的返回,但如果是静态变量或者是被返回的函数里已有的变量(传入的形参就是引用,返回时自然也可以返回引用),生存周期很长,返回引用是可以的。
同时我们也知道了引用的好处,它帮我们隐藏了取地址(&)和取内容(*)的操作3.
我们为什么需要引用
我们来看一个进阶的应用吧,请注意 *& 符号
#include<iostream>
using namespace std;
typedef struct _teacher
{
char name[32];
int age;
}teacher;
void getTeacher1(teacher **p)
{
teacher *tmp = (teacher *)malloc(sizeof(teacher));
tmp->age = 25;
*p = tmp;
}
void getTeacher2(teacher * &p)//p就相当于t2,把t2的地址传过来给p,但编译器遇到p会自动做*操作
{
p = (teacher *)malloc(sizeof(teacher));
p->age = 24;
}
void main()
{
teacher *t1 = NULL;
teacher *t2 = NULL;
getTeacher1(&t1);
getTeacher2(t2);
printf("t1:%d\n", t1->age);
printf("t2:%d\n", t2->age);
system("pause");
}
从上面的程序可以知道,我们先是定义了一个老师的结构体,然后定义了其结构体指针,到函数里去申请内存空间并赋值。比较getTeacher1(&t1)和getTeacher(t2),采用了引用的函数不仅在代码部分大大得到了简化,而且可读性也更强4!
怎么就发明引用了呢
经过以上的例子,相信你也差不多该领会引用的好处了。它就是帮我们隐藏了两种操作,仅仅只需要你在定义变量的时候在前面加一个&符号,就帮你避免了频繁写取地址和取内容的问题,而且在代码可读性上也大大提高,理解上只要替换下变量的名字就行了。
你看,引用这么方便,所以请尽情的使用 引用 吧!
懒惰使人类思考。
如果本文对你有帮助,不如请我一杯可乐吧 🍼