目录
[一、C++ 发展与版本更新](#一、C++ 发展与版本更新)
[1. 发展起源](#1. 发展起源)
[二、C++ 核心基础语法(入门必掌握)](#二、C++ 核心基础语法(入门必掌握))
[1. 第一个 C++ 程序:Hello World](#1. 第一个 C++ 程序:Hello World)
[2. 命名空间(namespace):解决命名冲突](#2. 命名空间(namespace):解决命名冲突)
[3. C++ 输入输出(cin/cout)](#3. C++ 输入输出(cin/cout))
[4. 缺省参数(默认参数):函数参数的默认值](#4. 缺省参数(默认参数):函数参数的默认值)
[5. 函数重载:C++ 的多态特性(入门)](#5. 函数重载:C++ 的多态特性(入门))
[6. 引用(&):变量的别名(C++ 核心语法,必吃透)](#6. 引用(&):变量的别名(C++ 核心语法,必吃透))
[7. 内联函数(inline):替代 C 语言宏函数](#7. 内联函数(inline):替代 C 语言宏函数)
[8. nullptr:C++11 的空指针常量](#8. nullptr:C++11 的空指针常量)
[三、C++ 参考文档(开发必备)](#三、C++ 参考文档(开发必备))
一、C++ 发展与版本更新
1. 发展起源
C++ 由本贾尼・斯特劳斯特卢普 于 1979 年在贝尔实验室研发,初衷是解决 C 语言在面向对象、可维护性、可扩展性上的不足,1983 年正式命名为 C++,1998 年发布第一个 ANSI/ISO 官方标准(C++98),并引入 STL(标准模板库)成为核心特性
二、C++ 核心基础语法(入门必掌握)
C++ 兼容 C 语言绝大多数语法,但新增了面向对象、命名空间、引用、函数重载等核心特性,以下是入门阶段必须吃透的语法点,按 "基础到进阶" 排序。
1. 第一个 C++ 程序:Hello World
C++ 有C 语言兼容版 和原生版 两种写法,核心区别是输入输出流 ,原生版使用 C++ 的iostream库,无需手动指定格式,更符合 C++ 特性。
cpp
// C++原生版Hello World
#include<iostream>
using namespace std; // 展开标准命名空间,方便使用cout/endl
int main()
{
cout << "hello world" << endl; // cout=输出流,endl=换行+刷新缓冲区
return 0;
}
编译注意 :C++ 文件后缀为.cpp,Windows(VS)自动调用 C++ 编译器,Linux 需用g++编译(而非 C 的gcc)。
2. 命名空间(namespace):解决命名冲突
核心问题
C 语言中所有变量、函数都在全局作用域 ,容易出现重定义(如自定义rand和库函数rand冲突),C++ 引入namespace实现作用域隔离。
核心特性
- 命名空间是独立的域,与全局域、局部域、类域分离,不同域可定义同名标识符;
- 只能定义在全局作用域,支持嵌套定义 ,多文件中同名命名空间会自动合并;
- C++ 标准库的所有内容都在std命名空间中(如 cout、cin、STL 容器)。
三种使用方式:
| 使用方式 | 语法 | 适用场景 | 推荐度 |
|---|---|---|---|
| 指定命名空间 | xh::rand |
项目开发(避免冲突) | ✅✅✅(强烈推荐) |
| 展开单个成员 | using xh::Add |
频繁使用的单个成员,无冲突风险 | ✅✅ |
| 展开全部成员 | using namespace xh |
日常小练习(方便快捷) | ❌(项目禁止,冲突风险极高) |
示例:解决 rand 重定义问题
cpp
#include <stdio.h>
#include <stdlib.h>
namespace xh // 自定义命名空间
{
int rand = 10; // 与库函数rand不冲突
}
int main()
{
printf("%p\n", rand); // 访问全局库函数rand
printf("%d\n", xh::rand); // 访问bit命名空间的rand
return 0;
}

3. C++ 输入输出(cin/cout)
基于<iostream>库,核心是流插入(<<)**和**流提取(>>) ,相比 C 的printf/scanf有 2 个核心优势:
- 自动识别变量类型 ,无需手动指定
%d/%lf/%c等格式符; - 更好支持自定义类型(如类对象的输入输出,后续面向对象重点)。
cpp
#include<iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.1;
char c = 'x';
cin >> a >> b >> c; // 输入,自动识别类型
cout << a << " " << b << " " << c << endl; // 输出,endl换行
return 0;
}
性能优化(竞赛 / 大量输入场景)
C++IO 流默认与 C 标准 IO 同步,效率较低,添加以下代码可关闭同步,提升效率:
cpp
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
4. 缺省参数(默认参数):函数参数的默认值
定义:
声明 / 定义函数时为参数指定默认值,调用时若不传该参数,则使用默认值;若传参,则使用实参。
分类
- 全缺省:所有参数都指定默认值;
- 半缺省 :部分参数指定默认值,必须从右往左连续指定,不能间隔(C++ 语法强制要求)。
cpp
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func1();
Func1(1);
Func1(1, 2);
Func1(1, 2, 3);
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
}

核心规则
- 函数调用时,实参必须从左到右依次传递,不能跳跃传参;
- 函数声明和定义分离 时,缺省参数只能在声明中指定(头文件),定义中不能重复(避免二义性)。
示例:栈初始化的缺省参数(实战常用)
cpp
// 头文件Stack.h(声明)
typedef int STDataType;
typedef struct Stack {
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps, int n = 4); // 半缺省,n默认值4
// 源文件Stack.cpp(定义)
void STInit(ST* ps, int n) // 不能再写n=4
{
ps->a = (STDataType*)malloc(n * sizeof(STDataType));
ps->top = 0;
ps->capacity = n;
}
// 调用
int main()
{
ST s1;
STInit(&s1); // 不传n,使用默认值4
ST s2;
STInit(&s2, 1000); // 传n,使用实参1000(避免扩容,提升效率)
return 0;
}
5. 函数重载:C++ 的多态特性(入门)
定义:
同一作用域 中,函数名相同 ,但形参列表不同 (参数个数 / 类型 / 顺序不同)的多个函数,称为函数重载,C 语言不支持(因为 C 语言通过函数名唯一标识函数)。
核心规则
- 返回值不同不能作为重载条件(调用时编译器无法区分);
- 缺省参数可能导致重载歧义(如无参函数和单缺省参数函数,调用时不传参会报错);
- 形参的const/volatile 属性不同,可作为重载条件(后续进阶)。
示例:函数重载的三种合法形式
cpp
#include<iostream>
using namespace std;
// 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" << endl; }
// 3. 参数顺序不同
void f(int a, char b) { cout << "int+char" << endl; }
void f(char b, int a) { cout << "char+int" << endl; }
int main()
{
Add(1,2); // 调用int版Add
Add(1.1,2.2); // 调用double版Add
f(); // 调用无参f
f(1); // 调用单参f
f(1, 'a'); // 调用int+char版f
f('a', 1); // 调用char+int版f
return 0;
}

6. 引用(&):变量的别名(C++ 核心语法,必吃透)
定义:
引用不是新定义变量,而是给已存在的变量取别名 ,编译器不为引用开辟内存,引用和原变量共用同一块内存空间 ,语法:类型& 引用名 = 原变量;。
三大核心特性(语法强制要求,记死)
- 定义时必须初始化(不能先定义后赋值);
- 一个变量可以有多个别名(多个引用指向同一个变量);
- 引用一旦指向某个变量,就不能再指向其他变量(终身绑定)。
基础示例
cpp
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a; // b是a的别名
int& c = a; // c也是a的别名
b = 20; // 修改变名,原变量也改变
cout << a << " " << b << " " << c << endl; // 输出20 20 20
cout << &a << " " << &b << " " << &c << endl; // 地址完全相同
return 0;
}

错误例子(改变已经引用的变量):

实战用途(核心:减少拷贝 + 修改原变量,替代指针的部分场景)
1引用传参:替代指针,简化代码,同时实现 "修改原变量" 的效果(如交换函数、栈操作)
cpp
#include <iostream>
using namespace std;
// 引用传参实现交换,无需指针,更简洁
void Swap(int& x, int& y)
{
int tmp = x; // 保存x的原始值
x = y; // 将y的值赋给x(直接操作原变量)
y = tmp; // 将原始x的值赋给y(直接操作原变量)
}
int main()
{
// 1. 定义两个待交换的变量
int a = 10, b = 20;
// 2. 打印交换前的值
cout << "交换前: a = " << a << ", b = " << b << endl;
// 3. 调用Swap函数(直接传变量名,无需取地址)
Swap(a, b);
// 4. 打印交换后的值,验证交换效果
cout << "交换后: a = " << a << ", b = " << b << endl;
return 0;
}
2引用返回值:函数返回值为引用,可直接修改返回的变量,同时减少值拷贝的性能损耗(如栈顶元素获取);
3替代二级指针 :在链表 / 树的开发中,用指针的引用 (如LTNode*& phead)替代二级指针,简化代码。
const 引用(常引用):权限的控制
核心是控制变量的访问权限 ,C++ 中引用的权限只能缩小,不能放大,这是 const 引用的核心规则:
- 普通引用:只能指向普通变量,不能指向 const 变量(权限放大,编译报错);
- const 引用 :可以指向const 变量 (权限匹配),也可以指向普通变量(权限缩小),但不能通过 const 引用修改原变量;
- 临时对象 :表达式计算(如
a*3)、类型转换(如double→int)会产生临时对象 ,临时对象具有常性,只能用 const 引用指向。
示例:const 引用的合法 / 非法使用
cpp
#include <iostream>
using namespace std;
int main()
{
const int a = 10;
//a= 20; // 非法:常量不能修改值
// int& ra = a; // 非法:权限放大(普通引用指向const变量)
const int& ra = a; // 合法:权限匹配
// ra = 20; // 非法:不能通过const引用修改原变量
cout << a << " " << ra << endl; // 输出:10 10
int b = 20;
b = 30; // 合法:普通变量可以修改值
const int& rb = b; // 合法:权限缩小(const引用指向普通变量)
// rb = 30; // 非法:不能通过const引用修改原变量
b= 40; // 合法:普通变量可以修改值
cout << b << " " << rb << endl; // 输出:40 40
// int& rc = b*3; // 非法:临时对象具有常性,普通引用不能指向
const int& rc = b * 3; // 合法:const引用指向临时对象
cout << rc << endl; // 输出:120
double d = 12.34;
// int& rd = d; // 非法:类型转换产生临时对象,普通引用不能指向
const int& rd = d; // 合法:const引用指向临时对象
// 常量表达式
//int& rf = 30;//非法:非常量引用的初始值必须为左值
const int& rf = 30;//合法:常量表达式可以作为左值
cout << rf << endl; // 输出:30
return 0;
}

引用与指针的区别(入门必背,理解核心差异)
C++ 中引用和指针功能重叠,但互相不可替代,核心差异如下:
| 特性 | 引用 | 指针 |
|---|---|---|
| 内存开辟 | 不开辟,只是别名 | 开辟内存,存储变量地址 |
| 初始化 | 定义时必须初始化 | 语法上不强制初始化(建议初始化) |
| 指向修改 | 一旦绑定,不能修改指向 | 可以随时修改指向的变量 |
| 访问方式 | 直接访问(如b = 20) |
解引用访问(如*p = 20) |
| sizeof 含义 | 引用类型的大小(如int&为 4) |
地址的大小(32 位 4 字节,64 位 8 字节) |
| 安全性 | 无空引用 / 野引用,更安全 | 有空指针 / 野指针,风险较高 |
7. 内联函数(inline):替代 C 语言宏函数
定义:
用inline修饰的函数,编译时编译器会在调用处直接展开函数体 ,无需建立栈帧,从而提升函数调用效率。
核心特性
- 编译器的建议 :
inline只是给编译器的 "建议",编译器可拒绝展开(如递归函数、代码量过大的函数); - 适用场景 :频繁调用的短小函数(如 Add、Swap),递归 / 长函数加 inline 会被编译器忽略;
- 声明定义不能分离 :inline 函数若在头文件声明、源文件定义,会导致链接错误(因为函数被展开,无函数地址);
- 替代 C 宏函数 :C 语言宏函数通过预处理展开,无类型检查、易出错、不方便调试,inline 函数保留宏的效率,同时具备函数的类型检查、调试友好特性。
示例:inline 函数的使用
cpp
#include<iostream>
using namespace std;
// 频繁调用的短小函数,加inline提升效率
inline int Add(int x, int y)
{
return x + y;
}
int main()
{
int ret = Add(1,2); // 编译时直接展开为ret = 1+2,无栈帧建立
return 0;
}
宏版本的实现代码
cpp
#include<iostream>
using namespace std;
// 定义加法宏函数(注意:宏的结尾不能加分号)
#define ADD(x, y) ((x) + (y))
int main()
{
int ret = ADD(1, 2); // 预处理阶段直接替换为 ((1) + (2))
cout << "ret = " << ret << endl; // 输出:ret = 3
// 扩展示例:验证宏的替换特性(也能看出宏的坑)
int a = 10, b = 20;
int ret2 = ADD(a++, b++); // 替换为 ((a++) + (b++)),a和b会被自增1次!
cout << "ret2 = " << ret2 << endl; // 输出:ret2 = 30
cout << "a = " << a << ", b = " << b << endl; // 输出:a = 11, b = 21
return 0;
}
宏的核心特性
- 宏是预处理阶段 (编译前)进行文本替换 ,而非函数调用,因此也没有栈帧建立的开销(这是宏和
inline的共同优点); - 宏定义的语法:
#define 宏名(参数) 替换内容,结尾不能加分号(否则替换后会多加分号导致语法错误); - 替换内容和参数必须加足够的括号(比如上面的
((x) + (y))),否则会因运算符优先级导致错误(比如ADD(1+2, 3*4)如果不加括号会变成1+2+3*4,结果不符合预期)。
8. nullptr:C++11 的空指针常量
问题背景
C 语言中的NULL是宏 ,在 C++ 中被定义为0,导致函数重载的歧义 (如调用f(int*)时,传NULL会被解析为0,调用f(int))。
核心特性
nullptr是 C++11 的关键字 ,是特殊的空指针字面量;- 只能被隐式转换为指针类型,不能转换为整数类型,彻底解决 NULL 的歧义问题;
- 所有需要表示 "空指针" 的场景,都用
nullptr替代NULL(C++11 及以后推荐)。
示例:nullptr 解决重载歧义
cpp
#include<iostream>
using namespace std;
void f(int x) { cout << "f(int)" << endl; }
void f(int* p) { cout << "f(int*)" << endl; }
int main()
{
f(0); // 调用f(int)
f(NULL); // 调用f(int)(因为NULL=0)
f((int*)NULL); // 强制转换,调用f(int*)
f(nullptr); // 调用f(int*)(正确的空指针用法,C++11推荐)
return 0;
}

三、C++ 参考文档(开发必备)
推荐 3 个核心文档,按需使用,优先使用 cppreference(官方):
- legacy.cplusplus.com:非官方,仅更新到 C++11,优点是按头文件组织,易看易懂,适合入门;
- C++ 官方文档中文版:官方,更新到最新标准,信息最全,适合进阶 / 开发;
- C++ 官方文档英文版:官方原版,内容最准确,适合查阅英文原版定义。