热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【深入理解C++】引用

文章目录1.变量的别名2.变量的多个别名3.引用存在的价值4.引用的大小5.从汇编角度看引用6.结构体的引用7.指针的引用8.数组的引用1.变量的别名在C语言中,使

文章目录

  • 1.变量的别名
  • 2.变量的多个别名
  • 3.引用存在的价值
  • 4.引用的大小
  • 5.从汇编角度看引用
  • 6.结构体的引用
  • 7.指针的引用
  • 8.数组的引用


1.变量的别名

在 C 语言中,使用指针(Pointer)可以间接获取、修改某个变量的值。在 C++ 中,使用引用(Reference)可以起到跟指针类似的功能。

引用相当于是变量的别名,一般用 & 符号表示,基本数据类型、枚举、结构体、类、指针、数组等都可以有引用。

引用必须绑定到变量上去,不能绑定到常量上去。引用指向的类型要相同。

对引用做计算,就是对引用所指向的变量做计算。

在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变,“从一而终”。

#include
using namespace std;int main() {int age &#61; 10;int height &#61; 20;// 定义了一个age的引用&#xff0c;ref相当于是age的别名int &ref &#61; age;ref &#61; 20;ref &#43;&#61; 30;cout << age << endl; // 50ref &#61; height;ref &#61; 11;cout << age << endl; // 11cout << height << endl; // 20return 0;
}

2.变量的多个别名

可以利用引用初始化另一个引用&#xff0c;相当于某个变量的多个别名。

#include
using namespace std;int main() {int age &#61; 10;// 定义了一个age的引用&#xff0c;ref相当于是age的别名int& ref &#61; age;int& ref1 &#61; ref;int& ref2 &#61; ref1;ref &#43;&#61; 10;ref1 &#43;&#61; 10;ref2 &#43;&#61; 10;cout << age << endl; // 40return 0;
}

3.引用存在的价值

不存在 “引用的引用”、“指向引用的指针”、“引用数组”。

引用存在的价值之一&#xff1a;比指针更安全、函数返回值可以被赋值。

举例1&#xff1a;通过指针传参交换两个数

#include
using namespace std;void swap(int *v1, int *v2) {int tmp &#61; *v1;*v1 &#61; *v2;*v2 &#61; tmp;
}int main() {int a &#61; 10;int b &#61; 20;swap(&a, &b);cout << "a &#61; " << a << ", b &#61; " << b << endl; // a &#61; 20, b &#61; 10return 0;
}

举例2&#xff1a;通过引用传参交换两个数

#include
using namespace std;void swap(int &v1, int &v2) {int tmp &#61; v1;v1 &#61; v2;v2 &#61; tmp;
}int main() {int a &#61; 10;int b &#61; 20;swap(a, b);cout << "a &#61; " << a << ", b &#61; " << b << endl; // a &#61; 20, b &#61; 10int c &#61; 2;int d &#61; 3;swap(c, d);cout << "c &#61; " << c << ", d &#61; " << d << endl; // c &#61; 3, d &#61; 2return 0;
}

4.引用的大小

一个引用占用一个指针的大小。

举例1&#xff1a;只含一个 int 整数的类对象的大小

#include
using namespace std;struct Student {int age;
};int main() {cout << sizeof(Student) << endl;// x64(64bit): 4// x86(32bit): 4return 0;
}

举例2&#xff1a;只含一个 int 指针的类对象的大小

#include
using namespace std;struct Student {int *age;
};int main() {cout << sizeof(Student) << endl;// x64(64bit): 8// x86(32bit): 4return 0;
}

举例3&#xff1a;只含一个 int 引用的类对象的大小

#include
using namespace std;struct Student {int &age;
};int main() {cout << sizeof(Student) << endl;// x64(64bit): 8// x86(32bit): 4return 0;
}

5.从汇编角度看引用

引用的本质就是指针&#xff0c;只是编译器削弱了它的功能&#xff0c;所以引用就是弱化了的指针。

加断点&#xff0c;按 F5 进入调试&#xff0c;转到反汇编&#xff0c;不勾选“显示符号名”。

举例1&#xff1a;查看 int 指针的汇编代码

#include
using namespace std;int main() {int age &#61; 10;// *p就是age的别名int *p &#61; &age;*p &#61; 30;return 0;
}

在这里插入图片描述

举例2&#xff1a;查看 int 引用的汇编代码

#include
using namespace std;int main() {int age &#61; 10;// ref就是age的别名int &ref &#61; age;ref &#61; 30;return 0;
}

在这里插入图片描述

对比两图可以发现&#xff0c;ref 本质上就是指针&#xff0c;存储的就是 age 的地址值。

6.结构体的引用

#include
using namespace std;struct Date {int year;int month;int day;
};int main() {Date d &#61; { 2022, 1, 25 };Date& ref &#61; d;ref.year &#61; 2023;cout << d.year << endl; // 2023return 0;
}

7.指针的引用

指针是一个存放地址的变量&#xff0c;而指针引用指的是这个指针变量的引用。

#include
using namespace std;int main() {int age &#61; 10;int *p &#61; &age;int *&ref &#61; p;*ref &#61; 30;cout << age << endl; // 30int height &#61; 40;ref &#61; &height;cout << *ref << endl; // 40return 0;
}

在 C&#43;&#43; 中&#xff0c;如果参数不是引用的话&#xff0c;会调用参数对象的拷贝构造函数&#xff0c;所以如果想改变指针所指的对象&#xff08;即想要改变指针里面存的地址&#xff09;&#xff0c;就要使用指针引用。

举例1&#xff1a;指针

#include
using namespace std;struct Point
{int x;int y;
};void change1(Point* pp)
{pp &#61; new Point;pp->x &#61; 4;
}int main()
{Point* p &#61; new Point;p->x &#61; 10;cout << "指针前&#xff1a;" << p->x << endl;change1(p);cout << "指针后&#xff1a;" << p->x << endl;return 0;
}

在这里插入图片描述

举例2&#xff1a;指针的引用

#include
using namespace std;struct Point
{int x;int y;
};void change2(Point* &pp)
{pp &#61; new Point;pp->x &#61; 4;
}int main()
{Point* p &#61; new Point;p->x &#61; 10;cout << "指针引用前&#xff1a;" << p->x << endl;change2(p);cout << "指针引用后&#xff1a;" << p->x << endl;return 0;
}

在这里插入图片描述

8.数组的引用

举例1&#xff1a;区分指针数组、数组指针、数组的引用

#include
using namespace std;int main() {int array[3] &#61; {1, 2, 3};// 指针数组&#xff0c;数组里面可以存放3个int*int *arr1[3] &#61; {array, array, array};// 数组指针&#xff0c;用于指向数组的指针int (*arr2)[3] &#61; &array;// 数组的引用int (&ref)[3] &#61; array;ref[0] &#61; 10;cout << array[0] << endl; // 10return 0;
}

举例2&#xff1a;引用数组的两种格式

#include
using namespace std;int main() {// 数组名arr其实是数组的地址&#xff0c;也是数组首元素的地址// 数组名arr可以看做是指向数组首元素的指针(int *)int arr[] &#61; {1, 2, 3};cout << *(arr &#43; 2) << endl; // 3// 等价于arr[2]// 数组的引用格式1int (&ref)[3] &#61; arr;cout << ref[2] << endl; // 3// 数组的引用格式2int * const &refArr &#61; arr;cout << refArr[2] << endl; // 3return 0;
}


推荐阅读
author-avatar
mobiledu2502853623
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有