菜鸟教程 -- 学的不仅是技术,更是梦想!

C++ 教程
C++ 教程 C++ 简介 C++ 环境设置 C++ 基本语法 C++ 注释 C++ 数据类型 C++ 变量类型 C++ 变量作用域 C++ 常量 C++ 修饰符类型 C++ 存储类 C++ 运算符 C++ 循环 C++ 判断 C++ 函数 C++ 数字 C++ 数组 C++ 字符串 C++ 指针 C++ 引用 C++ 日期 & 时间 C++ 基本的输入输出 C++ 结构体(struct) C++ vector 容器 C++ 数据结构

C++ 面向对象

C++ 类 & 对象 C++ 继承 C++ 重载运算符和重载函数 C++ 多态 C++ 数据抽象 C++ 数据封装 C++ 接口(抽象类)

C++ 高级教程

C++ 文件和流 C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程

C++ 资源库

C++ STL 教程 C++ 导入标准库 C++ 标准库 C++ 有用的资源 C++ 实例 C++ 测验 C++ <iostream> C++ <fstream> C++ <sstream> C++ <iomanip> C++ <array> C++ <vector> C++ <list> C++ <forward_list> C++ <deque> C++ <stack> C++ <queue> C++ <priority_queue> C++ <set> C++ <unordered_set> C++ <map> C++ <unordered_map> C++ <bitset> C++ <algorithm> C++ <iterator> C++ <functional> C++ <numeric> C++ <complex> C++ <valarray> C++ <cmath> C++ <string> C++ <regex> C++ <ctime> C++ <chrono> C++ <thread> C++ <mutex> C++ <condition_variable> C++ <future> C++ <atomic> C++ <type_traits> C++ <typeinfo> C++ <exception> C++ <stdexcept> C++ <cstdio> C++ <cstdint> C++ <memory> C++ <new> C++ <utility> C++ <random> C++ <locale> C++ <codecvt> C++ <cassert> C++ <cwchar> C++ <climits> C++ <cfloat> C++ <cstdlib> C++ <numbers> C++ OpenCV
(追記) (追記ここまで)

C++ 引用

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。

一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

引用必须在定义时初始化,并且一旦绑定到一个变量后,就不能再绑定到其他变量。

引用的语法如下:

int a = 10;
int &ref = a; // ref 是 a 的引用
  • int &ref 表示 ref 是一个 int 类型的引用。

  • refa 的别名,对 ref 的操作会直接作用于 a

C++ 引用 vs 指针

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用,引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。
  • 引用的对象必须是一个变量,而指针必须是一个地址。
特性引用指针
定义与初始化必须初始化,且不能为 null可以不初始化,可以在后续代码中指向其他对象,可以为 null
语法使用 & 声明,例如:int &ref = a;使用 * 声明,例如:int *ptr = &a;
重新绑定不能重新绑定,一旦初始化后始终引用同一个对象。可以重新指向其他对象,例如:ptr = &b;
空值(Nullability)不能为 null,必须绑定到有效的对象。可以为 null,表示不指向任何对象。
内存占用不占用额外内存(编译器通常将其优化为直接操作所引用的对象)。占用额外内存(存储地址,通常是一个机器字长,如4字节或8字节)。
访问方式直接使用,无需解引用操作符,例如:ref = 10;需要使用 * 解引用操作符访问或修改所指向的对象,例如:*ptr = 10;
多级间接访问不支持多级间接访问(不能有引用的引用)。支持多级间接访问(如指针的指针:int **pptr;)。
函数参数传递常用于函数参数传递,语法简洁,例如:void func(int &x) { x = 10; }也可以用于函数参数传递,但需要使用解引用操作符,例如:void func(int *x) { *x = 10; }
数组与引用不能直接创建引用数组,但可以创建数组的引用,例如:int (&ref)[10] = arr;可以创建指针数组,也可以创建指向数组的指针,例如:int *ptrArr[10];
安全性更安全,不能为 null,且语法更直观。更灵活,但容易出错(如空指针、野指针等)。
底层实现通常通过指针实现,但编译器会优化为直接操作所引用的对象。直接存储目标对象的内存地址。

C++ 中创建引用

试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,您可以通过原始变量名称或引用来访问变量的内容。例如:

int i = 17;

我们可以为 i 声明引用变量,如下所示:

int& r = i;
double& s = d;

在这些声明中,& 读作引用

因此,第一个声明可以读作 "r 是一个初始化为 i 的整型引用",第二个声明可以读作 "s 是一个初始化为 d 的 double 型引用"

