引用变量

c++新增了一种复合类型--引用变量。引用是已定义的变量的别名。(面试或笔试中也会常问道引用和指针的区别)常将引用变量用作函数的形参,函数将使用原始数据,而不是其拷贝,这点是不是和指针很像,确实很像,但同时又不同,让我们来具体看一看

        c和c++中使用&符号来指示变量的地址。c++给&符号赋予了另一个含义,将其用来声明引用。例如,要将rodents作为rats变量的别名,可以这样做:

int rats;
int &rodents = rats;

上述引用声明允许将rats和rodents互换,他们指向相同的值和内存单元。

看一个简单的例子

#include <iostream>
int main()
{
        using namespace std;
        int ret = 100;
        int & result = ret;

        cout << "ret:" << ret << endl;
        cout << "result:" << result << endl;

        result++;

        cout << "ret:" << ret << endl;
        cout << "result:" << result << endl;


        cout << "ret address:" << &ret << endl;
        cout << "result address:" << &result << endl;

        return 0;
}

运行结果

在代码中要区别一下&符号的使用,一个是声明引用的时候和另一个是取地址的时候。从结果中可以看出,ret和result的值和地址都是一样的。并且,result++使两个值都变化了。

引用看起来和指针很像,但还是有很多不一样的地方

1、引用必须在声明的时候就初始化,指针在初始化的可以不初始化。

2、使用的时候不一样,引用使用时和普通变量一样,例如上面的result,result本身就是表示value,而如果时地址的话则要通过* 来解除地址,再比如,下面这种情况

#include <iostream>                                                                                                                                              
using namespace std;
struct stu{
        char name[10];
        int height;
};
int main()
{
        struct stu stu1 = {"xiaoming",178};
        struct stu & stu2 = stu1;
        struct stu *stu3 = &stu1;

        cout << "name: "<< stu1.name <<" height:" << stu1.height << endl;
        cout << "name: "<< stu2.name <<" height:" << stu2.height << endl;
        cout << "name: "<< stu3->name <<" height:" << stu3->height << endl;
}

结果:

结构体时,引用还是用“.”来获取结构体内成员,指针则是用"->"来获取。所以回到本文的第一句话引用是已定义的变量的别名,它确实只是已定义变量的一个其他的名字,使用上方法上和这个变量时一模一样的

引用更接近于const指针,必须在创建的时候初始化,一旦与某个变量关联起来,就将一直效忠于他。

int & result = res;

相当于

int * const reset = &res;

我们来看一个例子

#include <iostream>                                                                                                                                              
int main()
{
        using namespace std;
        int ret = 100;
        int & result = ret;

        cout << "ret:" << ret << endl;
        cout << "result:" << result << endl;

        result++;

        cout << "ret:" << ret << endl;
        cout << "result:" << result << endl;


        cout << "ret address:" << &ret << endl;
        cout << "result address:" << &result << endl;
    
        int bus = 55; 
        result = bus;

        cout << "result" << result << endl;
        cout << "ret:" << ret << endl;
        cout << "bus:" << bus << endl;
        cout << "result address:" << &result << endl;
        cout << "ret address:" << &ret << endl;
        cout << "bus address:" << &bus << endl;
        return 0;
}

虽然我们启动修改引用result关联的变量,但是我们发现,尽管result打印的值发生了变化,但实际上,ret值也发生了变化,所以让一个引用指向另一个变量时,只会改变引用指向地址处的值,引用指向的地址时不会发生变化的。

简而言之,可以通过初始化声明来设置引用,但不能通过赋值。

再来看一个例子

#include <iostream>                                                                                                                                              
int main()
{
        using namespace std;
        int ret = 100;
        int *pt = &ret;
        int & result = *pt;

        cout << "ret:" << ret << endl;
        cout << "result:" << result << endl;

    
        int bus = 55; 
        pt = &bus;

        cout << "result:" << result << endl;
        cout << "ret:" << ret << endl;
        cout << "bus:" << bus << endl;
        cout << "result address:" << &result << endl;
        cout << "ret address:" << &ret << endl;
        cout << "bus address:" << &bus << endl;
        return 0;
}
~  

result引用关联了pt,pt指向的ret的地址,尽管pt后面指向了bus,但是result仍然时关联的ret.

 

引用变量经常被用作函数参数,使得函数中的变量名成为调用程序中的变量别名。这种传递参数的方法称为按引用传递。现在在c++中有了三种传递参数的方法,按值传递,按引用传递,按地址传递。我们通过下面一个程序来比较一下三者的区别。程序的作用是交换传递的两个参数的值


#include <iostream>
void swapr(int & a, int & b) // reference
{
        int tmp;
        tmp = a;
        a = b;
        b = tmp;
}
void swapv(int a, int b)     //value
{
        int tmp;
        tmp = a;
        a = b;
        b = tmp;

}
void swapp(int *a, int *b)   //address
{
        int tmp;
        tmp = *a;
        *a = *b;
        *b = tmp;
}



int main()
{
        using namespace std;
        int wallet1 = 300;
        int wallet2 = 500;

        cout << "wallet1: " << wallet1;
        cout << " wallet2: " << wallet2 << endl;

        cout << "using references to swap"<< endl;
        swapr(wallet1,wallet2);
        cout << "wallet1: " << wallet1;
        cout << " wallet2: " << wallet2 << endl;

        cout << "using pointers to swap"<< endl;
        swapp(&wallet1,&wallet2);
        cout << "wallet1: " << wallet1;
        cout << " wallet2: " << wallet2 << endl;

        cout << "using value to swap"<< endl;
        swapv(wallet1,wallet2);
        cout << "wallet1: " << wallet1;
        cout << " wallet2: " << wallet2 << endl;
        return 0;
}

执行结果:

从执行的结果可以看出:按地址和按引用传递,都可以改变这两个值,按值传递不能改变,从使用上来讲,按值传递和按引用传递在调用时的形态是一样,我们只能从函数的定义上才能区分出是按值传递还是按引用传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值