引用
引用的特点
引用是c++对c的重要扩充。在c/c++中指针的作用基本都是一样的,但是c++增加了另外一种给函数传递地址的途径,这就是按引用传递。
- 变量名实质上是一段连续内存空间的别名,是一个标号。
- 程序中通过变量来申请并命名内存空间
- 通过变量的名字可以使用存储空间
基本语法
数据类型 & 别名 = 原名
重点注意
- &在此不是求地址运算,而是起标识作用。
- 类型标识符是指目标变量的类型。
- 必须在声明引用变量时进行初始化。
- 引用初始化之后不能改变。
- 不能有NULL引用。必须确保引用是和一块合法的存储单元关联。可以建立对数组的引用。
图示
引用基本语法
代码示例
#include <iostream>
/**
* 基本引用语法
*/
using namespace std;
// 1.基本语法,
//语法 数据类型 & 别名 = 原名
void test01(){
// 定义变量
int a = 10;
int &b = a;
b = 100;
// 输出a , b的值
cout <<"a=" << a << endl;
cout <<"b=" << b << endl;
}
int main() {
// 调用函数
test01();
return 0;
}
程序运行结果
a = 100
b = 100
注意事项
代码说明
void test02()
{
//引用必须初始化
int a = 10;
//int &b; error 必须给引初始化
int &b = a;
//引用一旦初始化后,就不可以引向别的位置
int c = 20;
b = c; //赋值 并不是修改引用指向
}
数组引用
代码示例
#include <iostream>
/**
* 基本引用语法
*/
using namespace std;
// 数组引用
void test01(){
// 定义数组
int arr[5] = {1, 2,3,4,5};
// 1.直接建立引用
int(&pArr)[5] = arr;
// 遍历数组
/*
for (int i = 0; i < 5; ++i) {
cout << pArr[i] << endl;
}
*/
// 2.先定义数组类型,再通过类型。
typedef int(array_type)[5];
// 数据类型 &别名 = 原名
array_type & pArr2 = arr;
// 遍历数组
/* for (int i = 0; i < 5; ++i) {
cout << pArr2[i] << endl;
}*/
// 3.先定义数组引用类型,再通过类型定义引用
typedef int(&array_type1)[5];
array_type1 pArr3 = arr;
// 遍历数组
for (int i = 0; i < 5; ++i) {
// 输出数组元素
cout << pArr3[i] << endl;
}
}
int main() {
// 调用函数
test01();
return 0;
}
传递方式
地址传递
void Swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void test01()
{
int a = 10;
int b = 20;
Swap(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
引用传递
void Swap01(int &a ,int &b )
{
int temp = a;
a = b;
b = temp;
}
void test02()
{
int a = 10;
int b = 20;
Swap01(a, b);
cout << "a = " << a << endl; // 20
cout << "b = " << b << endl; // 10
}
注意:
1、引用必须引合法的内存空间。
2、不要返回局部变量的引用。
3、当函数返回值是引用时候,那么函数的调用可以作为左值存在。
引用的本质
引用的本质在c++内部实现是一个指针常量。
代码示例
Type& ref = val; // Type* const ref = &val
注意
c++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户不可见。
指针的引用
代码示例
#include <iostream>
/**
* 指针的引用
*/
using namespace std;
// 定义Person结构体类型
struct Person{
// 姓名
string name;
// 年龄
int age;
};
// 传统方法
void mallocMethod(Person ** person){
// 分配内存空间
Person *p = (Person *)malloc(sizeof(Person));
p->age = 21;
p->name = "Curry";
*person = p;
}
// 调用函数
void test01(){
// 初始化
Person *p = NULL;
mallocMethod(&p);
// 输出结果
// cout << "姓名是:"<< p->name <<endl << "年龄是:"<< p->age << endl;
cout << "p的年龄: " << p->age << endl;
cout << "p的姓名: " << p->name << endl;
}
// 指针引用
void mallocMethods(Person * &p){
// 分配内存空间
p = (Person *)malloc(sizeof(Person));
p->age = 22;
p->name = "kobe";
}
// 释放方法
void freeMethods(Person * &p){
free(p);
p = NULL;
}
// 调用函数
void test02(){
// 初始化
Person *p = NULL;
mallocMethods(p);
// 输出结果
cout << "p的年龄: " << p->age << endl;
cout << "p的姓名: " << p->name << endl;
// 调用freeMethods()
freeMethods(p);
}
int main() {
// 调用函数
// test01();
test02();
return 0;
}
常量的引用
特点:
1、字面量不能赋给引用,但是可以赋给const引用
2、const修饰的引用,不能修改。
代码示例
#include <iostream>
/**
* 常量的引用
*/
using namespace std;
//加const修饰形参,为了防止在代码中误操作,修改数据
void constValue( const int &a){
// 输出a的大小
cout << "a的大小是:" << a << endl;
}
// 声明函数
void test01(){
// 定义变量
int a = 200;
constValue(a);
}
int main() {
cout << "Hello, World!" << endl;
// 调用函数
test01();
return 0;
}