C++引用

引用的概念

引用的作用是为变量创建一个别名,使得通过这个别名可以直接操作原变量。引用的概念类似于Linux中的硬链接。任何对于引用的操作,实际上都是对原变量的操作。

示例

int a = 10;
int &r = a;  // r 是 a 的引用
r = 20;      // 修改 r 的值会影响 a

基本语法

引用使用  &  作为标识符

格式:数据类型 &引用名 = 引用的目标

例如:

        int a =10;

        int &r = a;        //定义一个int类型的引用,引用变量a

引用的本质

引用的本质是 C++ 内部实现的 指针常量。因此,引用与指针有着相似之处,但它是更高层次的抽象,提供了更方便的操作方式。

定义引用时需要注意以下几点:

  • 引用必须初始化

               定义引用时,必须为其指定一个初始化目标。

int a = 10;
int &r = a;  // r 必须在定义时初始化
  • 引用的类型与目标类型必须一致

        引用的类型必须与它所引用的变量类型保持一致。(继承和多态除外)

int a = 10;
int &r = a;  // 类型一致
  • 引用不可更改目标

        一旦引用绑定到一个变量上,不能再更改其引用的目标。

引用作为函数参数

作用

       函数传参时,可以利用引用的技术让形参修饰实参

优点

        可以简化指针修改实参

示例

#include "iostream"


using namespace std;
// 值传递
void func_swap_01(int val_1 , int val_2){
    int temp = val_1;
    val_1 = val_2;
    val_2 = temp;
}

// 值传递
void func_swap_02(int *val_1 , int  *val_2){
    int temp = *val_1;
    *val_1 = *val_2;
    *val_2 = temp;
}

// 值传递
void func_swap_03(int &val_1 , int &val_2){
    int temp = val_1;
    val_1 = val_2;
    val_2 = temp;
}


int main()
{
    int val_1 = 10;
    int val_2 = 20;

    func_swap_01(val_1, val_2);
    cout << "val_1 = " << val_1 << " val_2 = " << val_2 << endl;

    func_swap_01(val_1, val_2);
    cout << "val_1 = " << val_1 << " val_2 = " << val_2 << endl;

    func_swap_01(val_1, val_2);
    cout << "val_1 = " << val_1 << " val_2 = " << val_2 << endl;

}

示例结果
val_1 = 10 val_2 = 20
val_1 = 10 val_2 = 20
val_1 = 10 val_2 = 20

引用与指针

用法

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

typedef struct Node {
	int data;
	struct Node* next;
}Node;

void create_node(Node * &p)
{
	p = (Node*)malloc(sizeof(Node));
	p->data = 100;
	p->next = nullptr;
}

int main()
{
	Node* list = nullptr;
	create_node(list);
    
    cout << list->data << endl;
}

引用与返回值

我们平时使用函数时,函数的返回值都是一个右值。

但是引用作为函数的返回值时,返回值是一个左值。

  • 左值

既可以放在等号左边,也可以放在等号右边的值。

  • 右值

只能放在等号右边的值。

引用作为函数的返回值,不能返回局部变量的引用,因为局部变量在函数调用结束时就被回收了。

可以返回全局变量的引用或者 static 修饰的局部变量的引用。

示例1

#include <iostream>
using namespace std;

// 返回静态局部变量的引用
int &my_add(const int &x, const int &y) {
    static int temp = x + y;  // 静态局部变量
    return temp;  // 返回 temp 的引用
}

// 返回全局变量 value 的引用
int value = 100;
int &func() {
    return value;  // 返回 value 的引用
}

int main() {
    // 返回 temp 的引用
    int &r1 = my_add(10, 20);  // r1 绑定到 temp
    cout << r1 << endl;  // 输出 30

    // 返回全局变量 value 的引用
    int &r2 = func();  // r2 绑定到 value
    cout << r2 << endl;  // 输出 100

    // 修改 value 的值
    r2 = 200;
    cout << value << endl;  // 输出 200

    // 通过 func() 修改 value
    func() = 300;
    cout << value << endl;  // 输出 300

    return 0;
}

示例2

#include <iostream>

int& getElement(int arr[], int index) {
    return arr[index];  // 返回数组元素的引用
}

int main() {
    int numbers[] = {10, 20, 30, 40, 50};

    // 将getElement返回的引用作为左值
    getElement(numbers, 2) = 100;  // 修改索引为2的元素

    // 输出修改后的数组
    for (int i = 0; i < 5; ++i) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

引用与结构体

当结构体中包含引用时,定义结构体的对象时,必须对引用进行初始化。由于引用必须在创建时绑定到某个变量,因此不能延迟初始化。

1、引用结构:

2、结构体内部有引用:

初始化方式

MyStruct T1 = { .valur = 20 , .ref = val };  // 错误的写法,不能使用初始化列表的指定成员
MyStruct T1 = { 20 , val };  // 正确的写法,必须按照结构体成员顺序进行初始化

代码示例

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

struct MyStruct {
	int valur;   // 普通成员
	int &ref;    // 引用成员,必须在初始化时绑定
};

int main() {
	int val = 10;  // 用于初始化引用的变量
	MyStruct T1 = { 20, val };  // 初始化结构体,包括引用成员
	val = 20;  // 修改引用绑定的变量的值
	cout << T1.ref << endl;  // 输出 20,因为引用指向 val
}

 引用与常量

 const 修饰引用时,它被称为常引用。常引用的作用是禁止通过引用来修改其引用的目标变量。

作用:防止对引用目标的错误修改,保护数据的完整性。

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

int func_Add(const int &val_1, const int &val_2) {
    return val_1 + val_2;
}

int main() {
    // 变量
    int val = 10;
    // 引用 常量引用
    cosnt int &ref = val;

// 常量引用 引用变量
    cout << "ref = " << ref << endl;

// 常量引用 作为参数
    int val_1 = 80;
    int val_2 = 80;
    cout << "val_1 + val_2 = " << func_Add(val_1, val_2) << endl;

// 常用引用 引用常量
    // int & ref_1 = 10;  // 不使用常量引用是不能引用常量的
    const int & ref_1 = 10;

    const int val_3 = 50;

    // int & ref_2 = val_3;  // 不使用常量引用是不能引用const 所修饰的常量
    const int & ref_2 = val_3;

// 常量引用 引用临时值
    // int & ref_3 = val_1 + val_2;  // 不使用常量引用是不能引用临时值的
    const int & ref_3 = val_1 + val_2;

}

 引用和指针的区别

要记,面试会问

1、引用必须初始化,指针可以不初始化。
2、引用不可以改变指向,指针可以。
3、不存在指向 NULL 的引用,指针可以指向 NULL。
4、指针在使用前需要检查合法性,引用不需要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值