下面的实例使用了 int 和 double 引用:

实例

#include<iostream>usingnamespacestd; intmain(){// 声明简单的变量inti; doubled; // 声明引用变量int& r = i; double& s = d; i = 5; cout << "Value of i : " << i << endl; cout << "Value of i reference : " << r << endl; d = 11.7; cout << "Value of d : " << d << endl; cout << "Value of d reference : " << s << endl; return0; }

当上面的代码被编译和执行时,它会产生下列结果:

Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7

引用通常用于函数参数列表和函数返回值。下面列出了 C++ 程序员必须清楚的两个与 C++ 引用相关的重要概念:

概念描述
把引用作为参数 C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。
把引用作为返回值 可以从 C++ 函数中返回引用,就像返回其他数据类型一样。
AI 思考中...

7 篇笔记 写笔记

  1. #0

    Jailman

    xma***man.com

    205

    int& r = i;int r = i; 不同之处应该是内存的分配吧,后者会再开辟一个内存空间

    #include <iostream>
     
    using namespace std;
     
    int main ()
    {
     int i;
     int& r = i;
     i = 5;
     cout << "Value of i : " << i << endl;
     cout << "Value of i reference : " << r << endl;
     cout << "Addr of i: " << &i << endl;
     cout << "Addr of r: " << &r << endl;
     
     int x;
     int y = x;
     x = 6;
     cout << "Value of x : " << x << endl;
     cout << "Value of y : " << y << endl;
     cout << "Addr of x: " << &x << endl;
     cout << "Addr of y: " << &y << endl;
     
     return 0;
    }
    

    输出结果:

    Value of i : 5
    Value of i reference : 5
    Addr of i: 0x7fff59cda988
    Addr of r: 0x7fff59cda988
    Value of x : 6
    Value of y : 32767
    Addr of x: 0x7fff59cda97c
    Addr of y: 0x7fff59cda978
    

    Jailman

    xma***man.com

    9年前 (2017年07月20日)
  2. #0

    小马

    129***[email protected]

    96

    1.引用必须在声明时将其初始化,不能先声明后赋值。

    #include <iostream>
    using namespace std;
    int main()
    {
     int rats = 10;
     
     //声明引用,旦未初始化
     int &rodents;
     rodents = rats;
     return 0;
    }

    上述代码编译时会报以下错误:

    error: ‘rodents’ declared as reference but not initialized

    错误:'rodents' 声明为引用但未初始化。

    2.引用更接近const指针,必须在创建时进行初始化,一旦引用和某个变量关联起来,该引用就会一直指向该变量。

    int rats = 10;
    int &rodents = rats;

    上面代码实际上是下述代码的伪装表示:

    int rats = 10;
    int * const pr = &rats;

    例子:

    #include <iostream>
    using namespace std;
    int main()
    {
     int rats = 100;
     int &rodent = rats;
     cout << "rats = "<<rats<<", rosent = "<<rodent<<endl;
     cout << "rats address = "<<&rats<<endl;
     cout << "rosent address = "<<&rodent<<endl;
     cout <<"==================================="<<endl;
     int bunnies = 50;
     rodent = bunnies;
     cout << "rats = "<<rats<<", rosent = "<<rodent<<", bunnies = "<<bunnies<<endl;
     cout << "rats address = "<<&rats<<endl;
     cout << "rosent address = "<<&rodent<<endl;
     cout << "bunniess address = "<<&bunnies<<endl;
     return 0;
    }

    输出结果:

    rats = 100, rosent = 100
    rats address = 0xbfce21e4
    rosent address = 0xbfce21e4
    ===================================
    rats = 50, rosent = 50, bunnies = 50
    rats address = 0xbfce21e4
    rosent address = 0xbfce21e4
    bunniess address = 0xbfce21e8

    从结果可以看出,虽然在调用 rodent = bunnies; 后引用 rosent 的值变为 50,但是 rosent 所指向的地址空间还是指向了 rats,没有发生改变,说明 rodent = bunnies; 只是将 bunnies 的值赋值给引用 rodent 所指向的变量,没有改变引用的指向。

    小马

    129***[email protected]

    9年前 (2017年08月15日)
  3. #0

    月色真美

    132***[email protected]

    169

    我来给大家分享一下我对引用的理解:假如你被你的同学起了绰号叫"舞法少女",那么这个绰号就相当于你名字的一个引用,在同学看来,无论叫哪个都是在叫你。

    除此之外,若在函数中使用引用作为参数,如下实例:将 a 当实参传给函数 func,x 为函数 func 的形参且为引用,在函数 func 中 x 被赋予了新的值 3,于是 a 的值也跟着变为 3。

    #include <iostream>
    using namespace std;
    int func(int &x)//函数func将引用当作形参
    {
     x=3;
     return 0;
    } 
    int main ()
    {
     int a=1;//声明整型变量
     func(a);////给函数func传参
     cout<<"a的值为: "<<a<<endl;//输出a的值,结果为“a的值为3”
     return 0;
    }

    更多内容可以参考:C++ 引用类型

    月色真美

    132***[email protected]

    9年前 (2017年10月23日)
  4. #0

    胡椒酱

    fen***[email protected]

    58
    #include<iostream>
    int main(){
     int b = 0;
     int &a = b;
     a = 4;
     std::cout << a<<'\t'<< std::endl;
     b = 555554;
     std::cout << a << std::endl;
     return 0;
    }

    在这里也只是想着验证一下 引用是否可以改变这个原来的被引用变量里存的值,最后也确实是可以改变。

    用火影忍者里的分身法作比喻:

    • 指针其实更像是普通的分身法,即使是分身破灭,对自身也没有影响;
    • 引用更像是多重影分身,多重影分身发生了变化,本身也会受到影响。

    胡椒酱

    fen***[email protected]

    7年前 (2019年11月20日)
  5. #0

    JueVenil

    452***[email protected]

    31

    数组的引用一定要表明数组的大小。

    #include <iostream>
    int main() {
     int *p;
     int a[] = { 1,2,3,4 };
     int(&t)[4] = a;
     std::cout << t << std::endl;
     return 0;
    }

    JueVenil

    452***[email protected]

    6年前 (2020年08月31日)
  6. #0

    嘟嘟小猪

    409***[email protected]

    37

    B 引用 A:相当于 B 借用了 A 的内存地址和值,A 和 B 任意一个发生改变的话 AB 同时改变。

    指针 B 指向 A:B 借用了 A 的值,但是B的内存地址重新分配,不同于 A。

    #include<iostream>
    int main(){
     int b = 0;
     int &a = b;
     a = 4;
     std::cout << a<<'\t'<< std::endl;
     std::cout << &a<<'\t'<< std::endl;
     std::cout << b<<'\t'<< std::endl;
     std::cout << &b<<'\t'<< std::endl<< std::endl;
     b = 555554;
     std::cout << a << std::endl;
     std::cout << &a<<'\t'<< std::endl;
     std::cout << b<<'\t'<< std::endl;
     std::cout << &b<<'\t'<< std::endl<< std::endl;
     a = 54;
     std::cout << a << std::endl;
     std::cout << &a<<'\t'<< std::endl;
     std::cout << b<<'\t'<< std::endl;
     std::cout << &b<<'\t'<< std::endl<< std::endl;
     //*****************************
     int c = 100;
     int *d = &c ;
     std::cout << c<<'\t'<< std::endl;
     std::cout << &c<<'\t'<< std::endl;
     std::cout << *d<<'\t'<< std::endl;
     std::cout << &d<<'\t'<< std::endl<< std::endl;
     *d = 200;
     std::cout << c<<'\t'<< std::endl;
     std::cout << &c<<'\t'<< std::endl;
     std::cout << *d<<'\t'<< std::endl;
     std::cout << &d<<'\t'<< std::endl<< std::endl;
     return 0;
    }

    输出结果为:

    4
    0x7ffee3dff8d8
    4
    0x7ffee3dff8d8
    555554
    0x7ffee3dff8d8
    555554
    0x7ffee3dff8d8
    54
    0x7ffee3dff8d8
    54
    0x7ffee3dff8d8
    100
    0x7ffee3dff8cc
    100
    0x7ffee3dff8c0
    200
    0x7ffee3dff8cc
    200
    0x7ffee3dff8c0

    嘟嘟小猪

    409***[email protected]

    6年前 (2020年09月24日)
  7. #0

    TooHandsomeException

    ywt***@163.com

    24

    C++11 新增特性 -- 右值引用,写法示例:

    int &&rvalueReference = 1 + 2;

    加入右值引用的目的主要是为了解决这样一个问题:在函数传值以及返回值的时候,一个对象被复制给另外一个对象,然后这个对象紧接着就被析构了。显然很浪费时间。使用右值引用的话就可以把一个对象的所有权"转让"给另外一个对象,而无需调用复制构造函数和析构函数。

    TooHandsomeException

    ywt***@163.com

    4年前 (2022年09月16日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /