C++中的引用(附带实例)
C++ 11标准中提出了引用的概念,如果不加特殊声明,一般都是指左值引用。
引用实际上是一种隐式指针,它为对象建立了一个别名,通过操作符“&”来实现。其定义形式如下:
例如,下述定义了一个引用变量 ia,它是变量 a 的别名,对 ia 的操作与对 a 的操作完全一样:
有关引用的说明如下:
1) 一个 C++ 引用被初始化后,无法再使用它去引用另一个对象,即引用不能被重新约束。
2) 引用变量只是其他对象的别名,操作它与操作原对象的效果完全相同。
3) 指针变量与引用变量的区别为:指针是一种数据类型,引用不是数据类型;引用和变量的数据类型必须相同,不能进行类型转换;指针和引用都可以指向其他变量,指针的语法更复杂,而引用的使用方法与普通变量相同。
4) 引用必须进行初始化,否则会系统报错。例如,下面的代码会提示 references must be initialized 错误,无法通过编译:
【实例 1】利用引用输出变量的值。具体代码如下:
左值与右值的区别在于,右值是临时变量,如函数的返回值,并且无法改变。例如:
右值引用可以理解为对右值的引用,当右值引用初始化后,临时变量消失。例如:
右值引用只可以初始化于右值,但右值引用实质上是一个左值,它具有临时变量的数据类型。与左值引用相同的是:
【实例 2】引用传递交换数值。定义 swap() 函数,参数为两个引用变量。主函数中输入两个值,调用 swap() 函数交换两个数值。代码如下:
使用引用和指针作为函数参数,各有益处。引用必须被初始化为一个对象,且无法再指向其他对象,优点是函数中不用验证引用参数的合法性。
例如,下面的函数调用是非法的:
因此,当指针作为函数参数时,函数体中通常需要验证指针参数是否为空。优点是用户可以随意修改指针参数指向的对象,这是引用参数所不具备的。
引用实际上是一种隐式指针,它为对象建立了一个别名,通过操作符“&”来实现。其定义形式如下:
数据类型 & 表达式;
例如,下述定义了一个引用变量 ia,它是变量 a 的别名,对 ia 的操作与对 a 的操作完全一样:
int a=10; //定义整型变量a int & ia=a; //定义引用变量ia,它是a的别名 ia=2; //把2赋给ia,也就是a
有关引用的说明如下:
1) 一个 C++ 引用被初始化后,无法再使用它去引用另一个对象,即引用不能被重新约束。
2) 引用变量只是其他对象的别名,操作它与操作原对象的效果完全相同。
3) 指针变量与引用变量的区别为:指针是一种数据类型,引用不是数据类型;引用和变量的数据类型必须相同,不能进行类型转换;指针和引用都可以指向其他变量,指针的语法更复杂,而引用的使用方法与普通变量相同。
4) 引用必须进行初始化,否则会系统报错。例如,下面的代码会提示 references must be initialized 错误,无法通过编译:
int b; int &a; //未初始化的引用,无法通过编译,系统会报错
【实例 1】利用引用输出变量的值。具体代码如下:
#include <iostream>
using namespace std;
int main()
{
int a;
int & ref_a =a; //定义引用变量 ref_a,它是 a 的别名
a=100;
cout << "a="<< a <<endl;
cout << "ref_a="<< ref_a << endl;
a=2;
cout << "a="<< a <<endl;
cout << "ref_a="<< ref_a << endl;
int b=20;
ref_a=b; //改变 ref_a
cout << "a="<< a <<endl;
cout << "ref_a="<< ref_a << endl;
ref_a--;
cout << "a="<< a <<endl;
cout << "ref_a="<< ref_a << endl;
}
程序运行结果为:
a=100
ref_a=100
a=2
ref_a=2
a=20
ref_a=20
a=19
ref_a=19
C++11右值引用
右值引用是 C++ 11 中引入的新特性,其定义形式如下:类型 && i = 被引用的对象;
左值与右值的区别在于,右值是临时变量,如函数的返回值,并且无法改变。例如:
#include <iostream>
int get()
{
int i =4;
return i;
}
int main()
{
int k =3;
int& a =++(get()); //编译出错
int& a =++(get())+k; //编译出错
return 0;
}
右值引用可以理解为对右值的引用,当右值引用初始化后,临时变量消失。例如:
#include <iostream>
int get()
{
int i = 4;
return i;
}
int main()
{
int && k = get()+4;
// int & i = get()+4; //出错
k++;
std::cout<<"k的值"<<k<<std::endl;
return 0;
}
程序运行结果为:
k的值9
右值引用只可以初始化于右值,但右值引用实质上是一个左值,它具有临时变量的数据类型。与左值引用相同的是:
- 一个右值引用被初始化后,无法使用它再去引用另一个对象,它不能被重新约束;
- 右值引用初始化后,具有该类型数据的所有操作。
C++使用引用传递函数参数
C++ 中,函数参数的传递方式主要有两种,值传递和引用传递。使用引用传递时,在调用函数中修改参数的值,其改变会影响到实际参数。【实例 2】引用传递交换数值。定义 swap() 函数,参数为两个引用变量。主函数中输入两个值,调用 swap() 函数交换两个数值。代码如下:
#include <iostream>
using namespace std;
void swap(int & a,int & b) //定义 swap()函数,参数为两个引用
{
int tmp;
tmp=a;
a=b;
b=tmp;
}
int main()
{
int x,y;
cout << "请输入x" << endl;
cin >> x;
cout << "请输入y" << endl;
cin >> y;
cout<<"通过引用交换 x 和 y"<<endl;
swap(x,y); //调用 swap()函数,实现两个数的交换
cout << "x="<< x <<endl;
cout << "y="<< y <<endl;
}
程序运行结果为:
请输入x
37
请输入y
9
通过引用交换 x 和 y
x=9
y=37
使用引用和指针作为函数参数,各有益处。引用必须被初始化为一个对象,且无法再指向其他对象,优点是函数中不用验证引用参数的合法性。
例如,下面的函数调用是非法的:
void ValuePass(int & var) //定义函数 ValuePass(),使用引用作为参数
{
var = 10; //修改参数的值
cout << var << endl; //输出参数
}
int main(int argc, char *argv[])
{
ValuePass(0); //非法的函数调用
return 0;
}
程序中,如果 ValuePass 采用指针作为函数参数,则“ValuePass(0);”调用语句是合法的,但存在一定的隐患。这是因为 0 会被认为是空指针,而对空指针进行操作会导致地址访问错误。因此,当指针作为函数参数时,函数体中通常需要验证指针参数是否为空。优点是用户可以随意修改指针参数指向的对象,这是引用参数所不具备的。
ICP备案:
公安联网备案: