前置知识: C

C++ 基础语法

5 min入门

C++ 基本语法、注释、标识符与关键字。

前置知识

学习目标

  • 掌握「1. 数据类型 (Data Types)」的核心机制、典型用法与常见陷阱
  • 掌握「2. 控制流 (Control Flow)」的核心机制、典型用法与常见陷阱
  • 掌握「3. 输入输出 (I/O)」的核心机制、典型用法与常见陷阱
  • 掌握「4. 命名空间 (Namespace)」的核心机制、典型用法与常见陷阱
  • 掌握「5. 作用域 (Scope)」的核心机制、典型用法与常见陷阱

1. 数据类型 (Data Types)

C++ 具有丰富的类型系统,分为基本类型和复合类型。

1.1 基本数据类型

类型描述大小 (字节)示例
整数类型
char字符1char c = 'A';
unsigned char无符号字符1unsigned char uc = 255;
short短整数2short s = 32767;
unsigned short无符号短整数2unsigned short us = 65535;
int整数4int x = 10;
unsigned int无符号整数4unsigned int ux = 4294967295;
long长整数4 或 8long l = 1000000;
unsigned long无符号长整数4 或 8unsigned long ul = 1000000;
long long长长整数 (C++11)8long long ll = 10000000000;
unsigned long long无符号长长整数 (C++11)8unsigned long long ull = 18446744073709551615;
浮点类型
float单精度浮点数4float f = 3.14f;
double双精度浮点数8double d = 3.1415926535;
long double长双精度浮点数8 或 16long double ld = 3.14159265358979323846;
布尔类型
bool布尔值1bool is_valid = true;

注意:C++ 标准只规定各类型的最小宽度与相对大小,具体字节数随平台变化。 表中「4 或 8」的典型差异来自系统 ABI:long 在 Windows(MSVC)上为 4 字节, 在 Linux/macOS 上为 8 字节。需要固定位宽时使用 <cstdint> 中的 int32_t/int64_t 等定宽类型。 | 空类型 | | | | | void | 无类型 | - | 用于函数返回或通用指针 |

1.2 复合数据类型

类型描述示例
数组相同类型元素的集合int arr[5] = {1, 2, 3, 4, 5};
字符串字符序列std::string s = "Hello C++";
指针存储内存地址int* p = &x;
引用变量的别名int& ref = x;
结构体不同类型成员的集合struct Person { std::string name; int age; };
联合体共用内存的不同类型union Data { int i; float f; char c; };
枚举命名常量集合enum Color { RED, GREEN, BLUE };
类面向对象的类型class MyClass { /* ... */ };

1.3 类型修饰符

修饰符描述示例
signed有符号类型 (默认)signed int x = -10;
unsigned无符号类型unsigned int y = 10;
short短类型short s = 100;
long长类型long l = 1000000;
const常量类型const int MAX = 100;
volatile易变类型volatile int flag = 0;
constexpr编译期常量 (C++11)constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n-1); }
auto自动类型推断 (C++11)auto i = 10;
decltype类型推导 (C++11)decltype(i) j = 20;

1.4 类型转换

1.4.1 隐式类型转换

 int i = 10;
 double d = i; // 隐式转换:int -> double
 char c = 'A';
 i = c; // 隐式转换:char -> int

1.4.2 显式类型转换

 // C 风格转换
 double d = 3.14;
 int i = (int)d; // 截断小数部分
 // C++ 风格转换
 // static_cast: 静态类型转换
 i = static_cast<int>(d);
 // dynamic_cast: 动态类型转换(用于多态)
 Base* base = new Derived();
 Derived* derived = dynamic_cast<Derived*>(base);
 // const_cast: 移除 const 修饰
 const int& const_ref = i;
 int& ref = const_cast<int&>(const_ref);
 // reinterpret_cast: 重新解释类型
 int* p = &i;
 long addr = reinterpret_cast<long>(p);

2. 控制流 (Control Flow)

2.1 条件判断

2.1.1 if 语句

 // 基本 if 语句
 int score = 85;
 if (score >= 90) {
  std::cout << "优秀" << std::endl;
 }
  std::cout << "良好" << std::endl;
 }
  std::cout << "及格" << std::endl;
 }
  std::cout << "不及格" << std::endl;
 }
 // 嵌套 if 语句
 int x = 10, y = 20;
 if (x > 0) {
  if (y > 0) {
  std::cout << "x 和 y 都是正数" << std::endl;
  } else {
  std::cout << "x 是正数,y 不是正数" << std::endl;
  }
 }
 // 使用逻辑运算符
 int a = 5, b = 10, c = 15;
 if (a > 0 && b > 0 && c > 0) {
  std::cout << "所有数都是正数" << std::endl;
 }
 if (a > 10 || b > 10 || c > 10) {
  std::cout << "至少有一个数大于 10" << std::endl;
 }

2.1.2 switch 语句

 // 基本 switch 语句
 int day = 3;
 switch (day) {
  case 1:
  std::cout << "星期一" << std::endl;
  break;
  case 2:
  std::cout << "星期二" << std::endl;
  break;
  case 3:
  std::cout << "星期三" << std::endl;
  break;
  case 4:
  std::cout << "星期四" << std::endl;
  break;
  case 5:
  std::cout << "星期五" << std::endl;
  break;
  case 6:
  case 7:
  std::cout << "周末" << std::endl;
  break;
  default:
  std::cout << "无效的日期" << std::endl;
  break;
 }
 // 使用枚举的 switch 语句
 enum Color { RED, GREEN, BLUE };
 Color color = GREEN;
 switch (color) {
  case RED:
  std::cout << "红色" << std::endl;
  break;
  case GREEN:
  std::cout << "绿色" << std::endl;
  break;
  case BLUE:
  std::cout << "蓝色" << std::endl;
  break;
  default:
  std::cout << "未知颜色" << std::endl;
  break;
 }
 // 使用枚举类的 switch 语句 (C++11)
 enum class Direction { UP, DOWN, LEFT, RIGHT };
 Direction dir = Direction::UP;
 switch (dir) {
  case Direction::UP:
  std::cout << "向上" << std::endl;
  break;
  case Direction::DOWN:
  std::cout << "向下" << std::endl;
  break;
  case Direction::LEFT:
  std::cout << "向左" << std::endl;
  break;
  case Direction::RIGHT:
  std::cout << "向右" << std::endl;
  break;
 }

2.2 循环结构

2.2.1 for 循环

 // 传统 for 循环
 for (int i = 0; i < 10; ++i) {
  std::cout << i << " ";
 }
 std::cout << std::endl;
 // 循环变量作用域控制
 {
  for (int i = 0; i < 5; ++i) {
  std::cout << i << " ";
  }
  // i 在这里不可见
 }
 // 多变量 for 循环
 for (int i = 0, j = 10; i < 5 && j > 5; ++i, --j) {
  std::cout << "i: " << i << ", j: " << j << std::endl;
 }
 // 范围 for 循环 (C++11)
 std::vector<int> numbers = {1, 2, 3, 4, 5};
 for (int num : numbers) {
  std::cout << num << " ";
 }
 std::cout << std::endl;
 // 使用 auto 的范围 for 循环 (C++11)
 for (auto num : numbers) {
  std::cout << num << " ";
 }
 std::cout << std::endl;
 // 使用 const 引用的范围 for 循环(避免复制)
 for (const auto& num : numbers) {
  std::cout << num << " ";
 }
 std::cout << std::endl;
 // 使用引用的范围 for 循环(可以修改元素)
 for (auto& num : numbers) {
  num *= 2; // 每个元素都乘以 2
 }
 // 遍历数组
 int arr[] = {10, 20, 30, 40, 50};
 for (int x : arr) {
  std::cout << x << " ";
 }
 std::cout << std::endl;

2.2.2 while 循环

 // 基本 while 循环
 int i = 0;
 while (i < 10) {
  std::cout << i << " ";
  ++i;
 }
 std::cout << std::endl;
 // 无限循环(需要内部 break)
 i = 0;
 while (true) {
  std::cout << i << " ";
  ++i;
  if (i >= 10) {
  break;
  }
 }
 std::cout << std::endl;
 // 基于条件的 while 循环
 std::string input;
 while (true) {
  std::cout << "输入 'quit' 退出: ";
  std::cin >> input;
  if (input == "quit") {
  break;
  }
  std::cout << "你输入了: " << input << std::endl;
 }

2.2.3 do-while 循环

 // 基本 do-while 循环
 int i = 0;
 do {
  std::cout << i << " ";
  ++i;
 }
 std::cout << std::endl;
 // 至少执行一次的情况
 std::string password;
 do {
  std::cout << "请输入密码: ";
  std::cin >> password;
 }
 std::cout << "密码正确!" << std::endl;

2.3 跳转语句

2.3.1 break 语句

 // 在 for 循环中使用 break
 for (int i = 0; i < 10; ++i) {
  if (i == 5) {
  break; // 跳出循环
  }
  std::cout << i << " ";
 }
 // 输出: 0 1 2 3 4
 // 在 while 循环中使用 break
 int j = 0;
 while (j < 10) {
  if (j == 5) {
  break;
  }
  std::cout << j << " ";
  ++j;
 }
 // 在 switch 语句中使用 break
 int value = 2;
 switch (value) {
  case 1:
  std::cout << "值为 1" << std::endl;
  break;
  case 2:
  std::cout << "值为 2" << std::endl;
  break; // 没有这个 break 会继续执行下一个 case
  case 3:
  std::cout << "值为 3" << std::endl;
  break;
 }

2.3.2 continue 语句

 // 在 for 循环中使用 continue
 for (int i = 0; i < 10; ++i) {
  if (i % 2 == 0) {
  continue; // 跳过当前迭代
  }
  std::cout << i << " ";
 }
 // 输出: 1 3 5 7 9
 // 在 while 循环中使用 continue
 int j = 0;
 while (j < 10) {
  ++j;
  if (j % 2 == 0) {
  continue;
  }
  std::cout << j << " ";
 }
 // 在范围 for 循环中使用 continue
 std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 for (auto num : nums) {
  if (num % 3 == 0) {
  continue;
  }
  std::cout << num << " ";
 }

2.3.3 return 语句

 // 基本 return 语句
 int add(int a, int b) {
  return a + b; // 返回值并结束函数
 }
 // 提前返回
 bool is_even(int n) {
  if (n % 2 == 0) {
  return true; // 提前返回
  }
  return false;
 }
 // 返回引用
 int& get_largest(int& a, int& b) {
  if (a > b) {
  return a;
  }
  return b;
 }
 // 返回空
 void print_hello() {
  std::cout << "Hello!" << std::endl;
  return; // 可选
 }
 int main() {
  int result = add(5, 3);
  std::cout << "5 + 3 = " << result << std::endl;
  int x = 10, y = 20;
  int& largest = get_largest(x, y);
  largest = 100; // 修改返回的引用
  std::cout << "x: " << x << ", y: " << y << std::endl;
  return 0; // 结束主函数
 }

2.3.4 goto 语句(不推荐使用)

 // 基本 goto 语句
 int main() {
  int i = 0;
 loop:
  std::cout << i << " ";
  ++i;
  if (i < 10) {
  goto loop; // 跳转到标签处
  }
  return 0;
 }
 // 使用 goto 跳出多层循环
 void nested_loops() {
  for (int i = 0; i < 10; ++i) {
  for (int j = 0; j < 10; ++j) {
  if (i * j > 20) {
  goto exit_loops; // 跳出所有循环
  }
  std::cout << "i: " << i << ", j: " << j << std::endl;
  }
  }
 exit_loops:
  std::cout << "跳出循环" << std::endl;
 }
 // 使用 goto 进行错误处理
 bool process_data() {
  // 模拟错误
  bool error = true;
  if (error) {
  goto error_handler;
  }
  // 正常处理
  return true;
 error_handler:
  std::cout << "处理错误" << std::endl;
  return false;
 }

3. 输入输出 (I/O)

3.1 标准输入输出

3.1.1 输出

 #include <iostream>
 int main() {
  // 基本输出
  std::cout << "Hello, C++!" << std::endl;
  // 多个值输出
  int x = 10;
  double y = 3.14;
  std::cout << "x = " << x << ", y = " << y << std::endl;
  // 使用 endl 换行并刷新缓冲区
  std::cout << "Line 1" << std::endl;
  std::cout << "Line 2" << std::endl;
  // 使用 \n 仅换行
  std::cout << "Line 1\nLine 2" << std::endl;
  // 输出布尔值
  bool flag = true;
  std::cout << "Flag: " << flag << std::endl; // 输出 1
  std::cout << std::boolalpha << "Flag: " << flag << std::endl; // 输出
  // 输出字符和字符串
  char c = 'A';
  std::string s = "Hello";
  std::cout << "Character: " << c << std::endl;
  std::cout << "String: " << s << std::endl;
  return 0;
 }

