目录
引用的基本使用
作用:给变量起别名
语法:数据类型 &别名=原名
示例:
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;
return 0;
}
引用b是a的别名
引用的底层是指针
引用注意事项
·引用必须初始化
·引用在初始化后,不可以改变
·引用不可以初始化为空
示例:
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;
return 0;
}
输出10 20 20
int &c=a;
同时把c给定义了
引用做函数参数
作用: 函数传参时,可以利用引用的技术让形参和实参代表的是同一块内存
优点: 可以简化指针修改实参
示例:
#include<iostream>
using namespace std;
//1.值传递
void Swap01(int a, int b) {
int temp = a;
a = b;
b = temp;
}
//2.地址传递
void Swap02(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
//3.引用传递
void Swap03(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
Swap01(a, b);
cout << "a:" << a << " b:" << b << endl;
Swap02(&a, &b);
cout << "a:" << a << " b:" << b << endl;
Swap03(a, b);
cout << "a:" << a << " b:" << b << endl;
return 0;
}
总结: 通过引用参数产生的效果同按地址传递是一样的。引用的语法更清楚简单
引用作函数返回值
作用: 引用是可以作为函数的返回值存在的
注意: 不要返回局部变量引用
用法: 函数调用作为左值
示例:
#include<iostream>
using namespace std;
/*
如果返回值是引用类型的则返回的是变量本身
如果返回值是值类型,则返回的是副本*/
int& test01() {
int a = 10;
return a;
}
int &b=test01();//被优化了 实际上是随机值
/*test01 函数定义了一个局部变量 a,并返回它的引用。
由于 a 是局部变量,当 test01 函数结束时,a 的生命周期也结束,
a 的内存将被释放。
如果在 main 函数中尝试使用 test01 的返回值
(如通过引用赋值),
将会导致未定义行为,
因为返回的引用指向一个已经被释放的内存区域。*/
int& test02() {
static int a = 10;
return a;
}
test01没有&值类型
int &b=test02();
a要消失 给b拷贝副本给他初始化
b拷贝的是值 然后给b 拷贝一个副本
引用返回 引用接收 可能出现问题 a会随着函数的结束释放
不用引用接收 就没问题了
int main() {
// int& b = test01(); // 可能会出现问题,a 会随着函数的结束被释放
int b1 = test01(); // 不会出现问题,因为这里是值拷贝
int& c = test02(); // c 是 test02 返回的静态变量 a 的引用
test02() = 3; // 修改静态变量 a 的值为 3
左值右值
左值一般是非常量 右值一定是常量
test01返回a本身 左值
删掉&就是右值 因为返回a的副本 副本没有名字
// test01() = 3; // 没有意义,因为 a 会被释放
删掉&后再进行操作就会报错 因为副本没有名字 不是可修改的左值 右值不可修改
cout << c << endl; // 输出 c 的值,即静态变量 a 的值,应该是 3
return 0;
}
左值&右值引用
#include<iostream>
using namespace std;
int fun()
{
int a=2;
return a;
}
int& work()
{
int a=2;
return a;
}
int main()
{
/*
左值:有名字的是左值
右值:没有名字的是右值
左值引用:左值引用只能引用左值
右值引用:右值引用只能引用右值
*/
int a=2;
int& b=a;//左值引用
//int& b1=3;// error 左值引用只能引用左值
int&& c=2;//右值引用
//int&& c1= a;// erro 右值引用只能引用右值
int && d= fun();//fun 函数返回类型为引用,返回的不是副本
int &f= work();//返回的副本没有名字为右值
//万能引用 :左值引用被 const修饰就是万能引用,既能引用左值也能引用右值
const int& g=2;
const int& g1=a;
//g=3;//erro 被 const 修饰了不能修改
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++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了
思考题:
如果一个变量被const修饰,const int a,什么样的指针才能指向a?
在C++中,如果一个变量被`const`修饰,例如`const int a`,那么它的值是不可修改的。为了能够指向这个常量变量`a`,你需要使用一个指向常量的指针。具体来说,指针的类型应该是`const int*`。
### 具体示例```cpp
#include <iostream> using namespace std; int main() { const int a = 10; // 定义一个常量整型变量a // 指向常量的指针 const int* ptr = &a; // ptr是一个指向const int的指针,指向a cout << "a: " << a << endl; // 输出a的值 cout << "*ptr: " << *ptr << endl; // 输出ptr指向的值 // *ptr = 20; // 这行代码会导致编译错误,因为ptr指向的是const int,不能修改 return 0; }
```### 指针类型解释
1. **`const int* ptr`**:这是一个指向`const int`的指针,意味着你可以通过`ptr`读取`a`的值,但不能通过`ptr`修改`a`的值。
2. **`int* const ptr`**:这是一个常量指针,指针本身是常量,不能改变指向的地址,但可以通过这个指针修改所指向的值。如果你尝试将它指向`const int`,编译器会报错,因为指向的值是不可修改的。
3. **`const int* const ptr`**:这是一个指向`const int`的常量指针,既不能改变指针的指向,也不能通过指针修改所指向的值。
### 总结
要指向一个`const int`类型的变量,应该使用`const int*`类型的指针。这样可以确保在指针的作用域内,不能通过指针修改所指向的常量变量的值。
总结:
C++中的引用是一个非常重要的概念,它提供了一种方便的方式来操作变量。以下是对C++引用的
总结:
### 1. 引用的定义
- 引用是一个变量的别名。通过引用,可以使用另一个名字来访问同一个变量。
- 引用的声明使用`&`符号,例如:`int& ref = a;`,这里`ref`是`a`的引用。
### 2. 引用的特点
- **别名**:引用必须在定义时初始化,并且一旦绑定到一个变量,就不能再改变引用的对象。
- **不占用额外内存**:引用通常不占用额外的内存空间,它只是一个别名,因此对性能影响较小。
- **可以用于函数参数**:引用可以作为函数参数传递,这样可以直接修改传入的变量,而不需要返回值。
### 3. 引用的使用场景
- **简化代码**:通过引用可以避免使用指针,简化代码的可读性。
- **避免复制**:在传递大型对象(如类或结构体)时,使用引用可以避免不必要的复制,提高程序性能。
- **实现操作符重载**:在重载操作符时,通常使用引用来避免复制对象。
### 4. 引用与指针的比较
- **语法简洁**:引用的语法更简洁,不需要解引用操作符(`*`)。
- **安全性**:引用在创建时必须初始化,且不能为`null`,这使得引用在使用时更安全。
- **不可重新绑定**:一旦引用绑定到一个变量,就不能再改变引用的指向,而指针可以随时改变指向的对象。
### 5. 常量引用
- 使用`const`关键字可以创建常量引用,例如:`const int& ref = a;`。常量引用允许对常量对象进行读取,但不允许修改其值。
### 示例代码
#include <iostream>
using namespace std;
void updateValue(int& ref) {
ref = 50; // 修改引用所指向的变量
}
int main() {
int a = 10;
int& ref = a; // ref是a的引用
cout << "Before: a = " << a << ", ref = " << ref << endl;
ref = 20; // 通过引用修改a的值
cout << "After ref = 20: a = " << a << ", ref = " << ref << endl;
updateValue(a); // 通过引用传递给函数
cout << "After updateValue: a = " << a << ", ref = " << ref << endl;
return 0;
}
### 总结
C++中的引用是一个强大的工具,它提供了对变量的别名,使得代码更简洁和易于维护。引用的使用可以提高性能,并且通过引用参数可以方便地在函数中修改变量的值。