C++:引用语法

本文是笔者在C++学习过程中,对引用语法的总结记录,如有不对的地方,欢迎大家指正!


一、 什么是引用

  引用(reference),是C++对C语言的一项扩充,作用是给变量起别名,换句话说,就是将多个变量名指向同一个地址,从而使对其中的任意一个变量名的操作,都是对同一地址的操作。而在这种情况下,被声明为引用类型的变量名,就是实际变量名的一个别名。


二、引用的基本语法与注意事项

1、 声明语法

  引用的声明语法:数据类型 &引用变量名 = 原变量名;

eg:

#include <iostream>
using namespace std;

int main() {
    //语法:数据类型 &引用变量名 = 原变量名;
    int a=10;
    int &reference_a=a;

    cout<<"a="<<a<<endl;                     //a=10
    cout<<"reference_a="<<reference_a<<endl; //reference_a=10

    a+=10;
    cout<<"a="<<a<<endl; 					 //a=20
    cout<<"reference_a="<<reference_a<<endl; //reference_a=20

    reference_a+=10;
    cout<<"a="<<a<<endl; 					 //a=30
    cout<<"reference_a="<<reference_a<<endl; //reference_a=20
       
    return 0;
}

2、 注意事项

  1. 对引用进行操作,实际上就是对被引用的变量进行操作。

  2. 声明引用时,必须对其进行初始化。

  3. 引用在初始化之后,不可以再进行修改。

  4. 引用变量在编译器的底层实现是指针常量,即一个指针指向不可以发生更改的指针,所以引用占用内存空间的大小,和指针其实是一样的。

    但是,和指针不同的是,引用实际上不能算是一个变量,所以对引用变量求地址,与对实际变量求地址,结果是相同的。

#include <iostream>
using namespace std;

int main() {
    int a=10;
    int &reference_a=a;

    //对引用变量求地址,与对实际变量求地址,结果是相同的
    cout<<"对引用变量求地址"<<endl;
    cout<<"a的地址:"<<&a<<endl;
    cout<<"reference_a的地址:"<<&reference_a<<endl;
    
    return 0;
}

运行结果:
对引用变量求地址 运行结果

  1. 不能建立引用的数组,即数组中的元素不能是引用。因为引用使劲上并不能算是一个变量,所以在声明引用的数组时,并不能分配内存,也就无法声明和定义引用数组。

    但是,可以建立数组的引用,这是没有问题的。

#include <iostream>
using namespace std;

int main() {
    //不能建立引用的数组,但是,可以建立数组的引用
    int arr[]={0,1,2,3,4};
    // int &re_arr=&arr; 
    // 编译错误
    // error: invalid conversion from ‘int (*)[5]’ to ‘int’

    //数组的引用
    int (&re_arr)[5]=arr;

    return 0;
}

三、引用作为函数参数

  引用在C++中的一个重要作用,就是可以作为函数的参数使用。

  在C语言之中,函数参数传递使用的方法是值传递,而在有大量数据作为参数传递时,往往采用的是地址传递,即使用指针,来避免在函数调用时有大量数据压入栈中。现在,C++中可以使用引用作为函数参数,以此来代替指针作为函数参数,这种方法可以使代码更易阅读和维护。

eg:

#include <iostream>
using namespace std;

//引用作为函数参数
void fun1(int &a,int &b);

int main() {
    int a=10;
    int b=20;
    cout<<"a="<<a<<",b="<<b<<endl;
    fun1(a,b);
    cout<<"a="<<a<<",b="<<b<<endl;
    return 0;
}

//引用作为函数参数
void fun1(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

运行结果:
引用作为函数参数 运行结果

  可以看出,在使用引用作为函数参数时,与使用指针作为函数参数的效果一致,也就是在调用方法的时候,可以用形参修饰实参。


四、引用作为函数返回值

  C++支持将引用作为函数的返回值返回。

eg:

#include <iostream>
using namespace std;

//引用作为函数返回值
int& fun2(int &a);

int main() {
    int b=10;
    cout<<"fun2()前,b="<<b<<endl;
    cout<<"fun2()后,b="<<fun2(b)<<endl;
    return 0;
}

int& fun2(int &a){
    a*=a;
    return a;
}

运行结果:
引用作为函数返回值 运行结果

注意事项

1. 不要返回局部变量的引用

  因为局部变量是存放在栈区的,在函数返回后,局部变量就会被销毁,所以返回的引用就会像悬空指针一样,指向一个未知的空间。

eg:

#include <iostream>
using namespace std;

int& func2_local();

int main() {
    int &ref_locol=func2_local();
    
//    cout<<"ref_locol="<<ref_locol<<endl;			//编译错误
    cout<<"ref_locol的地址为:"<<&ref_locol<<endl;   //输出地址为0
    
    return 0;
}

// 不要返回局部变量的引用
int& func2_local(){
    int a=10;   //栈区,函数调用结束后释放
    return a;   //Reference to stack memory associated 
                // with local variable 'a' returned
}

运行结果:
不要返回局部变量的引用 运行结果

2. 函数调用可以作为左值

eg:

#include <iostream>
using namespace std;

int& func2_left();

int main() {
    int left=func2_left();
    cout<<"left="<<left<<endl;
    cout<<"func2_left()作为左值,修改为100"<<endl;
    func2_left()=100;
    cout<<"left="<<left<<endl;
    return 0;
}

//函数调用可以作为左值
int& func2_left(){
    static int a=10; //全局区,程序结束后由系统释放
    return a;
}

运行结果:
函数调用可以作为左值 运行结果

3. 不要返回函数内部使用 new 分配的内存的引用

  这种编程习惯是非常不好的,因为每个用 new 产生的指针都要调用 delete 释放,否则就会造成内存泄漏。而在被函数返回的引用作为一个临时变量时,我们很容易未对其进行释放,从而造成内存泄漏。

eg:

#include <iostream>
#include <string>
using namespace std;

string& func2_new();

int main() {
    string &str=func2_new();    //如果调用后没有用 delete 释放,就会造成内存泄漏
    cout<<"str="<<str<<endl;
    delete &str;                //释放
    return 0;
}
//不要返回函数内部使用 new 分配的内存的引用
string& func2_new(){
    string* str=new string("hello world");
    return *str;
}

  由代码可以看出,返回函数内部使用 new 分配的内存的引用时,极易引起内存泄漏,尤其是在形如以下代码的情况下:

string str="hello world"+func2_new();

五、常量引用/常引用

  声明方式:const 数据类型 &引用名 = 目标变量名;

eg:

#include <iostream>
using namespace std;

string& func3();

int main() {
    func3(a);
    return 0;
}

//常量引用/常引用
void func3(const int &a){
    cout<<"a="<<a<<endl;
}

  常引用主要用于修饰形参,防止函数中误操作。另外,在引用作为函数参数时应该尽量定义为 const 。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值