3.1.2 输入

 #include <iostream>
 #include <string>
 int main() {
  // 输入整数
  int x;
  std::cout << "Enter an integer: ";
  std::cin >> x;
  std::cout << "You entered: " << x << std::endl;
  // 输入浮点数
  double y;
  std::cout << "Enter a double: ";
  std::cin >> y;
  std::cout << "You entered: " << y << std::endl;
  // 输入布尔值
  bool flag;
  std::cout << "Enter a boolean (0 or 1): ";
  std::cin >> flag;
  std::cout << "You entered: " << std::boolalpha << flag << std::endl;
  // 输入字符
  char c;
  std::cout << "Enter a character: ";
  std::cin >> c;
  std::cout << "You entered: " << c << std::endl;
  // 输入字符串(遇到空格停止)
  std::string name;
  std::cout << "Enter your name: ";
  std::cin >> name;
  std::cout << "Hello, " << name << "!" << std::endl;
  // 输入一行字符串
  std::string line;
  std::cout << "Enter a line: ";
  std::cin.ignore(); // 忽略之前的换行符
  std::getline(std::cin, line);
  std::cout << "You entered: " << line << std::endl;
  // 输入多个值
  int a, b;
  std::cout << "Enter two integers: ";
  std::cin >> a >> b;
  std::cout << "You entered: " << a << " and " << b << std::endl;
  return 0;
 }

3.1.3 输入验证

 #include <iostream>
 #include <limits>
 int main() {
  int age;
  // 验证输入是否为整数
  while (true) {
  std::cout << "Enter your age: ";
  if (std::cin >> age) {
  // 输入成功
  break;
  } else {
  // 输入失败,清除错误状态
  std::cin.clear();
  // 忽略无效输入
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  std::cout << "Invalid input. Please enter a number." << std::endl;
  }
  }
  std::cout << "Your age is: " << age << std::endl;
  return 0;
 }

3.2 格式化输出

 #include <iostream>
 #include <iomanip>
 int main() {
  // 设置输出宽度
  std::cout << std::setw(10) << "Name" << std::setw(10) << "Age" << std::endl;
  std::cout << std::setw(10) << "Alice" << std::setw(10) << 25 << std::endl;
  std::cout << std::setw(10) << "Bob" << std::setw(10) << 30 << std::endl;
  // 设置填充字符
  std::cout << std::setw(10) << std::setfill('*') << "Hello" << std::endl;
  // 设置精度
  double pi = 3.1415926535;
  std::cout << "Pi: " << std::setprecision(5) << pi << std::endl;
  // 固定精度
  std::cout << "Pi (fixed): " << std::fixed << std::setprecision(2) << pi << std::endl;
  // 科学计数法
  double large_num = 123456789.123456;
  std::cout << "Large number: " << std::scientific << large_num << std::endl;
  // 十六进制输出
  int x = 255;
  std::cout << "Hex: " << std::hex << x << std::endl;
  std::cout << "Hex (uppercase): " << std::hex << std::uppercase << x << std::endl;
  // 八进制输出
  std::cout << "Octal: " << std::oct << x << std::endl;
  // 重置为十进制
  std::cout << "Decimal: " << std::dec << x << std::endl;
  // 显示正负号
  int positive = 10;
  int negative = -10;
  std::cout << "Positive: " << std::showpos << positive << std::endl;
  std::cout << "Negative: " << negative << std::endl;
  std::cout << std::noshowpos; // 关闭显示正负号
  // 显示前导零
  int num = 42;
  std::cout << "With leading zeros: " << std::setw(5) << std::setfill('0') << num << std::endl;
  return 0;
 }

