跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 入门:引用、内联函数与 C++11 新特性详解

C++ 引用别名机制与指针区别,内联函数空间换时间原理及限制,C++11 auto 类型推导规则与场景,基于范围的 for 循环迭代条件,以及 nullptr 解决 NULL 歧义的优势。涵盖参数传递效率对比、返回值风险及编译器优化细节。

SqlMaster发布于 2026/3/21更新于 2026/6/1915 浏览
C++ 入门:引用、内联函数与 C++11 新特性详解

一、引用

1. 引用概念

引用不是新定义一个变量,而是给已存在变量取了一个别名。编译器不会为引用开辟新的内存空间,它和引用的变量共用同一块内存。

void TestRef() {
    int a = 10;
    int& ra = a; // 定义引用类型
    printf("%p\n", &a);
    printf("%p\n", &ra);
}

注意:引用类型必须和引用实体是同种类型的。

2. 引用特性
  • 定义时必须初始化。
  • 一个变量可以有多个引用。
  • 引用一旦绑定一个实体,不能再指向其他实体(后续赋值是修改值,而非改变指向)。
#include <iostream>
using namespace std;
int main() {
    int a = 10;
    // int& ra; // 编译报错:必须初始化引用
    
    int& b = a;
    int& d = a; // 一个变量可以有多个引用
    
    int c = 20;
    b = c; // 这里并非让 b 引用 c,而是将 c 的值赋给 b 所指的 a
    return 0;
}
3. 常引用

const 修饰的引用即常引用。当常引用绑定临时变量时,会延长临时变量的生命周期,使其与常引用的生命周期一致。

4. 使用场景

引用做参数: 避免大对象拷贝,提高效率。形参和实参指向同一实体,不用担心值拷贝问题。

void Swap(int& left, int& right) {
    int temp = left;
    left = right;
    right = temp;
}

引用做返回值: 返回局部变量的引用是危险的,因为局部变量出函数后销毁,会导致悬空引用。正确做法是返回静态区变量或全局变量。

// 错误示例:返回局部变量引用
int& Add(int a, int b) {
    int c = a + b;
    return c; // 危险!c 销毁后 ret 成为野指针
}

// 正确示例:返回静态变量引用
int& Count() {
    static int n = 0;
    n++;
    return n;
}

返回引用的优势在于避免对象拷贝(尤其对大对象),提升性能,并支持链式操作。但需警惕被引用对象销毁后的未定义行为。

5. 传引用与传值效率比较

以值作为参数或返回值,期间会产生临时拷贝,效率低下,尤其是大对象。通过代码测试对比传引用和传值的耗时差异,能直观感受到引用在性能上的优势。

#include <time.h>
struct A {
    int a[10000];
};

void TestFunc1(A a) {} // 传值
void TestFunc2(A& a) {} // 传引用

void TestRefAndValue() {
    A a;
    size_t begin1 = clock();
    for (size_t i = 0; i < 1000000; ++i) TestFunc1(a);
    size_t end1 = clock();

    size_t begin2 = clock();
    for (size_t i = 0; i < 1000000; ++i) TestFunc2(a);
    size_t end2 = clock();

    cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
    cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

运行结果通常显示传引用耗时显著更低。

6. 指针和引用的区别

语法上,引用是别名,无独立空间;指针存储地址。底层实现上,引用可能按指针方式实现,但语义不同。

特性引用指针
定义要求必须初始化无要求
重新绑定不可变可变
NULL无 NULL 引用有 NULL 指针
sizeof引用类型大小地址空间大小
多级无多级引用有多级指针
访问自动解引用需显式解引用

引用比指针更安全,不易出错。

二、内联函数

1. 什么是内联函数

以 inline 修饰的函数,编译器会在调用处展开函数体,消除函数调用的栈帧开销,从而提升运行效率。

2. 如何判断是否为内联函数

查看编译器生成的汇编代码中是否存在 call 指令。若没有直接替换为代码,则说明未被内联。Debug 模式下默认不优化,Release 模式更容易观察到内联效果。

3. 内联函数特性

核心是以空间换时间。编译器仅处理规模小、非递归、频繁调用的函数。声明定义通常建议分离,否则可能导致链接错误。内联函数具有内部链接属性,不同源文件可定义同名内联函数而不冲突。

常见问题:

  • 目标文件变大? 是的,因为函数体在多处复制。
  • 递归不能内联? 编译器无法在编译期确定递归展开次数,故不支持。

三、auto 关键字 (C++11)

1. auto 简介

C++11 中 auto 用于编译期类型推导。不再表示'自动存储期',而是根据初始化表达式自动推断变量类型。极大简化了复杂类型(如迭代器、模板)的声明。

核心要求: 变量必须初始化,否则编译器无法推导。

int a = 10;
auto b = a; // 推导为 int
auto c = 'c'; // 推导为 char
2. 使用细则

结合指针和引用:

  • auto* p = &x; 和 auto p = &x; 均推导为指针类型。
  • auto& r = y; 推导为引用类型;若不加 &,则推导为值类型。

多变量定义: 同一行定义的多个变量必须能被推导为相同类型。

auto a = 10, b = 20; // 正确,均为 int
// auto c = 10, d = 3.14; // 错误,类型不一致
3. 不能推导的场景
  • 函数参数: 编译器无法在编译期知道调用时的实际类型。
  • 数组声明: 无法直接推导数组类型,需配合指针或引用。

四、基于范围的 for 循环 (C++11)

1. 语法

由冒号分为迭代变量和被迭代范围两部分,替代传统下标或指针遍历。

int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array) e *= 2; // 修改原值
for(auto e : array) cout << e << " "; // 拷贝遍历
2. 使用条件
  • 范围确定: 数组或提供 begin()/end() 方法的类对象。
  • 支持迭代器: 对象需实现 ++ 和 == 操作。

