引用(基本使用 注意事项 函数参数 函数返回只 本质 左值引用 右值引用 万能引用 常量指针)

目录

引用

引用的基本使用

引用注意事项

引用做函数参数

引用作函数返回值

左值&右值引用

引用的本质


引用的基本使用

作用:给变量起别名

语法:数据类型 &别名=原名

示例:

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++中的引用是一个强大的工具,它提供了对变量的别名,使得代码更简洁和易于维护。引用的使用可以提高性能,并且通过引用参数可以方便地在函数中修改变量的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值