3.3 文件输入输出

 #include <iostream>
 #include <fstream>
 #include <string>
 int main() {
  // 写入文件
  std::ofstream outfile("example.txt");
  if (outfile.is_open()) {
  outfile << "Hello, File!" << std::endl;
  outfile << "This is a test." << std::endl;
  outfile << "Number: " << 42 << std::endl;
  outfile.close();
  std::cout << "File written successfully." << std::endl;
  } else {
  std::cerr << "Unable to open file for writing." << std::endl;
  }
  // 读取文件
  std::ifstream infile("example.txt");
  if (infile.is_open()) {
  std::string line;
  std::cout << "File contents:" << std::endl;
  while (std::getline(infile, line)) {
  std::cout << line << std::endl;
  }
  infile.close();
  } else {
  std::cerr << "Unable to open file for reading." << std::endl;
  }
  return 0;
 }

3.4 字符串流

 #include <iostream>
 #include <sstream>
 #include <string>
 int main() {
  // 输出字符串流
  std::stringstream ss;
  ss << "Name: " << "Alice" << ", Age: " << 25 << ", Score: " << 95.5;
  std::string result = ss.str();
  std::cout << "String stream result: " << result << std::endl;
  // 输入字符串流
  std::string data = "10 3.14 Hello";
  std::stringstream input_ss(data);
  int i;
  double d;
  std::string s;
  input_ss >> i >> d >> s;
  std::cout << "Parsed values: " << i << ", " << d << ", " << s << std::endl;
  // 格式化数字为字符串
  std::stringstream format_ss;
  format_ss << std::fixed << std::setprecision(2) << 3.14159;
  std::string pi_str = format_ss.str();
  std::cout << "Formatted pi: " << pi_str << std::endl;
  return 0;
 }

4. 命名空间 (Namespace)

4.1 命名空间的定义

 // 定义命名空间
 namespace MyNamespace {
  int add(int a, int b) {
  return a + b;
  }
  namespace Nested {
  int multiply(int a, int b) {
  return a * b;
  }
  }
 }
 int main() {
  // 使用命名空间
  int result1 = MyNamespace::add(5, 3);
  int result2 = MyNamespace::Nested::multiply(5, 3);
  std::cout << "5 + 3 = " << result1 << std::endl;
  std::cout << "5 * 3 = " << result2 << std::endl;
  return 0;
 }

4.2 using 声明

 #include <iostream>
 // 使用命名空间中的特定成员
 using std::cout;
 using std::endl;
 int main() {
  cout << "Hello, C++!" << endl;
  return 0;
 }

4.3 using 指令

 #include <iostream>
 // 使用整个命名空间
 using namespace std;
 int main() {
  cout << "Hello, C++!" << endl;
  return 0;
 }

4.4 命名空间别名

 #include <iostream>
 namespace long_namespace_name {
  void func() {
  std::cout << "Function in long namespace" << std::endl;
  }
 }
 // 命名空间别名
 namespace lnn = long_namespace_name;
 int main() {
  lnn::func();
  return 0;
 }

5. 作用域 (Scope)

5.1 块作用域

 int main() {
  // 全局作用域
  int global_var = 10;
  if (true) {
  // 块作用域
  int local_var = 20;
  std::cout << "local_var: " << local_var << std::endl;
  std::cout << "global_var: " << global_var << std::endl;
  }
  // 这里无法访问 local_var
  std::cout << "global_var: " << global_var << std::endl;
  return 0;
 }

5.2 函数作用域

 void func() {
  // 函数作用域
  int func_var = 100;
  std::cout << "func_var: " << func_var << std::endl;
 }
 int main() {
  // 这里无法访问 func_var
  func();
  return 0;
 }

5.3 类作用域

 class MyClass {
 public:
  int public_var; // 类作用域
 private:
  int private_var; // 类作用域
 }
 int main() {
  MyClass obj;
  obj.public_var = 10; // 可以访问
  // obj.private_var = 20; // 无法访问,private 成员
  return 0;
 }

5.4 命名空间作用域

 namespace MyNS {
  int ns_var = 1000; // 命名空间作用域
 }
 int main() {
  std::cout << MyNS::ns_var << std::endl;
  return 0;
 }

头文件包含

系统头文件写法:包含系统头文件 #include <<header>>

// 包含输入输出流头文件
#include <iostream>

用户头文件写法:包含自定义头文件 #include "<header>"

// 包含当前目录下的头文件
#include "myheader.h"

命名空间

基本写法:使用命名空间 using namespace <name>;

// 使用标准命名空间
using namespace std;

作用域写法:使用命名空间中的特定成员 using <namespace>::<member>;

// 使用 std::cout
using std::cout;

