引用
一、引用的基本概念
引用变量是C++新增的符合类型。
引用时已定义的变量名。
引用的主要用途是作用函数的形参和返回值。
声明/创建引用的语法:数据类型 &引用名=原变量名;
注意:
- 引用的数据类型要与原变量的数据类型相同。
- 引用名和原变量名可以互换,他们的值和内存单元是相同的。
- 必须在声明引用的时候初始化,初始化后不可改变。
- C和C++用&符号来只是/取变量的地址,C++给&符号赋予了另一种含义。
示例:
#include <iostream> using namespace std; int main() { int a = 3; int& ra = a; cout << "a的地址是:" << &a << " a的值是:" << a << endl; cout << "ra的地址是:" << &ra << " ra的值是:" << ra << endl; ra = 5; cout << "a的地址是:" << &a << " a的值是:" << a << endl; cout << "ra的地址是:" << &ra << " ra的值是:" << ra << endl; }
二、引用的本质
引用时指针常量的伪装。
引用时编译器提供的一个有用而且安全的工具,去除了指针的一些缺点,禁止了部分不安全的操作。
变量是什么?变量就是一个在程序执行过程中可以改变的量。
换一个角度,变量是一块内存区域的名字,它代表了这块内存区域,当我们对变量进行修改的时候,会引起内存区域的中内容的改变。
在计算机看来,内存区域根本就不存在什么名字,它仅有的标志就是它的地址,因此我们若想修改一块内存区域的内容,只有知道它的地址才能实现。
所谓的变量只不过是编译器给我们进行的一种抽象,让我们不必去了解更多的细节,降低我们的思维阔度。
程序员拥有的引用,但编译器仅拥有指针(地址)。
引用的底层机制实际上是和指针一样的。不要相信有别名,不要认为引用可以节省一个指针空间,因为这一切不会发生,编译器还是会把引用解释为指针。
引用和指针本质上没有区别。
示例:
#include <iostream> using namespace std; int main() { int a = 3; int& ra = a; int* const rb = &a; cout << "a的地址是:" << &a << " a的值是:" << a << endl; cout << "ra的地址是:" << &ra << " ra的值是:" << ra << endl; cout << "rb的地址是:" << rb << " rb的值是:" << *rb << endl; ra = 5; cout << "a的地址是:" << &a << " a的值是:" << a << endl; cout << "ra的地址是:" << &ra << " ra的值是:" << ra << endl; cout << "rb的地址是:" << rb << " rb的值是:" << *rb << endl; }
三、引用用于函数的参数
把函数的形参声明为引用,调用函数的时候,形参将成为实参的别名。
这种方法也叫按引用传递或传引用。(传值、传地址、传引用只是说法不同,其实都是传值。)
引用的本质时指针,传递的是变量的地址,在函数中修改形参会影响实参。
1)传引用的代码更简洁。
2)传引用不比使用二级指针。
3)引用的属性和特别之处。
示例:
#include <iostream> // 包含头文件。 using namespace std; // 指定缺省的命名空间。 void func1(int no, string str) // 传值。 { no = 8; str = "我的"; cout << "no =" << no << " 号:" << str << endl; } void func2(int* no, string* str) // 传地址。 { *no = 8; *str = "我的"; cout << "no =" << *no << "号:" << *str << endl; } void func3(int &no, string &str) // 传引用。 { no = 8; str = "我的"; cout << "no =" << no << "号:" << str << endl; } int main() { int bh = 3; // 编号。 string message = "你的"; // 。 //func1(bh, message); // 传值。 //func2(&bh, &message); // 传地址。 func3(bh, message); // 传引用。 cout << "no =" << bh << "号:" << message << endl; }