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:跳出当前循环或switch
  • continue:跳过当前循环剩余语句,进入下一次循环
  • 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→子类publicprotected→子类protected
  • protected:父类public/protected→子类protected
  • private:父类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"]; // 输出90
     
     
  • unordered_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
  • 右值引用&&,支持移动语义(减少拷贝)

十四、常见坑与注意事项

  1. 数组越界:访问arr[size]会导致未定义行为
  2. 内存泄漏:new分配的内存未用delete释放(建议用智能指针)
  3. 悬空指针:指向已释放内存的指针
  4. 类的拷贝:未定义拷贝构造函数时,浅拷贝可能导致资源重复释放
  5. 虚函数:父类析构函数未声明为虚函数,子类对象通过父类指针销毁时可能不调用子类析构
posted @ 2025-11-27 12:11  老程序员888  阅读(0)  评论(0)    收藏  举报