限定写法:使用完整限定名 <namespace>::<member>

// 使用完整限定名
std::cout << "Hello" << std::endl;

定义写法:自定义命名空间 namespace <name> { ... }

// 定义命名空间
namespace MyMath {
    int add(int a, int b) { return a + b; }
}

输入输出

输出写法:标准输出 std::cout << <value>;

// 输出字符串到标准输出
std::cout << "Hello C++";

换行写法:输出并换行 std::cout << <value> << std::endl;

// 输出并换行
std::cout << "Hello" << std::endl;

输入写法:标准输入 std::cin >> <variable>;

// 从标准输入读取
int age;
std::cin >> age;

多值输入写法:连续读取多个值 std::cin >> <var1> >> <var2>;

// 连续读取多个值
int a, b;
std::cin >> a >> b;

main 函数

无参写法:无参数主函数 int main() { ... return 0; }

// 无参数形式的 main 函数
int main() {
    std::cout << "Hello" << std::endl;
    return 0;
}

带参写法:命令行参数主函数 int main(int argc, char *argv[]) { ... }

// argc 为参数个数,argv 为参数字符串数组
int main(int argc, char *argv[]) {
    for (int i = 0; i < argc; i++) {
        std::cout << argv[i] << std::endl;
    }
    return 0;
}

变量声明与初始化

基本写法:变量声明与初始化 <type> <var_name> = <value>;

// 声明并初始化变量
int x = 10;

直接初始化写法:构造函数式初始化 <type> <var_name>(<value>);

// 直接初始化
int x(10);

列表初始化写法:C++11 列表初始化 <type> <var_name>{<value>};

// 列表初始化
int x{10};

auto 写法:自动类型推导 auto <var_name> = <value>;

// 编译器自动推导类型
auto x = 10;

decltype 写法:推导表达式类型 decltype(<expression>) <var_name>;

// 推导表达式的类型
int a = 10;
decltype(a) b = 20;

const 写法:常量声明 const <type> <var_name> = <value>;

// 声明常量
const int MAX_SIZE = 100;

constexpr 写法:编译期常量 constexpr <type> <var_name> = <value>;

// 编译期常量
constexpr int SIZE = 10;

注释

单行写法:单行注释 // <注释内容>

// 这是一个单行注释
int x = 10;

多行写法:多行注释 /* <注释内容> */

/*
 * 这是一个多行注释
 * 可以跨越多行
 */
int y = 20;

引用

基本写法:左值引用 <type>& <ref_name> = <var>;

// 引用是变量的别名
int x = 10;
int& ref = x;

常量引用写法:const 引用 const <type>& <ref_name> = <value>;

// 常量引用,不能通过引用修改值
const int& ref = 10;

右值引用写法:C++11 右值引用 <type>&& <ref_name> = <value>;

// 右值引用,绑定到临时值
int&& rref = 10;

指针

基本写法:指针声明与初始化 <type>* <ptr_name> = &<var>;

// ptr 指向 x 的地址
int x = 10;
int* ptr = &x;

空指针写法:C++11 nullptr <type>* <ptr_name> = nullptr;

// 初始化为空指针
int* ptr = nullptr;

智能指针写法:unique_ptr std::unique_ptr<<type>> <ptr> = std::make_unique<<type>>(<args>);

#include <memory>
// 独占所有权的智能指针
std::unique_ptr<int> p = std::make_unique<int>(10);

智能指针写法:shared_ptr std::shared_ptr<<type>> <ptr> = std::make_shared<<type>>(<args>);

#include <memory>
// 共享所有权的智能指针
std::shared_ptr<int> p = std::make_shared<int>(10);

类型转换

static_cast 写法:静态类型转换 static_cast<<target_type>>(<expression>)

// 静态类型转换
double pi = 3.14;
int rounded = static_cast<int>(pi);

dynamic_cast 写法:动态类型转换 dynamic_cast<<target_type>>(<expression>)

// 动态类型转换(用于多态类型)
Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);

const_cast 写法:常量转换 const_cast<<target_type>>(<expression>)

// 添加或移除 const
const int* cp = &x;
int* p = const_cast<int*>(cp);

reinterpret_cast 写法:重解释转换 reinterpret_cast<<target_type>>(<expression>)

// 重解释类型转换
long addr = reinterpret_cast<long>(ptr);

