C++中的引用

引用(C++ 推荐 使用引用技术,因为语法方便。引用的本质是指针常量,但是所有的指针操作编译器都帮我们做了)

引用的基本使用

作用:给变量起别名(两个变量除了名字外是完全相同的)

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

 

#include <iostream>

#include <string>

using namespace std;

int main()

{

        int a = 10; // 原名

        int &b = a; // 引用(起别名)

        cout << "a = :" << a << endl;

        cout << "b = :" << b << endl;

        b = 1001; // 修改别名的内容

        cout << "a = :" << a << endl;

        cout << "b = :" << b << endl;

        system("pause");

        return 0;

}

运行结果:

 

引用的注意事项

1、引用必须初始化

解释:int &b; // 这就是错误的,因为没有经过初始化

2、引用在初始化后,不可以改变(只可以当一个变量的别名,不可以再改成其他变量的别名)

int &b = a;

int &b = c; // 错误,因为b已经是a的别名了,不可以被改成其他变量的别名

引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参(与形参是指针的作用相同)

优点:可以不使用指针来修改实参

#include <iostream>
#include <string>

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、引用传递(作用和2、地址传递作用相同)
void SWAP03(int &a, int &b) // 引用传递时,传进来的就是实参a和b“本身”(别名),而不是a、b的副本
{
	int temp = a;
	a = b;
	b = temp;
}

int main()
{
	int a = 10;
	int b = 20;

	SWAP01(a, b); // 1、值传递(形参不修饰实参)
	cout << "SWAP01 a = :" << a << endl;
	cout << "SWAP01 b = :" << b << endl;

	SWAP02(&a, &b); // 2、地址传递(形参会修饰实参)
	cout << "SWAP02 a = :" << a << endl;
	cout << "SWAP02 b = :" << b << endl;

	SWAP03(a, b); // 3、引用传递(形参会修饰实参,作用和2、地址传递一样)
	cout << "SWAP03 a = :" << a << endl;
	cout << "SWAP03 b = :" << b << endl;

	system("pause");
	return 0;
}

运行结果:

引用做函数的返回值

作用:引用可以作为函数的返回值存在

【注意】不要返回局部变量的引用(同“不要返回局部变量的地址”类似)

              函数调用还可以作为左值

#include <iostream>

#include <string>

using namespace std;

// 引用做函数的返回值

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

int& test01() // 引用的方式作为函数的返回

{

        int a = 10; //存放在栈区(函数执行完a就被释放)

        return a; // 返回局部变量(由于返回值类型为引用,所以这是在返回局部变量a的引用,也就是返回局部变量a的别名)

        // 注意这种操作是非法的,因为它返回的是局部变量a的引用(别名),也就是说它返回的其实就是a本身(而不是a的值)

}

// 2、函数的调用可以作为左值

int& test02()

{

        static int a = 10; // 存放在全局区,在全部的程序结束后由系统释放

        return a; //这种情况就没有问题,因为执行完test02()后,a不会被释放

}

int main()

{

        int &ref = test01(); // 由于返回值类型为引用,所以将引用ref来作为局部变量a的别名

// 等效为 int &ref = a; 但a所在的地址空间已经被释放了,里面的值已经不是10了

// 所以这一步可以看出,int &ref = a;其实是让 ref 与 a 指向同一个地址

        cout << "ref = " << ref << endl;

        int &ref2 = test02(); // ref2和静态局部变量a指向同一个地址,执行完test02()后a并没有被释放,因此下面的输出是正确的

        cout << "ref2 = " << ref2 << endl;

        cout << "ref2 = " << ref2 << endl;

        test02() = 1000; // 返回值为引用类型时,函数调用可以作为左值

// 这句等效为a = 1000;因为test02()返回的就是a,注意不是a的值

        cout << "ref2 = " << ref2 << endl;

        cout << "ref2 = " << ref2 << endl;

        system("pause");

        return 0;

}

运行结果: 

 

引用的本质

本质:引用的本质在C++内部实现是一个指针常量(即常量类型的指针,也即该指针本身就是一个常量)

int &ref = a; // 会自动转换为 int * const ref = &a; 所以ref不能是其他变量的别名(引用一旦初始化后,就不可以发生改变)

#include <iostream>

#include <string>

using namespace std;

void func(int &ref)

{

        ref = 100; // 发现ref是引用,自动转成 *ref = 100;

}

int main()

{

        int a = 10;

        int &ref = a; // 发现是引用,转换为int * const ref = &a

        ref = 20; // 发现ref是引用,自动转成 *ref = 20;

        cout << "a = " << a << endl;

        cout << "ref = " << ref << endl;

        system("pause");

        return 0;

}

运行结果:

 

结论:C++ 推荐 使用引用技术,因为语法方便。引用的本质是指针常量,但是所有的指针操作编译器都帮我们做了。

常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参。

#include <iostream>

#include <string>

using namespace std;

void showValue(int &a) // 引用的方式进行接收,即传入的是实参本身

{

        a = 1000; // 实参会被修改

        cout << "showValue val = " << a << endl;

}

void showValue_2(const int &a) // 引用的方式进行接收,即传入的是实参本身。但由于加了const修饰,就把引用变成了一个常量

{ // 因此形参引用的方式加const是为了防止误操作常见的应用场景)

//a = 1000; // 此操作非法,实参不会被修改

        cout << "showValue val = " << a << endl;

}

int main()

{

// 常量引用

// 使用场景:用来修饰形参,防止误操作

        int a = 10;

// int &ref = 10;// 此操作是非法的,因为右边是常量。被引用的对象必须是在栈区或堆区的数据,而常量位于常量区,即全局区。

        const int &ref = 10; // 此操作是合法的。加上const后,编译器将代码修改为 int temp = 10; const int &ref = temp;

// 也就是说现在的引用是引用一块临时的空间比如temp,但其实我们找不到它的原名(编译器起好了),我们只能通过别名ref去操控它

        // int &ref是一个指针常量,再加一个const,就既是指针常量,又是常量指针

        // ref = 20; // 此操作非法,因为被ref指向的对象已经是一个常量了

        int val = 100;

        showValue(val); // 由于showValue()函数是以引用的方式传递参数的,因此传入的就是实参val本身

        cout << "main() val = " << val << endl; // 验证实参是否被修改

        system("pause");

        return 0;

}

运行结果:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值