当前位置: 首页 > news >正文

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;
}

输出:

相关文章:

  • python装饰器的详解使用
  • 深入理解 Java 接口的回调机制 【学术会议-2025年人工智能与计算智能(AICI 2025)】
  • qt5实现表盘的旋转效果,通过提升QLabel类
  • 深入解析:在Spring Boot中集成MyBatis Plus实现高效数据库操作
  • 欢乐力扣:同构字符串
  • antv G6绘制流程图
  • 网络运维学习笔记 019 HCIA-Datacom综合实验03
  • 各种硬件模块
  • lattice hdl实现spi接口
  • RoCEv2 高性能传输协议与 Lossless 无损网络
  • 深入理解设计模式之代理模式
  • 基于 DeepSeek + Gemeni 打造 AI+前端的多人聊天室
  • Ollama 部署大模型
  • Java 集合:单列集合和双列集合的深度剖析
  • 基于Flask的去哪儿网海南旅游攻略数据分析系统的设计与实现
  • 2025吐槽季第一弹---腾讯云EO边缘安全加速平台服务
  • Graspness Discovery in Clutters for Fast and Accurate Grasp Detection 解读
  • RoCBert:具有多模态对比预训练的健壮中文BERT
  • 细说STM32F407单片机2个ADC使用DMA同步采集各自的1个输入通道的方法
  • 【开源免费】基于SpringBoot+Vue.JS物流管理系统(JAVA毕业设计)
  • 绿城约13.93亿元竞得西安浐灞国际港港务片区地块,区内土地楼面单价首次冲破万元
  • 定位真核生物起源于约27.2亿年前,华东师大团队在《自然》发文
  • 自然资源部印发地理信息数据分类分级指南
  • 潘功胜:坚定支持汇金公司在必要时实施对股票市场指数基金的增持
  • A股三大股指集体高开大涨超1%,券商、房地产涨幅居前
  • 老人刷老年卡乘车被要求站着?公交公司致歉:涉事司机停职