异常处理

基本写法:try-catch try { ... } catch (<type> <e>) { ... }

// 异常处理
try {
    throw std::runtime_error("Error");
} catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
}

抛出写法:抛出异常 throw <expression>;

// 抛出异常
throw std::runtime_error("Something went wrong");

多 catch 写法:捕获多种异常 try { ... } catch (<type1> <e>) { ... } catch (<type2> <e>) { ... }

// 捕获多种异常
try {
    // 可能抛出不同异常的代码
} catch (const std::runtime_error& e) {
    std::cerr << e.what() << std::endl;
} catch (const std::logic_error& e) {
    std::cerr << e.what() << std::endl;
}

编译命令

单文件写法:编译单个源文件 g++ <source.cpp> -o <output>

# 编译 hello.cpp 生成可执行文件 hello
g++ hello.cpp -o hello

标准写法:指定 C++ 标准 g++ -std=c++17 <source.cpp> -o <output>

# 使用 C++17 标准编译
g++ -std=c++17 hello.cpp -o hello

C++23/26 新特性

基本写法:C++23 std::print std::print("<格式>", <参数>);

// 格式化输出到 stdout,支持 {} 占位符
#include <print>
std::print("Hello, {}! Value = {}\n", "World", 42);
// 输出:Hello, World! Value = 42

基本写法:C++23 std::println std::println("<格式>", <参数>);

// 自动换行的格式化输出
#include <print>
std::println("Sum of {} and {} is {}", 3, 5, 8);
// 输出:Sum of 3 and 5 is 8(自动换行)

基本写法:C++23 if consteval if consteval { }

// 编译期分支判断:仅在常量求值上下文中执行
constexpr int compute(int x) {
    if consteval {
        return x * 2;  // 编译期执行
    } else {
        return x + 1;  // 运行期执行
    }
}

基本写法:C++23 多维下标运算符 operator[](size_t x, size_t y)

// 支持多维下标访问,简化矩阵类设计
class Matrix {
    int data[3][3];
public:
    // 多参数 operator[]
    int& operator[](size_t i, size_t j) {
        return data[i][j];
    }
};
Matrix m;
m[1, 2] = 42;  // 直接多维访问

基本写法:C++23 static call operator static operator()(<参数>) { }

// 静态调用运算符:无需实例即可调用
class Calculator {
public:
    static int operator()(int a, int b) {
        return a + b;
    }
};
// 直接通过类型名调用
int result = Calculator()(3, 4);  // 返回 7

基本写法:C++26 = delete 原因 = delete("reason");

// = delete 支持说明删除原因
class NonCopyable {
public:
    NonCopyable() = default;
    // 禁用拷贝构造并说明原因
    NonCopyable(const NonCopyable&) = delete("该类不允许拷贝构造");
    NonCopyable& operator=(const NonCopyable&) = delete("该类不允许拷贝赋值");
};

基本写法:C++26 pack indexing typename...<T>[N]

// 模板参数包索引:直接访问参数包中第 N 个类型
template <typename... Ts>
using First = Ts...[0];  // 取参数包第一个类型
template <typename... Ts>
using Last = Ts...[sizeof...(Ts) - 1];  // 取参数包最后一个类型
// 使用
First<int, double, char> a = 10;   // a 为 int
Last<int, double, char> b = 3.14;  // b 为 double

基本写法:C++26 hazard pointer std::hazard_pointer<<T>>

// 危险指针:用于无锁数据结构的安全内存回收
#include <hazard_pointer>
// 获取危险指针
std::hazard_pointer hp = std::make_hazard_pointer();
// 保护对象指针,防止被回收
hp.protect(ptr);
// 操作受保护对象
if (hp.get() != nullptr) {
    hp.get()->do_something();
}
// 离开作用域自动释放保护

基本写法:C++26 RCU(Read-Copy-Update) std::rcu<<T>>

// RCU:读多写少场景的无锁同步原语
#include <rcu>
// 读端:在 RCU 域中安全访问共享数据
std::rcu_reader reader;
auto* p = shared_ptr.load();
if (p) p->read_data();
// 写端:复制更新后原子替换,并延迟回收旧数据
auto* new_data = new Data(*p);
new_data->update();
shared_ptr.store(new_data);
std::rcu_retire(p);  // 等待所有读者退出后回收