注意:传递数组指针时,范围 for 无法获取长度,需谨慎使用。

五、指针空值 nullptr (C++11)

1. NULL 的问题

NULL 本质是宏,可能被定义为 0 或 (void*)0。在函数重载时,f(NULL) 可能因歧义导致匹配错误。

2. 引入 nullptr 的原因
  • 明确性: 专门表示指针空值,解决 NULL 的类型歧义。
  • 无需头文件: 关键字级别支持。
  • 类型安全: 可隐式转换为任何指针类型,但不能转为整数。
void f(int);      void f(int*);
f(0);             // 调用 f(int)
f(nullptr);       // 明确调用 f(int*)
3. nullptr 类型

类型为 std::nullptr_t,兼容所有指针类型,但不兼容整数类型。相比 NULL,它能显著提升代码健壮性。

目录

  1. 一、引用
  2. 1. 引用概念
  3. 2. 引用特性
  4. 3. 常引用
  5. 4. 使用场景
  6. 5. 传引用与传值效率比较
  7. 6. 指针和引用的区别
  8. 二、内联函数
  9. 1. 什么是内联函数
  10. 2. 如何判断是否为内联函数
  11. 3. 内联函数特性
  12. 三、auto 关键字 (C++11)
  13. 1. auto 简介
  14. 2. 使用细则
  15. 3. 不能推导的场景
  16. 四、基于范围的 for 循环 (C++11)
  17. 1. 语法
  18. 2. 使用条件
  19. 五、指针空值 nullptr (C++11)
  20. 1. NULL 的问题
  21. 2. 引入 nullptr 的原因
  22. 3. nullptr 类型
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Spring Boot 3.x 新特性解析:Java 17 支持与 GraalVM 原生镜像
  • Python+TensorRT+ONNX 实现大模型量化部署
  • VMware 17 Ubuntu 虚拟机与宿主机复制粘贴失效修复
  • 大模型落地实战指南:显卡选型、模型训练与未来展望
  • 基于 FPGA 的高精度 TDC 设计
  • LLaMA-Factory 大模型微调实战指南
  • 2025 年蓝桥杯省赛 C++大学 A 组试题解析
  • 2026 边缘 AI 视觉白皮书:算法固化与产线工程师转型
  • Spring AI Agent Skills 功能介绍与实战指南
  • AI 智能客服系统构建方案:选型指南与实战避坑
  • OpenAI Codex 全面上手指南
  • Python act-atmos 大气数据处理工具包介绍
  • 昇腾 CANN 学习路径指南:Python、C++ 与算子开发选型
  • Meta-Llama-3-8B-Instruct 代码能力测试及 HumanEval 45+ 解析
  • Python 字典(dict)数据类型详解
  • JavaScript 错误处理:Uncaught (in promise) 错误分析与解决方案
  • OpenClaw 机器人本地部署与配置实战
  • 告别 MobaXterm:开源终端模拟器 Tabby 深度对比与迁移指南
  • AI 辅助前端页面开发提速 3 倍:生成 HTML+CSS 仅需改细节
  • Python IDLE 中文汉化方法

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online