0. 引言
上了一节 DS 课,但是回到了初学 C++ 的内容……
众所周知,最小生成树的 Kruskal 要用边表排序,通常是 sort()
配 cmp()
。
而 cmp()
的两个参数的类型最好是什么呢?
让我们回到初学 C++ 的时候,温习一下知识……
1. 实参的局限性
在自定义函数中,如 swap()
,参数必须是实参。而在别的函数中,也常常用实参来减少时间与内存的消耗。
但是,某些东西不能作为实参。
大家可以编译一下以下程序:
#include<bits/stdc++.h>
using namespace std;
void f(int &a){}
int main()
{
int a=114514;
f(a);
f(1);
return 0;
}
编译结果:
[Error] invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
,翻译过来就是 [错误]从“int”类型的右值初始化“int&”类型的非常量引用无效
。
就是说,右值1不能作为实参,只有左值2可以作为实参。
2. 常量3实参与变量4实参的区别
常量实参不可以改变值,而变量实参可以改变原变量的值。
编译程序:
#include<bits/stdc++.h>
using namespace std;
void f1(const int &a){a++;}
void f2(int &a){a++;}
int main()
{
int a=114514;
f1(a);
f2(a);
return 0;
}
效果:
常量不可改变值。
再编译这个程序:
#include<bits/stdc++.h>
using namespace std;
void f1(const int &a){}
void f2(int &a){}
int main()
{
int a=114514;
f1(1);
f2(1);
return 0;
}
照理来说,两者都是右值,编译是不可通过的。
然而:
f1()
没有报错。
因此,常量实参是可以传入右值的。
3. cmp() 的参数类型
相信过去的你,为了方便,类型是 Type x
;抑或是看了别人的写法,懵懂地写了 const Type x
、const Type &x
。
显而易见,const Type &x
是最好的。
const
避免莫名其妙的修改;&
避免耗费时间、内存;const &
避免传入右值错误。
现在,你懂了吗?
4. 后记
文章是相对较短的。原本的一节 DS 课,结构体排序 cmp() 使得老师给我们细化了知识。当初初学 C++ 时,由于一些原因,可能对 C++ 语法不会讲这么多。学好 DS 和算法,哪个不是先从最初的语法开始再到实现呢?
右值:只能出现在赋值号(
=
)右边的东西。比如实数。 ↩︎左值:可以出现在赋值号(
=
)左边的东西。实际的变量都是左值。 ↩︎常量:程序运行过程中不会改变的量。 ↩︎
变量:程序运行过程中可以改变的量。 ↩︎