C++语法大全笔记
C++ 是一门融合面向过程、面向对象和泛型编程的多范式编程语言,语法体系庞大且灵活。以下笔记按模块梳理核心语法,兼顾基础与进阶,便于系统学习和查阅。
一、基础语法与环境
1. 程序结构
C++ 程序的基本单元是函数,入口为
main()函数:cpp
运行
#include <iostream> // 头文件包含(输入输出流)
using namespace std; // 命名空间(避免std::前缀)
int main() { // 主函数(返回int类型)
cout << "Hello, C++!" << endl; // 输出语句
return 0; // 返回值(0表示正常结束)
}
2. 编译与运行
- 编译命令(g++):
g++ 文件名.cpp -o 可执行文件名 - 运行(Windows):
可执行文件名.exe;(Linux/Mac):./可执行文件名
二、数据类型与变量
1. 基本数据类型
| 类型 | 说明 | 大小(字节) | 示例 |
|---|---|---|---|
bool |
布尔型 | 1 | true/false |
char |
字符型 | 1 | 'a'/'\n' |
int |
整型 | 4 | 10/-5 |
float |
单精度浮点型 | 4 | 3.14f |
double |
双精度浮点型 | 8 | 3.1415926 |
void |
无类型(用于函数) | - | void func() |
2. 修饰符
- 符号修饰:
signed(默认)、unsigned(无符号) - 长度修饰:
short(短整型)、long(长整型)、long long(超长整型)示例:unsigned int age = 20;、long long num = 1e18;
3. 变量声明与初始化
- 声明:
类型 变量名;(如int a;) - 初始化:
类型 变量名 = 值;(如int a = 10;) - 列表初始化(C++11+):
int a{10};(更安全,避免窄化转换)
三、运算符
1. 算术运算符
+(加)、-(减)、*(乘)、/(除)、%(取模)、++(自增)、--(自减)- 注意:整数除法取整(如
5/2=2),%仅适用于整数。
2. 关系运算符
==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)返回值为bool类型(true/false)。3. 逻辑运算符
&&(与)、||(或)、!(非)- 短路特性:
&&左侧为false时右侧不执行;||左侧为true时右侧不执行。
4. 赋值运算符
=(赋值)、+=(加等于)、-=(减等于)、*=(乘等于)、/=(除等于)、%=(模等于)5. 位运算符(操作二进制)
&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)示例:3 << 1(3 的二进制11左移 1 位为110,即 6)。6. 三目运算符
条件 ? 表达式1 : 表达式2(条件为真执行表达式 1,否则执行表达式 2)示例:int max = a > b ? a : b;四、控制流语句
1. 分支语句
(1)if-else
cpp
运行
if (条件1) {
// 条件1为真执行
} else if (条件2) {
// 条件2为真执行
} else {
// 都不满足执行
}
(2)switch
cpp
运行
switch (变量/表达式) {
case 常量1:
// 执行语句
break; // 跳出switch(否则穿透)
case 常量2:
// 执行语句
break;
default: // 所有case不匹配时执行
// 执行语句
}
2. 循环语句
(1)for循环
cpp
运行
for (初始化; 条件; 更新) {
// 循环体
}
// 示例:遍历0-9
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
(2)while循环
cpp
运行
while (条件) {
// 循环体(先判断后执行)
}
(3)do-while循环
cpp
运行
do {
// 循环体(先执行后判断,至少执行一次)
} while (条件);
3. 跳转语句
break:跳出当前循环或switchcontinue:跳过当前循环剩余语句,进入下一次循环return:终止函数并返回值(或无返回值)goto:跳转到标签位置(不推荐,易导致代码混乱)示例:goto end; ... end: cout << "结束";
五、数组与字符串
1. 数组
(1)一维数组
- 声明:
类型 数组名[大小];(如int arr[5];) - 初始化:
int arr[5] = {1,2,3};(未初始化元素为 0)、int arr[] = {1,2,3};(自动推导大小) - 访问:
数组名[索引](索引从 0 开始,如arr[0])
(2)二维数组
- 声明:
类型 数组名[行][列];(如int mat[2][3];) - 初始化:
int mat[2][3] = {{1,2},{3,4}}; - 访问:
mat[行索引][列索引](如mat[0][1] = 2;)
2. 字符串
(1)C 风格字符串(字符数组)
- 声明:
char str[10] = "hello";(末尾自动加\0结束符) - 常用函数(需包含
<cstring>):strlen(str)(长度)、strcpy(str1, str2)(复制)、strcmp(str1, str2)(比较)、strcat(str1, str2)(拼接)
(2)C++ 风格字符串(string类)
需包含
<string>头文件,支持便捷操作:cpp
运行
string s = "hello";
s += " world"; // 拼接
cout << s.size(); // 长度(输出11)
cout << s.substr(0,5); // 子串(输出hello)
六、函数
1. 函数定义与声明
(1)定义格式
cpp
运行
返回值类型 函数名(参数列表) {
// 函数体
return 返回值; // 无返回值则省略(void类型)
}
示例:
cpp
运行
int add(int a, int b) {
return a + b;
}
(2)声明(原型)
当函数定义在调用之后时,需提前声明:
cpp
运行
int add(int a, int b); // 声明
int main() {
cout << add(1,2); // 调用
return 0;
}
int add(int a, int b) { // 定义
return a + b;
}
2. 参数传递
- 值传递:传递副本,函数内修改不影响实参
- 引用传递:传递别名,函数内修改影响实参(
类型& 形参)示例:cpp运行void swap(int &a, int &b) { int temp = a; a = b; b = temp; } - 指针传递:传递地址,函数内通过
*指针修改实参(类型* 形参)示例:cpp运行void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
3. 函数重载
同一作用域内,函数名相同但参数列表(类型 / 个数 / 顺序)不同,称为重载:
cpp
运行
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }
4. 默认参数
函数参数可指定默认值(需从右往左连续指定):
cpp
运行
int add(int a, int b = 10) { return a + b; }
// 调用:add(5) → 15;add(5,20) → 25
5. 内联函数(inline)
用
inline修饰,编译器尝试将函数体直接嵌入调用处,减少函数调用开销(适用于短小函数):cpp
运行
inline int square(int x) { return x * x; }
七、指针与引用
1. 指针
指针是存储变量地址的变量,类型为
类型*:cpp
运行
int a = 10;
int *p = &a; // p指向a的地址(&取地址符)
cout << *p; // *解引用,输出a的值(10)
*p = 20; // 修改a的值为20
(1)空指针与野指针
- 空指针:
int *p = nullptr;(C++11+,替代NULL) - 野指针:未初始化或指向已释放内存的指针(需避免)
(2)指针与数组
数组名本质是指向首元素的指针:
cpp
运行
int arr[5] = {1,2,3};
cout << *arr; // 输出1(首元素)
cout << *(arr+1); // 输出2(第二个元素)
2. 引用
引用是变量的别名,用
类型&声明,必须初始化且不可更改指向:cpp
运行
int a = 10;
int &ref = a; // ref是a的别名
ref = 20; // a的值变为20
引用 vs 指针
| 特性 | 引用 | 指针 |
|---|---|---|
| 初始化 | 必须初始化 | 可延迟初始化 |
| 指向修改 | 不可改 | 可改 |
| 空值 | 无空引用 | 有空指针 |
| 语法 | 无需解引用 | 需解引用(*) |
八、结构体与枚举
1. 结构体(struct)
用于封装不同类型的数据:
cpp
运行
struct Student {
string name;
int age;
float score;
};
// 使用
Student s1 = {"Alice", 18, 90.5};
cout << s1.name << endl;
2. 枚举(enum/enum class)
(1)普通枚举
cpp
运行
enum Color { Red, Green, Blue }; // 默认Red=0, Green=1, Blue=2
Color c = Red;
(2)强类型枚举(C++11+)
类型安全,需指定作用域:
cpp
运行
enum class Direction { Left, Right };
Direction d = Direction::Left;
九、面向对象编程(OOP)
1. 类与对象
类是 ** 数据(成员变量)和行为(成员函数)** 的封装,对象是类的实例:
cpp
运行
class Person {
private: // 私有成员(仅类内访问)
string name;
int age;
public: // 公有成员(外部可访问)
// 构造函数(初始化对象)
Person(string n, int a) : name(n), age(a) {}
// 成员函数
void showInfo() {
cout << "Name: " << name << ", Age: " << age << endl;
}
// 析构函数(释放资源)
~Person() {}
};
// 创建对象
Person p("Bob", 20);
p.showInfo();
2. 访问控制
public:类内 / 外均可访问private:仅类内访问(默认)protected:类内 / 子类可访问
3. 构造函数与析构函数
(1)构造函数
- 与类名相同,无返回值
- 重载:支持多个构造函数
- 默认构造函数:无参构造(若未定义,编译器自动生成)
- 拷贝构造函数:用已有对象初始化新对象(
类名(const 类名& 其他对象))
(2)析构函数
- 名称为
~类名,无返回值、无参数 - 对象销毁时自动调用(如局部对象离开作用域)
4. 继承
子类继承父类的成员,实现代码复用:
cpp
运行
// 父类
class Animal {
public:
void eat() { cout << "Eating..." << endl; }
};
// 子类(public继承)
class Dog : public Animal {
public:
void bark() { cout << "Barking..." << endl; }
};
// 使用
Dog d;
d.eat(); // 继承父类方法
d.bark(); // 子类自有方法
继承方式
public:父类public→子类public,protected→子类protectedprotected:父类public/protected→子类protectedprivate:父类public/protected→子类private
5. 多态
(1)静态多态(编译时)
通过函数重载或模板实现
(2)动态多态(运行时)
通过虚函数实现:父类指针 / 引用指向子类对象时,调用子类重写的方法
cpp
运行
class Animal {
public:
virtual void makeSound() { // 虚函数
cout << "Animal sound" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override { // 重写
cout << "Meow" << endl;
}
};
// 使用
Animal *p = new Cat();
p->makeSound(); // 输出Meow(动态多态)
delete p;
纯虚函数与抽象类
纯虚函数:
virtual 返回值 函数名() = 0;,包含纯虚函数的类为抽象类(不能实例化),子类必须重写纯虚函数:cpp
运行
class Shape {
public:
virtual double area() = 0; // 纯虚函数
};
class Circle : public Shape {
private:
double r;
public:
Circle(double r) : r(r) {}
double area() override { return 3.14 * r * r; }
};
6. 封装与抽象
- 封装:通过访问控制(
private)隐藏内部细节,仅暴露接口(public) - 抽象:通过抽象类 / 纯虚函数提取共性,屏蔽具体实现
十、模板
模板是泛型编程的核心,实现代码的参数化:
1. 函数模板
cpp
运行
template <typename T> // 模板参数(T为类型占位符)
T max(T a, T b) {
return a > b ? a : b;
}
// 使用
cout << max(1, 2); // T=int
cout << max(3.14, 2.5); // T=double
2. 类模板
cpp
运行
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() { return value; }
};
// 使用
Box<int> b1(10);
Box<string> b2("hello");
十一、STL(标准模板库)
STL 包含容器、算法、迭代器三大核心:
1. 容器
(1)序列容器
vector:动态数组(随机访问快)cpp运行vector<int> vec = {1,2,3}; vec.push_back(4); // 尾部添加 cout << vec[2]; // 访问第3个元素list:双向链表(插入删除快)deque:双端队列(头尾操作快)
(2)关联容器
map:键值对(有序,红黑树)cpp运行map<string, int> mp; mp["Alice"] = 90; cout << mp["Alice"]; // 输出90unordered_map:无序键值对(哈希表,查询更快)set:有序集合(无重复元素)
(3)容器适配器
stack:栈(后进先出)queue:队列(先进先出)
2. 算法(需包含<algorithm>)
- 排序:
sort(vec.begin(), vec.end()); - 查找:
find(vec.begin(), vec.end(), 3); - 遍历:
for_each(vec.begin(), vec.end(), [](int x){cout << x;});
3. 迭代器
遍历容器的工具,类似指针:
cpp
运行
vector<int> vec = {1,2,3};
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << endl;
}
十二、异常处理
捕获并处理运行时错误:
cpp
运行
try {
int a = 10, b = 0;
if (b == 0) {
throw "Division by zero!"; // 抛出异常
}
cout << a / b;
} catch (const char* msg) { // 捕获异常
cout << "Error: " << msg << endl;
} catch (...) { // 捕获所有其他异常
cout << "Unknown error" << endl;
}
十三、C++11 及以上新特性
- 自动类型推导:
auto(根据初始化推导类型,如auto x = 10;) - 范围 for 循环:
for (int x : vec) { cout << x; } - Lambda 表达式:匿名函数(
[捕获](参数){函数体}) - 智能指针:
unique_ptr(独占所有权)、shared_ptr(共享所有权),避免内存泄漏cpp运行unique_ptr<int> p(new int(10)); cout << *p; // 输出10 - nullptr:空指针常量(替代
NULL) - 右值引用:
&&,支持移动语义(减少拷贝)
十四、常见坑与注意事项
- 数组越界:访问
arr[size]会导致未定义行为 - 内存泄漏:
new分配的内存未用delete释放(建议用智能指针) - 悬空指针:指向已释放内存的指针
- 类的拷贝:未定义拷贝构造函数时,浅拷贝可能导致资源重复释放
- 虚函数:父类析构函数未声明为虚函数,子类对象通过父类指针销毁时可能不调用子类析构

浙公网安备 33010602011771号