携手创作,一起成长!这是我参与「日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
引证
引证的根本运用
效果: 给变量起别号
语法: 数据类型 &别号 = 原名
示例:
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;
}
引证注意事项
- 引证必须初始化
- 引证在初始化后,不能够改动
示例:
int main() {
int a = 10;
int b = 20;
//int &c; //过错,引证必须初始化
int &c = a; //一旦初始化后,就不能够更改
c = b; //这是赋值操作,不是更改引证
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
system("pause");
return 0;
}
引证做函数参数
效果: 函数传参时,能够运用引证的技术让形参润饰实参
长处: 能够简化指针修正实参
示例:
//1. 值传递
void mySwap01(int a, int b) {
int temp = a;
a = b;
b = temp;
}
//2. 地址传递
void mySwap02(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
//3. 引证传递
void mySwap03(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
mySwap01(a, b);
cout << "a:" << a << " b:" << b << endl;
mySwap02(&a, &b);
cout << "a:" << a << " b:" << b << endl;
mySwap03(a, b);
cout << "a:" << a << " b:" << b << endl;
system("pause");
return 0;
}
总结:经过引证参数产生的效果同按地址传递是一样的。引证的语法更清楚简略
PS:值传递与地址传递的回忆:
值传递
- 所谓值传递,便是函数调用时实参将数值传入给形参
- 值传递时,==如果形参产生,并不会影响实参==
示例:
void swap(int num1, int num2)
{
cout << "交流前:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交流后:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
//return ; 当函数声明时分,不需求回来值,能够不写return
}
int main() {
int a = 10;
int b = 20;
swap(a, b);
cout << "mian中的 a = " << a << endl;
cout << "mian中的 b = " << b << endl;
system("pause");
return 0;
}
总结: 值传递时,形参是润饰不了实参的
地址传递
效果: 运用指针作函数参数,能够修正实参的值
示例:
//值传递
void swap1(int a ,int b)
{
int temp = a;
a = b;
b = temp;
}
//地址传递
void swap2(int * p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
int a = 10;
int b = 20;
swap1(a, b); // 值传递不会改动实参
swap2(&a, &b); //地址传递会改动实参
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
总结:如果不想修正实参,就用值传递,如果想修正实参,就用地址传递
引证传递
能够润饰实参。实质:接纳(int *const a ,int * const b) 传入(&a,&b),编译器主动把辨认引证所以运用引证时只传入(a,b)即可。
注意:别号能够和原名相同
引证做函数回来值
剖析
效果:引证是能够作为函数的回来值存在的
注意:不要回来局部变量引证
用法:函数调用作为左值
示例
//回来局部变量引证
int& test01() {
int a = 10; //局部变量
return a;
}
//回来静态变量引证
int& test02() {
static int a = 20;
return a;
}
int main() {
//不能回来局部变量的引证
int& ref = test01();
cout << "ref = " << ref << endl;//第一次结果正确,编译器做了保存
cout << "ref = " << ref << endl;//第2次可能会输出乱码
//如果函数做左值,那么必须回来引证
int& ref2 = test02();
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;
test02() = 1000;
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;
system("pause");
return 0;
}
解析:回来值类型后边加上and符int&相当于用引证的方式回来数据。如下图例子回来的是a的一个别号,再用一个别号ref去接纳函数回来的别号,最终ref是a的一个别号。
上图结果:第2次输出便是乱码了,编译器不再保存改函数栈区数据a的地址!
可是加上static要害字后数据性质就不一样了,静态变量存贮与静态区,程序运行后开释!
能够作为左值便是能够进行和变量一样的操作,编译器不会报错。
PS:上图案例刨析
案例剖析:函数回来值不能回来局部变量的引证 类比于 不能回来局部变量的地址
旧知识回忆:不能回来局部变量的地址
栈区:
由编译器主动分配开释, 寄存函数的参数值,局部变量等
注意事项:不要回来局部变量的地址,栈区拓荒的数据由编译器主动开释
示例:
int * func()
{
int a = 10;
return &a;
}
int main() {
int *p = func();
cout << *p << endl;//第一次编译器可能会保存
cout << *p << endl;//第2次直接会报错!取决于编译器。
system("pause");
return 0;
}
引证的实质
剖析
实质:引证的实质在c++内部实现是一个指针常量(指针指向不行改).
讲解示例:
//发现是引证,转换为 int* const ref = &a;
void func(int& ref){
ref = 100; // ref是引证,转换为*ref = 100
}
int main(){
int a = 10;
//主动转换为 int* const ref = &a; 指针常量是指针指向不行改,也说明为什么引证不行更改
int& ref = a;
ref = 20; //内部发现ref是引证,主动帮咱们转换为: *ref = 20;
cout << "a:" << a << endl;
cout << "ref:" << ref << endl;
func(a);
return 0;
}
结论:C++推荐用引证技术,由于语法便利,引证实质是指针常量,可是一切的指针操作编译器都帮咱们做了
图析
int * const ref = &a;指针常量,地址不能够改动,值能够改动,即引证的地址不能够改动,即引证不行更改
旧知回忆
引证注意事项
- 引证必须初始化
- 引证在初始化后,不能够改动
常量引证
效果: 常量引证首要用来润饰形参,避免误操作
在函数形参列表中,能够加==const润饰形参==,避免形参改动实参
示例:
//引证运用的场景,一般用来润饰形参
void showValue(const int& v) {
//v += 10;
cout << v << endl;
}
int main() {
//int& ref = 10; 引证自身需求一个合法的内存空间,因而这行过错
//参加const就能够了,编译器优化代码,int temp = 10; const int& ref = temp;
const int& ref = 10;
//ref = 100; //参加const后不能够修正动量
cout << ref << endl;
//函数中运用常量引证避免误操作修正实参
int a = 10;
showValue(a);
system("pause");
return 0;
}
参加const表明只读不行修正,避免误操作
实例刨析
已然引证的实质是指针,那咱们能够运用指针的性质来进行一些实验性操作,见上图的demo1-demo3
多状况运用场景
demo1地址和值都不能够修正
只读不行修正,避免误操作
demo2指针常量,地址可变,值不行变
用于在函数体内给函数体外的变量替换别号,且别号只在函数体内有用
demo3常量指针,地址不变,值能够变
正常的值传递,能够简化指针值传递的繁琐操作