一、引用的概念和声明
什么是引用?
就是给变量起一个别名(外号)
语法:<引用类型>&<引用名>=<被引用变量名>;
&在这里代表引用变量说明符;
&一符多义:
①位运算中的位与运算符
②引用变量说明符
③取地址运算符
引用时的注意事项:
1.引用类型必须与被引用变量的数据类型一致
2.被引用变量名必须是已被定义过的
3.声明引用时必须进行初始化,指明它是哪个变量的引用
4.引用不是值,不占内存空间
5.引用只能被初始化一次
对引用的修改实际就是对被引用变量的修改
【例1】 分析下列程序的输出结果,熟悉引用的建立和使用。
#include <iostream>
using namespace std;
int main( )
{
int intOne=5;
int &rInt=intOne;
cout<<"intOne:"<<intOne<<endl;
cout<<"rInt:"<<rInt<<endl;
rInt=7;
cout<<"intOne:"<<intOne<<endl;
cout<<"rInt:"<<rInt<<endl;
}
答案:
intOne:5
rInt:5
intOne:7
rInt:7
补充:
1.与指针类似,引用声明有三种:
int& ra;
int &ra;
int & ra;
2.可以在一条语句中完成变量定义与引用声明
eg:int a, &ra=a;
二、引用的操作
对引用的操作就是对被引用变量的操作(比如:赋值,取地址)
【例2】 分析下列程序的输出结果。
#include <iostream>
using namespace std;
int main( )
{
int intOne=5;
int &rInt=intOne;
cout<<"intOne:"<<intOne<<endl;
cout<<"rInt:"<<rInt<<endl;
int intTwo=8;
rInt=intTwo;
cout<<"intOne:"<<intOne<<endl;
cout<<"intTwo:"<<intTwo<<endl;
cout<<"rInt:"<<rInt<<endl;
cout<<"intOne:"<<&intOne<<endl;
cout<<"intTwo:"<<&intTwo<<endl;
cout<<"rInt:"<<&rInt<<endl;
}
答案:
intOne:5
rInt:5
intOne:8
intTwo:8
rInt:8
intOne:0x28fea8
intTwo:0x28fea4
rInt:0x28fea8
三、什么能被引用呢?
1.引用是变量的别名,不能使用常量初始化引用
如何用常量初始化引用呢?
①:int temp=10;
const int &a=temp;
②:const int &a=10;
2.指针变量的引用
eg:
int* a;
int b=8;
int* &p=a;//表示int*的引用p初始化为a,&为引用说明符
p=&b;//p是a的别名,也是一个指针,&为取地址符
3.错误的引用
①建立void类型的引用
②建立引用的数组 int &ra[3]={1,2,3};
可以建立数组的引用:int a[3]={1,2,3};int (&ra)[3]=a;
③建立引用的引用 int &&ra;
④建立指向引用的指针 int& *p=&ra;
⑤用类型或NULL初始化 int &ra=int;int &ra=NULL;
四、引用的应用
1.用引用传递函数参数
- 引用的主要作用是用来做函数的参数或函数的返回值
- 引用做函数的形参,实际上是在被调函数中对实参变量进行操作
-
引用作为形参,实参是变量而不是地址,与指针变量做形参不同
void swap(int &x,int &y)//形参为整型引用 { int t; t=x;x=y;y=t; } int main() { int a=3,b=5; swap(a,b);//实参为变量 cout << a << " " << b << endl; } void swap(int *x,int *y)//形参为指针变量 { int t; t=*x;*x=*y;*y=t; } int main() { int a=3,b=5; swap(&a,&b);//实参为地址 cout << a << " " << b << endl; }
2.返回多个值:
函数只能返回一个值,但是我们可以用引用给函数传递多个参数,然后由函数往目标中填入正确的值,因为引用传递允许函数改变原来的变量值,所以除函数本身的返回值,实际上也返回了被引用变量的值。
#include<bits/stdc++.h>
using namespace std;
bool Factor(int n,int &rSquared,int &rCubed)
{
if(n>20||n<0)
return true;
else
{
rSquared=n*n;
rCubed=n*n*n;
}
return false;
}
int main()
{
int number,squared,cubed;
cout << "Enter a number(0~20):";
cin >> number;
bool error=Factor(number,squared,cubed);
if(error)
cout << "Error ecountered!\n";
else
{
cout << "Number:" << number << endl;//函数返回值
cout << "Squared:" << squared << endl;//引用值
cout << "Cubed:" << cubed << endl;//引用值
}
return 0;
}
答案:
Enter a number(0~20):10
Number:10
Squared:100
Cubed:1000
3.引用作为函数的返回值
- 函数返回值时,要生成一个值的副本,而引用返回值时,不生成值的副本
- 语法:<类型> &<函数名>(<形参列表>){<函数体>}
- 必须在定义函数时在函数名前加引用说明符&
-
返回的变量的引用,这个变量必须是全局变量或静态局部变量(避免引用变量内存被释放后引用无所指)
补充:C++的内存格局
全局数据区 | 全局变量,静态(static)数据(全局与局部),常量及字面量 |
代码区 | 所有类成员函数和非成员函数代码 |
堆区(自由存储) | 动态分配内存空间 |
栈区 | 为运行函数而分配的局部变量、函数参数、返回数据、返回地址等 |
引用返回的四种类型:
#include<bits/stdc++.h>
using namespace std;
float temp;//全局变量
float fn1(float r)
{
temp=r*r*3.14;
return temp;
}
float &fn2(float r)
{
temp=r*r*3.14;
return temp;
}
int main()
{
float a=fn1(5.0);//函数返回值
const float &b=fn1(5.0);//用函数返回值初始化引用
float c=fn2(5.0);//引用作为函数的返回值
float &d=fn2(5.0);//用函数返回的引用作为新引用的初始化值
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
}
答案:
78.5
78.5
78.5
78.5
4.函数返回的引用作为赋值表达式的左值:
一般来说函数不能作为左值,但是如果将引用作为函数的返回值,因为返回的是一个变量的别名,就可以将函数放在左边,即给这个变量赋值
#include<iostream>
using namespace std;
int value[10];//返回的引用所对应的变量一定要是全局变量,不能是在函数体内定义的局部变量
int error=-1;
int &func(int n)
{
if(n>=0&&n<=9)
return value[n];
else
return error;
}
int main()
{
func(0)=10;
func(4)=12;
cout << value[0] << endl;
cout << value[4] << endl;
}
答案:
10
12
五、用const限定引用
传递引用的目的是提高程序的运行效率,但是会使所传参数存在随时被修改的风险
保证实参不被修改的办法是传递const引用
语法:const<类型>&<引用名>=<被引用变量名>;
不允许通过常引用对其所对应的变量或对象进行修改
eg:
const int &ra=a;
ra=11;这样的表达是不对的哦!
六、返回堆中变量的引用
可以用动态分配的内存空间来初始化一个引用变量
double &rd=*new double;//用new动态分配一个堆空间,取别名为rd
delete rd;//用delete释放空间内存
补充:
一、引用与指针的区别:
1.指针是变量,引用不是变量,它本身没有值和地址值
2.指针可以引用,而引用不可以引用
3.指针可以作数组元素,而引用不可以
4.可以有空指针,但是不可以有空引用
5.引用可以用指针代替,但指针不能完全被引用代替;但是引用比指针安全
二、函数的参数传递
1.值传递
将主调函数中的实参值传递给被调函数的形参
特点:
①:无论形参如何改变都不影响实参
②:单向数据传递机制,只能将数据从主调函数单向传递给被调函数
③:实参可以是常量、变量或表达式
2.引用传递
传递实参变量的引用
被调函数的形参需要定义成引用变量
特点:
①:被调函数通过该引用间接访问主调函数中的变量
②:双向数据传递机制
③:实参必须是变量
3.指针传递
传递实参变量的内存地址,被调函数通过该地址间接访问主调函数中的变量,从而达到传递数据的目的
被调函数的形参需要定义成指针变量,以接收实参变量的内存地址
特点:
①:被调函数通过内存地址间接访问主调函数中的变量
②:双向数据传递机制
③:实参必须是指针变量或指针表达式
okk,结束啦!!!谢谢大家驻足,下次见!