C++: 引用

最后更新:2026-08-26

指针虽然强大,但用起来有点麻烦——要写 *p 解引用,还要注意空指针。

C++ 引入了引用(Reference)——变量的"别名",用起来比指针更安全、更简洁。


1. 什么是引用?

(1) 1.1 生活中的引用

生活场景 程序中的对应
你有个外号"小明",叫哪个都能找到你 引用(变量的别名)
身份证上的名字和日常用的名字 引用和原变量

引用的本质: 引用是变量的别名——对引用的操作,就是对被引用变量的操作。

(2) 1.2 为什么需要引用?

用指针(麻烦):

▶ 示例 2:代码示例(难度⭐)

CPP
#include <iostream>

void modifyValue(int* x) {
 *x = 100; // 要解引用
}

int main() {
 int a = 5;
 modifyValue(&a); // 要传地址
 std::cout << a << std::endl; // 100
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
(程序输出)

用引用(简单):

CPP
#include <iostream>

void modifyValue(int& x) { // x 是引用
 x = 100; // 直接用,不用解引用
}

int main() {
 int a = 5;
 modifyValue(a); // 看起来像传值,其实是传引用
 std::cout << a << std::endl; // 100
 return 0;
}


2. 引用的声明与初始化

(1) 2.1 声明引用

语法:

TEXT 📖 仅展示
类型& 引用名 = 原变量;

示例:

CPP
#include <iostream>

int main() {
 int x = 5;
 int& ref = x; // ref 是 x 的别名
 
 std::cout << "x = " << x << std::endl; // 5
 std::cout << "ref = " << ref << std::endl; // 5
 
 ref = 100; // 修改 ref 就是修改 x
 std::cout << "修改后 x = " << x << std::endl; // 100
 
 return 0;
}

💡 重点: 引用必须初始化——不能先声明,后赋值。


(2) 2.2 引用 vs 指针

对比 引用 指针
语法 int& ref = x; int* p = &x;
是否能为空 ❌ 不能(必须初始化) ✅ 能(nullptr
是否要解引用 ❌ 不用(直接用) ✅ 要(*p
能否重新指向 ❌ 不能(一旦绑定,不能改) ✅ 能(可以指向别的变量)
推荐程度 ⭐⭐⭐⭐⭐(优先用) ⭐⭐⭐(必要时用)


3. 引用作为函数参数*

(1) 3.1 基本用法

CPP
#include <iostream>

// 用引用参数"返回"多个值
void minMax(int arr, int length, int& min, int& max) {
 min = arr[0];
 max = arr[0];
 
 for (int i = 1; i < length; i++) {
 if (arr[i] < min) {
 min = arr[i];
 }
 if (arr[i] > max) {
 max = arr[i];
 }
 }
}

int main() {
 int arr[5] = {3, 1, 4, 1, 5};
 int min, max;
 
 minMax(arr, 5, min, max); // min 和 max 会被修改
 
 std::cout << "最小值:" << min << std::endl; // 1
 std::cout << "最大值:" << max << std::endl; // 5
 
 return 0;
}

💡 重点: 引用参数让函数能"返回"多个值(因为可以修改多个引用参数)。


(2) 3.2 const 引用(最常用)

如果你不想让函数修改参数,但又想避免复制开销,可以用 const 引用

CPP
#include <iostream>
#include <string>

void printName(const std::string& name) { // const 引用:不能修改 name
 std::cout << "名字:" << name << std::endl;
 // name = "Alice"; // ❌ 错误:不能修改 const 引用
}

int main() {
 std::string myName = "MOTO";
 printName(myName); // 不用复制整个字符串,效率高
 return 0;
}

💡 黄金法则: 函数参数优先用 const 引用——兼顾安全性和效率。



4. 引用的陷阱*

(1) 4.1 引用必须初始化*

CPP
#include <iostream>

int main() {
 int& ref; // ❌ 错误:引用必须初始化
 return 0;
}

编译错误信息:

TEXT 📖 仅展示
error: 'ref' declared as reference but not initialized

(2) 4.2 引用不能重新绑定*

CPP
#include <iostream>

int main() {
 int x = 5;
 int y = 10;
 int& ref = x;
 
 ref = y; // ❌ 这不是重新绑定!这是把 x 的值改成 y 的值
 std::cout << "x = " << x << std::endl; // 10
 std::cout << "y = " << y << std::endl; // 10
 
 return 0;
}

💡 重点: 引用一旦绑定到某个变量,不能重新绑定到另一个变量。



5. 实战:多个返回值*

▶ 示例 1:计算商和余数(难度⭐⭐)

CPP
#include <iostream>

// 用引用参数"返回"多个值
void divide(int a, int b, int& quotient, int& remainder) {
 quotient = a / b;
 remainder = a % b;
}

int main() {
 int a = 17, b = 5;
 int q, r;
 
 divide(a, b, q, r); // q 和 r 会被修改
 
 std::cout << a << " / " << b << " = " << q << " ... " << r << std::endl;
 // 输出:17 / 5 = 3 ... 2
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
 /  =  ... 

▶ 示例 3:引用作为函数返回值(难度⭐)

CPP
#include <iostream>
#include <string>

std::string name = "张三"; // 全局变量

// 返回引用(不是值)
std::string& getName() {
    return name; // 返回的是 name 的引用
}

int main() {
    getName() = "李四"; // 修改全局变量
    
    std::cout << "name = " << name << std::endl;
    
    return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
name = 
💡 提示:函数返回引用可以让返回值作为左值使用。但注意:不要返回局部变量的引用!


❓ 常见问题

Q:引用和指针到底有什么区别? A:> - 引用是变量的别名,指针是存储地址的变量 > - 引用必须初始化,指针可以是 nullptr > - 引用不能重新指向,指针可以 > - 优先用引用,除非需要表示"没有"(这时用指针) Q:为什么数组作为参数时,不能用引用? A:可以用,但要写 数组引用 的语法(比较复杂)。

更简单的方法:std::arraystd::vector(后面会学)。

Q:引用能提高程序运行效率吗? A:不能。引用在底层通常就是用指针实现的,运行效率和指针一样。

它提高的是开发效率(代码更简洁、不易出错)。


Q:关于references最重要的是什么? A:先理解核心概念,再通过实践例子来巩固。


📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 写一个函数 void addTen(int& x),给传入的变量加 10。在 main 里测试。

  2. 进阶题 (Difficulty ⭐⭐): 写一个函数 void swap(int& a, int& b),交换两个变量的值。在 main 里测试。

  3. 挑战题 (Difficulty ⭐⭐⭐): 写一个程序,实现"三个数排序":

  4. 写一个函数 void sortThree(int& a, int& b, int& c),把三个数按从小到大排序

  5. main 里让用户输入三个数,调用 sortThree,然后输出排序后的结果

6. 🚀 下一步*

学会了引用,接下来我们学习 动态内存分配(第26课)—— 用 newdelete 手动管理内存,理解堆和栈的区别。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