C++第一讲:C++ 入门基础
文档内容按背景认知→核心语法 的逻辑分层梳理,每个知识点包含核心概念、用法规则、易错点,并搭配简化代码示例。
一、C++ 基础背景认知
1. 课程与学习规划
-
课程总时长:150 + 小时
-
核心内容:C++ 基础语法 → STL 标准模板库 → 高阶数据结构
-
学习建议:
-
每节课后手动敲一遍课堂示例代码,理解执行逻辑
-
重点章节整理笔记 / 博客,沉淀知识
-
先跟着课程学,再用经典书籍查漏补缺
-
2. 发展历史与版本迭代
C++ 由本贾尼・斯特劳斯特卢普 在 1983 年基于 C 语言设计,核心是增加面向对象编程特性,后续通过标准化不断演进:
| 版本 | 发布时间 | 核心特性 | 学习优先级 |
|---|---|---|---|
| C++98 | 1998 年 | 第一个官方标准,引入 STL | ✅ 必学(所有编译器支持) |
| C++11 | 2011 年 | 革命性更新:lambda、右值引用、智能指针、线程库 | ✅ 核心必学(现代 C++ 基础) |
| C++14/17 | 2014/2017 年 | 对 C++11 的补充:泛型 lambda、if constexpr、结构化绑定 | ⭐ 了解常用特性 |
| C++20/23 | 2020/2023 年 | 协程、概念、模块化、import std | ⭐ 进阶了解 |
3. 官方参考文档
-
入门友好:https://legacy.cplusplus.com/reference/(更新到 C++11,头文件形式呈现)
-
权威全面:https://zh.cppreference.com/w/cpp(中文官方文档,更新到最新标准)
4. 重要性与应用领域
-
2024 年 6 月 TIOBE 排行榜第 2 位,是性能敏感场景的首选语言
-
核心应用:游戏引擎(UE4/Unity 底层)、音视频处理(FFmpeg)、服务器后端、嵌入式开发、机器学习底层、操作系统 / 编译器开发
5. 经典书籍推荐
| 书籍 | 适用阶段 | 核心内容 |
|---|---|---|
| 《C++ Primer》 | 入门→进阶 | 全面讲解 C++ 语法,可作为语法字典 |
| 《STL 源码剖析》(侯捷) | 中期 | 深入 STL 底层实现,理解泛型编程 |
| 《Effective C++》 | 进阶 | 55 个高效使用 C++ 的最佳实践 |
二、C++ 核心语法入门
1. 第一个 C++ 程序
C++ 完全兼容 C 语言语法,但有自己的输入输出体系,代码文件后缀为.cpp。
cpp
// C语言风格(兼容)
#include <stdio.h>
int main() {
printf("hello world\n");
return 0;
}
// C++标准风格
#include <iostream> // 输入输出流头文件
using namespace std; // 展开标准命名空间(练习用,项目不推荐)
int main() {
cout << "hello world" << endl; // cout输出,endl换行+刷新缓冲区
return 0;
}
- 编译方式:Linux 下用
g++ test.cpp -o test,Windows 下 VS 编译器自动识别.cpp文件
2. 命名空间(namespace)
核心作用
解决命名冲突问题(C 语言中全局变量 / 函数重名会报错),本质是定义一个独立的作用域。
定义方式
cpp
// 1. 普通命名空间
namespace bit {
int rand = 10; // 与stdlib.h中的rand函数不冲突
int Add(int a, int b) { return a + b; }
struct Node { int val; struct Node* next; };
}
// 2. 嵌套命名空间
namespace bit {
namespace pg { int rand = 1; }
namespace hg { int rand = 2; }
}
// 3. 多文件同名命名空间会自动合并(项目中常用)
// Stack.h和Stack.cpp中都定义namespace bit,会合并为同一个
三种使用方式
cpp
#include <iostream>
namespace bit { int a = 0; int b = 1; }
int main() {
// 方式1:指定命名空间访问(项目推荐,无冲突)
std::cout << bit::a << std::endl;
// 方式2:展开单个成员(常用且无冲突的成员推荐)
using bit::b;
std::cout << b << std::endl;
// 方式3:展开整个命名空间(仅练习用,项目冲突风险大)
using namespace bit;
std::cout << a << " " << b << std::endl;
return 0;
}
3. C++ 输入输出(iostream)
核心对象
-
cin:标准输入流(对应键盘),用>>(流提取运算符) -
cout:标准输出流(对应屏幕),用<<(流插入运算符) -
endl:输出换行并刷新缓冲区
优势
自动识别变量类型,无需像printf/scanf手动指定格式符:
cpp
#include <iostream>
using namespace std;
int main() {
int a;
double b;
char c;
cin >> a >> b >> c; // 自动识别int、double、char类型
cout << a << " " << b << " " << c << endl;
return 0;
}
效率优化(竞赛 / 大数据输入必备)
cpp
int main() {
// 关闭与C语言IO同步,解除cin与cout绑定
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// 后续输入输出效率大幅提升
return 0;
}
4. 缺省参数(默认参数)
核心概念
声明 / 定义函数时为参数指定默认值,调用时不传参则使用默认值。
分类与规则
cpp
// 1. 全缺省:所有参数都有默认值
void Func1(int a = 10, int b = 20, int c = 30) {
cout << a << " " << b << " " << c << endl;
}
// 2. 半缺省:必须从右往左连续缺省,不能间隔
void Func2(int a, int b = 10, int c = 20) { // 正确
cout << a << " " << b << " " << c << endl;
}
// void Func2(int a = 10, int b, int c = 20) {} // 错误:中间参数不能缺省
int main() {
Func1(); // 输出:10 20 30
Func1(1); // 输出:1 20 30
Func1(1, 2, 3); // 输出:1 2 3
Func2(100); // 输出:100 10 20
Func2(100, 200); // 输出:100 200 20
return 0;
}
关键注意点
-
函数声明和定义分离时,缺省参数只能写在声明中,不能同时写在定义里
-
调用时必须从左到右传参,不能跳跃传参
5. 函数重载
核心概念
同一作用域中可以定义同名函数 ,但要求参数列表不同(参数个数、类型、顺序不同),C 语言不支持函数重载。
重载条件与反例
cpp
// 1. 参数类型不同
int Add(int a, int b) { return a + b; }
double Add(double a, double b) { return a + b; }
// 2. 参数个数不同
void f() { cout << "f()" << endl; }
void f(int a) { cout << "f(int)" << endl; }
// 3. 参数类型顺序不同
void f(int a, char b) { cout << "int, char" << endl; }
void f(char b, int a) { cout << "char, int" << endl; }
// ❌ 错误:返回值不同不能作为重载条件
// void fxx() {}
// int fxx() { return 0; }
// ❌ 错误:缺省参数导致调用歧义
// void f1() {}
// void f1(int a = 10) {}
// f1(); // 编译器不知道调用哪个
6. 引用(&)
核心概念
引用是变量的别名,编译器不会为引用开辟新的内存空间,它和原变量共用同一块内存。
语法与特性
cpp
int main() {
int a = 10;
int& b = a; // b是a的别名
int& c = a; // 一个变量可以有多个别名
int& d = b; // 别名的别名还是指向原变量
b = 20;
cout << a << endl; // 输出20,修改别名会影响原变量
cout << &a << " " << &b << endl; // 地址相同
// 特性1:引用定义时必须初始化
// int& ra; // 错误
// 特性2:引用一旦绑定一个变量,不能再绑定其他变量
int x = 30;
b = x; // 这是赋值,不是改变引用指向
cout << a << endl; // 输出30
return 0;
}
核心使用场景
- 引用传参:替代指针,简化代码,避免拷贝
cpp
// 交换两个变量(无需传地址)
void Swap(int& rx, int& ry) {
int tmp = rx;
rx = ry;
ry = tmp;
}
int main() {
int x = 0, y = 1;
Swap(x, y); // 直接传变量,无需&
cout << x << " " << y << endl; // 输出1 0
return 0;
}
- 引用返回值:减少拷贝,支持修改返回值(后续类和对象章节深入)
const 引用
-
权限可以缩小,不能放大:普通变量可以用 const 引用,const 变量不能用普通引用
-
临时对象具有常性,必须用 const 引用接收
cpp
int main() {
const int a = 10;
// int& ra = a; // 错误:权限放大
const int& ra = a; // 正确
int b = 20;
const int& rb = b; // 正确:权限缩小
// rb = 30; // 错误:const引用不能修改变量
// 临时对象(表达式结果、类型转换结果)必须用const引用
// int& r1 = a * 3; // 错误
const int& r1 = a * 3; // 正确
// int& r2 = 12.34; // 错误
const int& r2 = 12.34; // 正确
return 0;
}
引用与指针的区别
| 对比项 | 引用 | 指针 |
|---|---|---|
| 内存 | 不开辟空间,是变量别名 | 开辟空间,存储变量地址 |
| 初始化 | 定义时必须初始化 | 语法上可以不初始化(建议初始化) |
| 指向 | 绑定后不能改变 | 可以随时改变指向 |
| 访问 | 直接访问原变量 | 需要解引用* |
| 安全性 | 几乎不会出现空 / 野引用 | 容易出现空指针、野指针 |
7. 内联函数(inline)
核心作用
编译时在调用处展开函数,避免函数调用的栈帧开销,替代 C 语言的宏函数(宏函数易出错、难调试)。
用法与规则
cpp
// 频繁调用的短小函数适合用inline
inline int Add(int x, int y) {
return x + y;
}
int main() {
int ret = Add(1, 2);
// 编译后展开为:int ret = 1 + 2; 无call Add指令
return 0;
}
关键注意点
-
inline只是给编译器的建议,编译器可能忽略(递归函数、代码过长的函数不会展开) -
内联函数不能声明和定义分离(分离会导致链接错误,因为展开后没有函数地址)
8. nullptr(C++11)
为什么需要 nullptr
C++ 中NULL本质是宏,定义为0或(void*)0,会导致函数重载歧义:
cpp
void f(int x) { cout << "int" << endl; }
void f(int* ptr) { cout << "int*" << endl; }
int main() {
f(0); // 调用f(int)
f(NULL); // 本意调用f(int*),但实际调用f(int)(因为NULL是0)
f(nullptr); // 正确调用f(int*)
return 0;
}
核心特性
-
nullptr是 C++11 关键字,专门表示空指针 -
只能隐式转换为指针类型,不能转换为整数类型
-
所有指针类型都可以用
nullptr初始化
三、下一步学习建议
-
先把上述所有语法点的代码示例手动敲一遍,验证执行结果
-
重点攻克引用 和函数重载,这是 C++ 区别于 C 语言的核心基础
-
接下来学习类和对象(封装、继承、多态),这是 C++ 面向对象编程的核心