
个人主页:
wengqidaifeng
✨ 永远在路上,永远向前走
个人专栏:
数据结构
C语言
嵌入式小白启动!
重要OJ算法题详解
蓝桥杯备战
C++从菜鸟到强手
python启航
文章目录
-
-
- [1. C++简介](#1. C++简介)
- [2. C++发展历史](#2. C++发展历史)
-
- [2.1 C++版本更新历程](#2.1 C++版本更新历程)
- [2.2 C++23的"网络库"小故事](#2.2 C++23的“网络库”小故事)
- [3. C++参考文档](#3. C++参考文档)
- [4. C++的重要性](#4. C++的重要性)
-
- [4.1 编程语言排行榜](#4.1 编程语言排行榜)
- [4.2 应用领域](#4.2 应用领域)
- [5. 学习建议与书籍推荐](#5. 学习建议与书籍推荐)
- [6. C++的第一个程序](#6. C++的第一个程序)
- [7. 命名空间](#7. 命名空间)
-
- [7.1 价值](#7.1 价值)
- [7.2 定义与特性](#7.2 定义与特性)
- [7.3 使用方式](#7.3 使用方式)
- [8. C++输入与输出 (IO)](#8. C++输入与输出 (IO))
- [9. 缺省参数](#9. 缺省参数)
- [10. 函数重载](#10. 函数重载)
- [11. 引用](#11. 引用)
-
- [11.1 概念](#11.1 概念)
- [11.2 核心特性](#11.2 核心特性)
- [11.3 主要应用](#11.3 主要应用)
- [11.4 const引用](#11.4 const引用)
- [11.5 指针与引用的区别](#11.5 指针与引用的区别)
- [12. 内联函数 (inline)](#12. 内联函数 (inline))
- [13. nullptr](#13. nullptr)
- [14. 总结](#14. 总结)
-
1. C++简介
C++是一门强类型、编译型 的通用编程语言,兼具面向过程 和面向对象 的特性。它由Bjarne Stroustrup于1979年在贝尔实验室开始研发,旨在解决C语言在大型软件开发中表达能力、可维护性不足的问题。C++的设计目标是在保留C语言高效性和底层控制力的同时,引入面向对象理念,构建复杂系统。
核心特点:
- 高效性:允许底层编程,直接操控硬件和内存。
- 面向对象:支持类、封装、继承、多态。
- 多范式:支持面向对象、泛型编程、函数式编程等。
- 标准库:拥有丰富的标准库(如STL),涵盖容器、算法、I/O等。
- 兼容C:几乎无缝兼容C语言代码。
2. C++发展历史
- 起源(1979-1983):Bjarne Stroustrup 在C语言基础上添加面向对象特性,1983年正式命名为C++。
- 标准化的推进(1989-1998):1989年开始标准化工作,成立ANSI/ISO联合委员会。1994年提出第一份标准草案。
- STL的加入 :惠普实验室开发的 STL(标准模板库) 被投票纳入C++标准,虽然延缓了进程,但极大扩展了语言能力。
- 第一个标准 :1997年通过最终草案,1998年发布C++98标准。
2.1 C++版本更新历程
| 年份 | 版本 | 核心更新内容 |
|---|---|---|
| 1998 | C++98 | 首个官方标准,引入STL,以模板重写标准库。 |
| 2003 | C++03 | 主要修订错误和漏洞,引入TR1库,强化稳定性。 |
| 2011 | C++11 | 革命性更新:引入auto、lambda、范围for、右值引用与移动语义、智能指针、标准线程库等。 |
| 2014 | C++14 | C++11的增强版,修复漏洞,引入泛型lambda、二进制字面常量等。 |
| 2017 | C++17 | 引入if constexpr、折叠表达式、结构化绑定,改进string和filesystem库。 |
| 2020 | C++20 | 重要里程碑:引入协程、概念(Concepts)、模块(Modules)、ranges等。 |
| 2023 | C++23 | 小版本更新,增加if consteval、flat_map、import std等特性。 |
| 2026 | C++26 | 制定中。 |
2.2 C++23的"网络库"小故事
C++一直被诟病缺乏标准的网络库 。原本计划在C++23中加入的networking,由于标准委员会内部的技术路线之争(如Asio与Senders/Receivers方案对立),最终被推迟到C++26。这次延期引发了社区的广泛讨论,也反映了C++标准制定过程中严谨与缓慢并存的现实。
3. C++参考文档
- [C++ Reference (Legacy)]:内容以C++11为主,但以头文件形式呈现,较易读。
- C++官方文档 (中文):信息全面,持续更新至最新标准。
- C++官方文档 (英文):信息最权威、最全面。
4. C++的重要性
4.1 编程语言排行榜
TIOBE排行榜反映编程语言的热门程度和流行趋势,虽不代表语言优劣,但能体现其市场占用率和社区活跃度。
4.2 应用领域
- 系统软件:如编译器、数据库、操作系统、浏览器等。
- 音视频处理:如FFmpeg、WebRTC等流媒体和开源方案,这是C++的核心技术栈。
- PC客户端开发:常用C++搭配Qt框架开发跨平台桌面应用,如WPS。
- 高性能服务端:游戏服务器、流媒体服务、量化高频交易系统等。
- 游戏引擎:如UE4、Cocos2d-x等,是游戏开发的核心语言。
- 嵌入式系统:从智能手环到车载系统,涉及驱动及应用开发。
- 机器学习引擎:底层核心算法用C++实现,上层由Python封装调用。
- 测试开发:开发自动化测试工具和性能测试脚本。
5. 学习建议与书籍推荐
- 学习建议 :
- 保证每节课后亲手练习课堂样例。
- 坚持写博客或笔记总结,尤其针对重点章节。
- 推荐书籍 :
- 《C++ Primer》:入门与系统学习语法的经典圣经。
- 《STL源码剖析》:深入学习STL实现原理,适合中后期。
- 《Effective C++》:提升C++编程习惯和效率的必读书籍。
6. C++的第一个程序
C++程序兼容C代码,其标准的Hello World程序引入了<iostream>输入输出流,并使用了命名空间std。
cpp
#include <iostream>
using namespace std; // 展开std命名空间
int main() {
cout << "Hello, World!" << endl;
return 0;
}
7. 命名空间
7.1 价值
为解决全局作用域中的命名冲突 问题,C++引入了namespace关键字,对标识符名称进行本地化隔离。
7.2 定义与特性
- 定义 :使用
namespace关键字,后跟空间名和一对大括号{},内部可定义变量、函数、类型。 - 本质 :定义了一个独立于全局域的命名空间域。不同域允许定义同名实体,从而避免冲突。
- 嵌套:命名空间可以嵌套定义。
- 合并:多文件中定义的同名命名空间会被编译器自动合并在一起。
cpp
namespace bit { // 以项目名称命名
int rand = 10;
int Add(int left, int right) { return left + right; }
}
7.3 使用方式
- 指定访问 (项目推荐):
bit::rand - 成员展开 (访问频繁无冲突时推荐):
using bit::rand; - 全展开 (练习推荐,项目禁忌):
using namespace bit;
8. C++输入与输出 (IO)
- 标准对象 :
std::cin(标准输入流),std::cout(标准输出流)。 - 运算符 :
<<(流插入,用于输出),>>(流提取,用于输入)。 - 优势 :无需像
printf/scanf那样手动指定格式,能自动识别变量类型(通过函数重载实现)。 - 注意 :
cout/cin/endl都位于std命名空间。项目开发中不推荐using namespace std。 - 效率优化 :在大量输入输出的场景下,可加入
ios_base::sync_with_stdio(false);等代码来提高IO效率。
9. 缺省参数
- 概念 :函数声明或定义时为参数指定的默认值。调用时若未传实参,则使用该默认值。
- 分类 :
- 全缺省:所有参数都有默认值。
- 半缺省 :仅部分参数有默认值,且必须从右向左依次连续给出,不能跳跃。
- 规则 :
- 调用时,实参必须从左到右依次传递。
- 声明与定义分离时,缺省参数只能在函数声明中给出。
10. 函数重载
C++允许在同一作用域内声明同名函数 ,只要它们的形参列表不同 (参数个数、类型或顺序不同)。这体现了编译时多态。注意:返回值类型不同不能作为重载的条件,因为调用处无法区分。
cpp
int Add(int left, int right); // 1. 参数类型不同
double Add(double left, double right);
void f(); // 2. 参数个数不同
void f(int a);
void f(int a, char b); // 3. 参数顺序不同
void f(char b, int a);
11. 引用
11.1 概念
引用是给一个已存在变量 取的别名。定义形式为类型& 别名 = 原变量;。引用和被引用变量共用同一块内存空间,编译器不会为引用开辟新空间。
11.2 核心特性
- 必须初始化:引用定义时必须绑定一个对象。
- 一夫一妻制 :引用一旦绑定一个实体,就不能更改去引用其他实体(Java等其他语言的引用可以)。
- 别名机制:一个变量可以有多个引用,也可以给别名起别名。
11.3 主要应用
- 做参数(引用传参):替代指针传参,通过修改引用变量来直接修改函数外部的实参,更安全方便,尤其能避免复杂的指针操作(如二级指针)。
- 做返回值(引用返回) :返回引用可以避免拷贝,提高效率,且可作为左值被修改。需确保返回对象的生命周期在函数调用后依然存在(不能返回局部变量的引用)。
11.4 const引用
- 可以对
const对象用const引用。 - 引用过程中,访问权限可以缩小,但不能扩大。
- 临时对象(如表达式结果、类型转换中间值)具有常性,因此只能用
const引用指向它们。
cpp
const int& ra = 30; // ra引用一个临时对象
const int& rd = d; // d是double,转换过程产生临时对象
11.5 指针与引用的区别
| 比较项 | 引用 | 指针 |
|---|---|---|
| 内存空间 | 语法上不开空间(别名) | 存储地址,需开辟空间 |
| 初始化 | 定义时必须初始化 | 语法上非必须,但建议初始化 |
| 指向更改 | 绑定后不能更改 | 可随时指向不同对象 |
| 访问方式 | 直接使用引用名 | 需用*解引用 |
| 安全性 | 相对更安全,无空/野引用 | 容易出现空指针、野指针等问题 |
12. 内联函数 (inline)
- 作用 :用
inline修饰的函数,编译器会在调用的地方将其展开,避免建立函数栈帧的开销,提高运行效率。常用于频繁调用的短小函数。 - 特性 :
inline只是一种建议,编译器有权忽略不展开(如对递归或长函数)。- 不能声明和定义分离:因为被展开后没有函数地址,分离到两个文件会导致链接错误。
- 目的:替代C语言中复杂且易出错的宏函数。
13. nullptr
- 传统问题 :
NULL在C++中常被定义为宏0,导致在函数重载时,f(NULL)会调用f(int)而非期望的f(int*),引发歧义。 - 解决方案 :C++11引入了
nullptr关键字,它只能被隐式转换为任意类型的指针 ,而不能转为整数,从根本上解决了空指针的重载歧义问题。建议在C++中统一使用nullptr表示空指针。
14. 总结
回顾C++入门基础的全貌,可以提炼出以下几条贯穿始终的学习主线:
1. 历史与定位:一门"演进型"语言
C++并非一蹴而就,其发展史(从C++98到C++26)本身就展现了系统级语言为平衡"极致性能"与"开发效率"所做的持续妥协与革新。理解其版本更迭,有助于明白为何不同项目会遇到不同风格的C++代码。
2. 语法体系:两大核心矛盾
入门阶段的所有语法点,本质上都在解决两个问题:
- 命名与作用域问题 :
namespace解决了全局命名冲突,是大型项目模块化的基石。 - 效率与安全性的平衡 :
引用对比指针更安全、内联函数替代宏更可靠、nullptr替代NULL消除歧义,这些都在保留C语言高性能的同时,强化了类型安全。
3. 编程范式:多态的最初体现
- 编译时多态:函数重载让我们看到,同一接口名称能应对不同参数,这是C++灵活性的初现。
- 默认行为:缺省参数是让接口"少即是多"的简洁设计。
4. 学习路径建议
作为入门基础,本章内容是后续深入理解面向对象、STL泛型编程的基石。建议在练习中反复体会以下三点:
- 把
namespace内化为习惯:从一开始就养成隔离代码的习惯。 - 吃透
引用的语义:它不仅是"别名",更是后续理解拷贝控制、右值引用的基础。 - 动手对比C与C++代码 :例如用引用重写链表操作、用
cout替代printf,感受C++在代码表达力上的提升。
掌握这些基础,你就拿到了深入C++高性能编程世界的敲门砖。接下来的学习将从"面向过程"逐步迈向"面向对象"与"泛型编程",而本章的每一个语法细节,都会在那里反复出现并发挥更大的作用。