C++学习笔记
作者:齐花Guyc(CAUC)
文章目录
- C++学习笔记
- Chapter.1 面向对象编程(OOP)
- 1.类(class)
- 2.对象(object)
- 3.封装(Encapsulation)
- 4.继承(Inheritance)
- 5.多态(Polymorphism)
- 6.指针
- Chapter.2 内存管理
- 1.栈
- 2.堆
- Chapter.3 数据结构
- a1.内置基础结构——数组(array)
- a2.内置基础结构——指针(point)
- a3.内置基础结构——结构体(struct)和联合体(union)
- b1.STL容器——向量(vector)
- b2.STL容器——双向链表(list)
- b3.STL容器——栈(stack)
- b4.STL容器——队列(queue)
- Chapter.4 标准头文件——<stdio.h>
- 1.格式化输入输出
- 2.字符输入输出
- 3.字符串输入输出
- 4.文件操作
- Chapter.N 乱七八糟的一些
- 1.指针函数
- 2.函数指针
- 3.typedef
- 4.数据表示
- 5.sizeof操作符

Chapter.1 面向对象编程(OOP)
一个宠物店的故事
有一家宠物店,里面有很多宠物。你需要管理他们的信息和行为。这就是面向对象编程的场景。
1.类(class)
类就是宠物设计图纸,上面写着“猫科动物”:名字、年龄、会叫、会吃…
class Pet{
public:string name;int age;void eat(){cout << name << "在吃东西。" << endl;} void speak(){cout << name << "在叫。" << endl;}
};
Pet是蓝图,定义宠物有什么(属性)、会干什么(方法)。
2.对象(object)
对象是具体的宠物,用“猫科动物”图纸制造已知猫,名字为“咪咪”,2岁。
Pet cat;
cat.name = "咪咪";
cat.age = 2;
cat.eat();
cat.speak();
3.封装(Encapsulation)
宠物店里,每只宠物都有自己的小窝(私有空间),你不能随便动它的东西,只能通过“服务窗口”(公有方法)喂食或逗它。
class Pet{
private:string name;int age;
public:void setName(string n){name = n};void setAge(int a){age = a};void eat(){cout << name <<"在吃。"<< endl;}
};int main()
{Pet cat;cat.setName("咪咪");cat.setAge(2);cat.eat();//cat.name = "小花" //输出错误 name是私有的return 0;
}
4.继承(Inheritance)
“猫”和“狗”都是宠物,但猫会喵喵叫,狗会汪汪叫。你画一个“通用宠物图纸”,然后在上面加点细节,变成“猫图纸”和“狗图纸”。
class Pet{
public:string name;void eat(){cout << name << "在吃." << endl;}
};class Cat : public Pet{ //派生类:猫
public:void meow(){cout << name << "miao." << endl;}
};class Dog : public Pet{
public:void bark(){cout << name << "wang." << endl;}
};int main(){Cat cat;cat.name = "咪咪";cat.eat();cat.meow();Dog dog;dog.name = "旺财";dog.eat();dog.bark();return 0;
}
5.多态(Polymorphism)
想让所有宠物一起“表演叫声”,但每只宠物叫得不一样。多态就像你喊“叫一声!”,猫喵喵,狗汪汪。
class Pet{
public:string name;virtual void speak(){ //虚函数:让子类进行重写cout << name << "发出声音。" << endl;};
};class Cat : public Pet{
public: void speak() override{cout << name << "miao" << endl;}
};class Dog : public Pet{
public: void speak() override{cout << name << "wang" << endl;}
};int main()
{Pet* pet1 = new Cat();Pet* pet2 = new Dog();pet1->name = "咪咪";pet2->name = "旺旺";pet1->speak();// 咪咪 miaopet2->speak();// 旺旺 wangdelete pet1;delete pet2;return 0 ;
}
6.指针
指针可以想象成宠物店的“快递员”。指针是一个“地址标签”。宠物店里有很多宠物(对象),快递员(指针)拿着标签,知道去哪个窝找哪只宠物。
Pet cat; //一只猫
Pet* ptr = &cat;//快递员ptr拿着猫的地址
ptr->name = "咪咪";//通过快递员访问猫的名字
ptr->eat(); //让猫吃东西->表示通过快递员找宠物做事从外面订购了一只新宠物
Pet* ptr = new Pet();//新宠物,快递员拿着地址
ptr->name = "小白";
pet->eat();// 小白 在吃
delete ptr;//送走宠物,释放地址new创建对象在堆上,指针ptr管理它,delete释放地址
智能指针
通快递员(裸指针)可能会丢包裹(内存泄漏),智能快递员(unique_ptr)会自动清理。
智能指针格式
#include <memory>
unique_ptr<类> 指针名 = make_unique<类型>(参数);
#include <iostream>
#include <memory>
using namespace std;class Pet{
public:string name;Pet(string n) : name(n){cout << name << " 被创建" << endl;}~Pet(){cout << name << " 被销毁" << endl;}void bark(){ cout << name << "wang" << endl; }
};int main(){
unique_ptr<Pet> dog = make_unique<Pet>("旺财");
dog->bark();// unique_ptr不允许被复制
// unique_ptr<Pet> dog2 = dog;// 可以转让所有权
unique_ptr<Pet> dog2 = move(dog);return 0;
}
Chapter.2 内存管理
在C++中,程序的内存分为几个区域,其中栈(stack)和堆(heap)是最常用的两种内存分配方式。
1.栈
栈是程序运行时自动管理的内存区域,遵循“后进先出”(LIFO)的原则。像叠盘子,盘子一个个摞起来,最上面放的先拿走。变量超出作用域(比如函数结束)自动销毁。
#include <iostream>
using namespace std;void func(){int x = 10; //x在栈上,函数结束时自动销毁cout << x <<endl;
}
int main(){func();// 输出10//此时 x已经销毁 无法访问return 0;
}
2.堆
堆是程序员手动管理的内存区域,大小动态可变。像一片大空地,你想盖多少房子(内存)都可以,但得自己规划和清理。用 new 分配,delete 释放,不释放会内存泄漏。
#include <iostream>
using namespace std;int main(){int* ptr = new int(20);//new 在堆上分配内存cout << *p <<endl;//解引用delete p;//手动释放return 0;
}
Chapter.3 数据结构
CPP中数据结构主要分为两类:1.内置基础结构:数组、指针;2.STL容器:标准模板库提供的动态数据结构,比如向量,链表,栈,队列等。
a1.内置基础结构——数组(array)
固定大小的连续内存,元素类型相同。像一排固定数量的储物柜,每个柜子放一个东西。
int arr[5] = {1,2,3,4,5};
cout << arr[2] << endl;//输出3 索引从0开始 MATLAB从1开始
a2.内置基础结构——指针(point)
存储内存地址,可以动态分配内存。像房子的“地址标签”,告诉你东西在哪。
int* p = new int(10)
cout << *p <<endl;
delete p;
a3.内置基础结构——结构体(struct)和联合体(union)
结构体
允许把多个不同类型的变量组合在一起,形成一个整体。每个变量称为“成员”,可以通过结构体访问这些成员。
结构体就像一个“收纳盒”,里面可以放不同类型的东西(比如笔、橡皮、尺子),但每个东西有自己的格子,互不干扰。你可以用这个“盒子”一次性管理所有东西,而不是单独拿着一堆零散物品。
格式:
struct 结构体名{类型1 成员1;类型2 成员2;
};
嵌套结构体
#include <iostream>
using namespace std;struct Date{int year;int month;int day;
};struct Student{string name;Date birthday;//嵌套结构体int grade;
}int main(){Student s;s.name = "Bob";s.birthday.year = 2000;s.birthday.month = 1;s.birthday.day = 11;s.grade = 9;return 0;
}指针和结构体
struct Car(){string brand;int year;
};int main(){Car c = {"Audi",2025}Car *ptr = &c;cout = ptr->brand << " " << ptr->year << endl;return 0;
}
b1.STL容器——向量(vector)
动态数组,大小可变,元素连续存储。像一个可以伸缩的储物柜,想加多少格子都可以。
格式:
头文件:#include <vector>
vector<类型> 变量名;
vector<类型> 变量名={值1,值2,...};
vector<类型> 变量名(大小,默认值);
常用操作:
push_back(值):尾部添加元素
pop_back():删除尾部元素
size():返回元素个数
empty():检查是否为空
#include <vector>
#inclede <iostream>
using namespace std;int main(){vector<int> vec = {1,2,3};vec.push_back(4);cout << "大小:"<< vec.size() << endl;for (int i = 0;i < vec.size();i++){cout << vec[i] << endl;}vec.pop_back();//删除4cout << "\n新大小为:"<< vec.size() << endl;return 0;
}
联合体
类似于 struct,但它的所有成员共享同一块内存。union 的大小由其中最大的成员决定,每次只能使用一个成员的值,修改一个成员会覆盖其他成员的值。
结构体像一个“多格储物柜”,每个格子(成员)有自己的空间,互不干扰。
联合体像一个“单格魔法箱”,只有一个格子,但可以变出不同的东西(成员),放进新东西会覆盖旧的。
格式
union 联合名{类型1 成员1;类型2 成员2;
}
#include <iostream>
using namespace std;union MyUnion {int i; // 4字节float f; // 4字节char c; // 1字节
};int main(){MyUnion u;u.i = 65;cout << "i: " << u.i << endl; // 输出 65cout << "f: " << u.f << endl; // 输出乱码(内存被解释为 float)cout << "c: " << u.c << endl; // 输出 'A'(65 的 ASCII)u.f = 3.14;cout << "i: " << u.i << endl; // 输出乱码(内存被解释为 int)cout << "f: " << u.f << endl; // 输出 3.14cout << "c: " << u.c << endl; // 输出乱码cout << "大小: " << sizeof(u) << endl; // 输出 4(最大成员是 4 字节)return 0;
}
嵌套union和struct
#include <iostream>
using namespace std;union Data{struct {int x,y;};int array[2];
};int main(){Data d;d.x = 10;d.y = 20;cout << "x: " << d.x << ",y: " << d.y << endl;//输出10,20cout << "array:" << d.array[0] << "," << d.array[1] << endl;//输出10,20//union 里面有一个匿名结构体和一个数组array//x和array[0]共享内存 y和array[1]共享内存d.array[0] = 30;//修改array[0]cout << "x: " << d.x << endl;//输出30 x被覆盖cout << "大小: " << sizeof(d) << endl; //输出8 (2个int)return 0;
}
b2.STL容器——双向链表(list)
双向链表,元素分散存储,插入删除快,随机访问慢。像一串珍珠,每颗珠子用线连着,随时加减珠子。
格式:
list<类型> 变量名;
list<类型> 变量名 = {值1,值2,...};
常用操作:
push_front(值):头部插入
push_back(值):尾部插入
pop_front():删除头部
pop_back():删除尾部
size():元素格式
empty():是否为空
#include <list>
#include <iostream>int main(){list<int> lst = {2,3};lst.push_front(1);lst.push_back(4);for(int x:lst){cout << x <<'';}lst.pop_front();cout << "\n新大小:" << lst.size() << endl;return 0;
}
b3.STL容器——栈(stack)
后进先出(LIFO),只能操作顶部。像叠盘子,只能从顶部放或取。
格式:
头文件:#include <stack>
stack<类型> 变量名;
常用操作:
push(值):入栈
pop():出栈
top():访问顶部元素
size():元素个数
empty():是否为空
#include <iostream>
#include <stack>int main(){stcak<int> s;s.push(1);s.push(2);cout << s.top() << endl;//2s.pop();cout << s.top() << endl;//1return 0;
}
b4.STL容器——队列(queue)
先进先出(FIFO),像排队。像超市结账队列,先来先走。
头文件:#include <queue>
queue<类型> 变量名;
常用操作:
push(值):入队
pop():出队(删除队首)
front():访问队首
back():访问队尾
size():元素个数
#include <iostream>
#include <queue>int main(){queue<int> q;q.push(1);q.push(2);cout << q.front() << endl;//1q.pop();cout << q.front() << endl;//2return 0;
}
Chapter.4 标准头文件——<stdio.h>
1.格式化输入输出
printf();//输出到屏幕
scanf();//从键盘读取输入
2.字符输入输出
getchar();//读取一个字符
putchar();//输出一个字符
3.字符串输入输出
puts();//输出字符串并自动换行
gets();//读取一行字符串
4.文件操作
fprintf 格式化输出到文件
int fprintf(FILE* stream,const char *format,...);fscanf 从文件读取格式化输入
int fscanf(FILE* stream,const char *format,...);fopen 打开文件
FILE* fopen(const char* filename,const char* mode);
文件模式
"r":打开文件进行读取;"w":打开文件进行写入,若原文件存在则清空内容;"a":打开文件进行追加,若原文件不存在则创建fclose 关闭文件
int fclose(FILE* stream);fgets 从文件读取一行
char* fgets(char* buffer, int size, FILE* stream);fputs 向文件写入字符串
int fputs(const char* str, FILE* stream);fseek 移动文件指针的位置
int fseek(FILE* stream,long offset,int whence);ftell 获取文件指针的当前位置
long ftell(FILE* stream);
Chapter.N 乱七八糟的一些
1.指针函数
返回指针的函数,是一个函数,返回值是指针类型。
声明格式:
返回类型* 函数名(参数列表);
示例:
#include <iostream>
//指针函数
int* getPointer(int value){int* ptr = new int;//分配内存*ptr = value;return *ptr;
}int main(){int* result = getPointer(42);std::cout << "解引用*p = " << *result << std::endl;delete result;return 0;
}
2.函数指针
指向函数的指针,是一个指针变量。
声明格式:
返回类型 (*指针名)(参数类型列表);
示例:
#include <iostream>//普通函数
int add(int a, int b){int c = a + b; return c;
}int main(){//声明函数指针int (*funcPtr)(int,int);//funcPtr为指针,指向返回int的函数//把函数的地址赋值给指针funcPtr = &add;//通过函数指针调用函数int result = funcPtr(3,4);return 0;
}
3.typedef
全称type definition(类型定义),它的作用是给已有的数据类型取一个新的名字,就像给类型起个“别名”。
格式:
typedef 已有类型 新类型名称;
用法
1.给基本类型取别名
#include <iostream>
using namespace std;typedef int NUMBER;int main(){NUMBER a = 10;//用NUMBER代替int
}2.简化复杂类型,比如指针类型写起来麻烦
#include <iostream>
using namespace std;typedef int* IntPtr;//int* 的别名是Intptrint main(){int x = 5;IntPtr p = &x; //用IntPtr代替int*cout << *p << endl; // 输出:5return 0;
}3.处理结构体,结构体名字太长或需要多次使用。
#include <iostream>
using namespace std;typedef struct{string name;int age;
}Person;//结构体的别名是Personint main(){Person p;p.name = "Alice";p.age = 25;cout << p.name << "," << p.age << endl;// 输出:Alice,25return 0;
}4.处理结构体,起两个别名
typedef struct{string name;int age;
}Person, *PPerson;//一个是结构体的本身,一个是指向结构体的指针
在C/C++中,结构体经常通过指针传递(尤其在函数参数中),因为直接传结构体可能效率低(复制整个结构体)。
4.数据表示
Bit(位) 最小的单位,只表示0或者1。
Byte(字节) 8个Bit的组合,表示256种状态。1Byte=8Bit
char:1字节
short:2字节
int8:1字节
int16:2字节
int:4字节
float:4字节
long:8字节
double:8字节
pointer:8字节
5.sizeof操作符
sizeof用来告诉你某个数据类型或变量占多少 Byte(字节) 。