C++核心编程之引用
1 引用的基本使用
作用: 给变量起别号
语法: 数据类型 &别名 = 原名
基本实例代码如下:
#include<iostream>
using namespace std;
int main()
{
// 引用的基本语法
// 数据类型 &别名 = 原名
int a = 10;
// 根据引用的语法--》创建引用
int &b = a;
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
b = 100;
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
system("pause");
return 0;
}
运行结果:
分析:首先,将10赋值给a,也就是分配一个地址,该地址存放的内容为10。其次,将a的别名起成b,也就是b也指向这个地址,内容仍然为10。因此,a和b都指向相同地址,因此,a和b都为10。如果将b=100,也就是将该地址存放的内容修改成100,那么,a和b指向的地址不变,地址存放的内容变化,则输出的内容也相对应变化。因此,最后a和b的内容都为100(a=b=100)。
2 引用的注意事项
注意事项1:引用必须初始化
注意事项2:引用在初始化后,就不可以改变
基本实例代码如下:
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 100;
//int &c; //错误,引用必须初始化
int &c=a; //一旦初始化后,就不可以更改
c=b; //这个“=”是赋值操作,而不是更改引用
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
cout<<"c= "<<c<<endl;
system("pause");
return 0;
}
运行结果:
分析:a赋值为10,b赋值为100,将a起别名为c,也就是说a和c同时指向同一个地址(内容为10)。其次,将b的内容赋值给c,也就是c=b=100。接着,c和a同时指向同一地址,c=100,那么,a也为100。最后,输出的a、b、c都为100。
3 引用做函数参数
作用:函数传参时,可以利用引用的技术让形参修饰实参
优点:可以简化指针修改实参
#include<iostream>
using namespace std;
// 交换函数的3种传递方式
// 1.值传递 形参不会修饰实参
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout<<"swap01 a= "<<a<<endl;
cout<<"swap01 b= "<<b<<endl;
}
// 2.指针传递 形参会修饰实参
void swap02(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
cout<<"swap02 a= "<<*a<<endl;
cout<<"swap02 b= "<<*b<<endl;
}
// 3.引用传递 形参会修饰实参
void swap03(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
cout<<"swap03 a= "<<a<<endl;
cout<<"swap03 b= "<<b<<endl;
}
int main()
{
int a = 99;
int b = 101;
// swap03(a, b);
// swap02(&a, &b);
swap03(a, b);
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
system("pause");
return 0;
}
运行结果:
分析:通过引用参数产生的效果同按地址传递是一样的。就是将a和b换一种别名而已。
4 引用做函数返回值
作用:引用可以作为函数的返回值存在的
用法:函数调用作为左值
注意:不要作为局部变量引用
#include<iostream>
using namespace std;
// 引用作为函数的返回值
// 1.不要返回局部变量的引用
int& test01()
{
int a = 100; // 局部变量存放在四区中的 栈区
return a;
}
// 2.函数的调用可以作为左值
int& test02()
{
static int a = 100; // 静态变量存放在四区中的 全局区,数据在程序运行结束后自动释放
return a;
}
int main()
{
// int &out1 = test01(); // 不要返回局部变量的引用, 本地输出报错,为NULL
// cout<<"out1= "<<out1<<endl;
int &out2 = test02();
cout<<"out2= "<<out2<<endl;
test02() = 1; // 如果函数返回值是引用,则这个函数调用可以作为左值
cout<<"out2= "<<out2<<endl;
system("pause");
return 0;
}
运行结果:
5 引用的本质
本质:在C++内部实现是一个指针常量。
#include<iostream>
using namespace std;
// 引用的本质:引用转换为int* const ref = &a;
void func(int& ref)
{
ref = 10; // ref是引用,转换为*ref = 10
}
int main()
{
int a = 1000;
// 自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改
int& ref = a;
ref = 200; // 内部发现ref是引用,自动转换为:*ref = 200;
cout<< "a= "<< a << endl;
cout<< "ref= "<< ref<<endl;
func(a);
system("pause");
return 0;
}
输出:
a= 200
ref= 200
请按任意键继续. . .
分析:
- 首先,取一个内存地址(假设0x0100),存放1000,并且由变量a来操作
- 其次,int& ref = a;内部就是自动创建一个指针,由ref指向存放1000的地址0x0100
- 接着,ref=10;自动转换为*ref = 200,也就是ref解引用后的内容赋值为200
- 最后,a和ref的内容都为200,因为0x0100地址存放的内容为200
结论:C++推荐使用引用技术,语法方便,引用本质就是指针常量,但是所有的指针操作编译器都自动做了。
6 常量引用
作用:常量引用主要用来修饰形参,防止误操作
在函数形参列表中,可以加const修饰形参,防止形参改变实参
#include<iostream>
using namespace std;
// 打印数据
// 加入const 修饰形参,防止误操作
void printValue(const int &value)
{
// value = 100; // 会报错
cout<<"value = "<< value<< endl;
}
int main()
{
// 常量引用
// 作用:修饰形参,防止误操作
// int a = 10;
// int &ref = 10; // 引用必须引一块合法的内存空间 ,这里会报错
// 加上const之后编译器将代码修改 int temp=10; int &ref = temp;
// const int &ref = 10;
// ref = 100; // 加入const之后为只读,不可以修改
int a = 1000;
printValue(a);
cout<<"a = "<<a<< endl;
system("pause");
return 0;
}
输出: