【和春笋一起学C++】(十八)C++函数新特性——引用变量用作函数参数
目录
1. 内置变量的引用作为函数参数
2. 结构的引用作为函数参数
3. 延伸
1. 内置变量的引用作为函数参数
在C语言中,要实现交换两个变量值的一个函数,需要用到指针。
void swapp(int *p, int *q)
{int temp;temp = *p;*p = *q;*q = temp;
}
C++有了引用变量之后,可以通过将引用变量用作函数参数实现交换两个变量的值。
void swapr(int &a, int &b)
{int temp;temp = a;a = b;b = temp;
}
原文为CSDN作者:三月微暖寻春笋
2. 结构的引用作为函数参数
C++引入引用主要是为了用于结构和类,而不是基本的内置类型。
使用结构引用的方式与使用内置变量引用相同,只需在声明结构参数时使用引用操作符&即可。
关于结构的引用作为函数参数,其实在《结构作为函数参数》文章中已有体现。此处将代码稍作修改,将两个时间的和的函数返回值也设置为结构的引用,代码如下:
#include <iostream>
#include <cstring>using namespace std;
struct homework_time
{int hours;int mins;
};const int Mins_per_hr = 60;homework_time& sum(homework_time& t1, homework_time& t2)
{homework_time total;total.mins = (t1.mins + t2.mins) % Mins_per_hr;total.hours = (t1.hours + t2.hours) + (t1.mins + t2.mins) / Mins_per_hr;return total;
}void show_time(const homework_time& t)
{cout << t.hours << "hours, " << t.mins << " minutes\n";
}int main()
{homework_time time1 = {1,20};homework_time time2 = { 1,50 };homework_time& time_total = sum(time1, time2);show_time(time1);show_time(time2);show_time(time_total);return 0;
}
输出结果如下:
求和结果是一串乱码,怎么回事呢?
函数的返回机制是将返回值复制到新的临时存储区域中,然后调用程序将访问该区域,而返回引用意味着调用函数将直接访问返回值,返回值也不再需要拷贝到临时存储区域。上面的程序中,当调用程序访问返回值时,返回值total的变量生命周期已经结束,该变量的内存空间已被释放,因此,调用程序访问了一个未知的地址,所以输出值才出现了一串乱的数字。可以作如下修改,将求和函数中的total声明为一个指向homework_time结构的指针,并使用new申请一段用以存放homework_time结构数据的内存空间,代码如下。这时当sum函数结束时,只要没有使用delete释放存储homework_time结构数据的内存空间,那么存放在内存空间的返回值就不会丢失,调用程序也就能访问到函数的返回值。
可以将下面的函数替换上面程序中的求和函数,试着运行下程序。
homework_time& sum(homework_time& t1, homework_time& t2)
{homework_time * total = new homework_time;total->mins = (t1.mins + t2.mins) % Mins_per_hr;total->hours = (t1.hours + t2.hours) + (t1.mins + t2.mins) / Mins_per_hr;return *total;
}
那既然这么麻烦,为什么要将函数返回值也设置为结构的引用呢?其实,刚才在分析过程中已经解释了,将返回值设置为结构的引用可以使调用程序直接访问返回值,返回值就不需要拷贝到临时存储区域了,这样程序的运行效率会更高。需要注意的地方是,不能将函数中的自动变量作为函数的返回值,即当函数结束时,如果变量所占的内存单元被释放了,那该变量就不能作为返回值。
3. 延伸
在函数中用new申请的内存空间在函数结束时,其内存空间到底会不会被释放呢?下面用一个简单实例来说明问题,依然使用上面的程序,只是将求和函数改成返回一个指针,求和函数返回的是一个指向两个homework_time结构数据的指针,代码如下:
#include <iostream>
#include <cstring>using namespace std;
struct homework_time
{int hours;int mins;
};const int Mins_per_hr = 60;homework_time* sum(homework_time& t1, homework_time& t2)
{homework_time total1;total1.mins = (t1.mins + t2.mins) % Mins_per_hr;total1.hours = (t1.hours + t2.hours) + (t1.mins + t2.mins) / Mins_per_hr;homework_time total2;int t1_total_min = t1.hours*Mins_per_hr + t1.mins;int t2_total_min = t2.hours*Mins_per_hr + t2.mins;int diff_min = abs(t1_total_min - t2_total_min);total2.hours = diff_min / Mins_per_hr;total2.mins = diff_min - total2.hours*Mins_per_hr;homework_time* pt_homework_time = new homework_time[2];pt_homework_time[0] = total1;pt_homework_time[1] = total2;return pt_homework_time;
}void show_time(const homework_time& t)
{cout << t.hours << "hours, " << t.mins << " minutes\n";
}int main()
{homework_time time1 = {1,20};homework_time time2 = { 1,50 };homework_time* time_total = sum(time1, time2);show_time(time1);show_time(time2);show_time(time_total[0]);show_time(time_total[1]);return 0;
}
程序输出如下:
从输出结果看,求和函数中pt_homework_time指针所指向的内存空间在函数结束后并没有被释放,因为如果该内存空间被释放了,那么程序将无法输出正确的结果。
因此,在函数中用new申请的内存空间如果没有使用delete释放,那么在函数结束后其内存空间是不会被释放的。