C++ 笔记
发布于 2026-04-06更新于 2026-11-147602 字36 分钟 · 阅读时间
2023-8-15 ~ 2023-10-19
这一篇只记不会的,关键的,之后新学的
第一篇好像已经丢失,只有图片还保留,我就把图片放到这篇文章最底部了。
C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。
*C++ 被认为是一种**中级**语言,它综合了高级语言和低级语言的特点。*
C++ 进一步扩充和完善了 C 语言,最初命名为带类的 C,后来在 1983 年更名为 C++。
C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。
**注意:***使用静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查。*
封装(Encapsulation):对外部隐藏实现细节,只公开对外提供的接口
继承(Inheritance):可以提高代码的复用性和可扩展性
多态(Polymorphism):多态是指同一种操作作用于不同的对象,可以有不同的解释和实现。
抽象(Abstraction):抽象是从具体的实例中提取共同的特征,形成抽象类或接口
标准的 C++ 由三个重要部分组成:
C++常在需要高性能/低硬件等情况下使用
使用$ g++ -v可查看是否在 Linux 中安装了 GNU 的编译器
程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。通过遵循源码的命名规范并指定对应库的名字,用 gcc 来编译链接 C++ 程序是可行的,如下例所示:
$ gcc main.cpp -lstdc++ -o main下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码:
#include <iostream>using namespace std;int main(){ cout << "Hello, world!" << endl; return 0;}最简单的编译方式:
$ g++ helloworld.cpp由于命令行中未指定可执行程序的文件名,编译器采用默认的 a.out。程序可以这样来运行:
$ ./a.outHello, world!通常我们使用 -o 选项指定可执行程序的文件名,以下实例生成一个 helloworld 的可执行文件:
$ g++ helloworld.cpp -o helloworld执行 helloworld:
$ ./helloworldHello, world!如果是多个 C++ 代码文件,如 runoob1.cpp、runoob2.cpp,编译命令如下:
$ g++ runoob1.cpp runoob2.cpp -o runoob生成一个 runoob 可执行文件。
g++ 有些系统默认是使用 C++98,我们可以指定使用 C++11 来编译 main.cpp 文件:
g++ -g -Wall -std=c++11 main.cpp| 选项 | 解释 |
|---|---|
| -ansi | 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色, 例如 asm 或 typeof 关键词。 |
| -c | 只编译并生成目标文件。 |
| -DMACRO | 以字符串"1"定义 MACRO 宏。 |
| -DMACRO=DEFN | 以字符串"DEFN"定义 MACRO 宏。 |
| -E | 只运行 C 预编译器。 |
| -g | 生成调试信息。GNU 调试器可利用该信息。 |
| -IDIRECTORY | 指定额外的头文件搜索路径 DIRECTORY。 |
| -LDIRECTORY | 指定额外的函数库搜索路径 DIRECTORY。 |
| -lLIBRARY | 连接时搜索指定的函数库 LIBRARY。 |
| -m486 | 针对 486 进行代码优化。 |
| -o | FILE 生成指定的输出文件。用在生成可执行文件时。 |
| -O0 | 不进行优化处理。 |
| -O | 或 -O1 优化生成代码。 |
| -O2 | 进一步优化。 |
| -O3 | 比 -O2 更进一步优化,包括 inline 函数。 |
| -shared | 生成共享目标文件。通常用在建立共享库时。 |
| -static | 禁止使用共享连接。 |
| -UMACRO | 取消对 MACRO 宏的定义。 |
| -w | 不生成任何警告信息。 |
| -Wall | 生成所有警告信息。 |
C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。
| asm | else | new | this |
|---|---|---|---|
| auto | enum | operator | throw |
| bool | explicit | private | true |
| break | export | protected | try |
| case | extern | public | typedef |
| catch | false | register | typeid |
| char | float | reinterpret_cast | typename |
| class | for | return | union |
| const | friend | short | unsigned |
| const_cast | goto | signed | using |
| continue | if | sizeof | virtual |
| default | inline | static | void |
| delete | int | static_cast | volatile |
| do | long | struct | wchar_t |
| double | mutable | switch | while |
| dynamic_cast | namespace | template |
1. asm
asm (指令字符串):允许在 C++ 程序中嵌入汇编代码。
2. auto
auto(自动,automatic)是存储类型标识符,表明变量"自动"具有本地范围,块范围的变量声明(如 for 循环体内的变量声明)默认为 auto 存储类型。
3. bool
bool(布尔)类型,C++ 中的基本数据结构,其值可选为 true(真)或者 false(假)。C++ 中的 bool 类型可以和 int 混用,具体来说就是 0 代表 false,非 0 代表 true。bool 类型常用于条件判断和函数返回值。
4. break
break(中断、跳出),用在 switch 语句或者循环语句中。程序遇到 break 后,即跳过该程序段,继续后面的语句执行。
5. case
用于 switch 语句中,用于判断不同的条件类型。
6. catch
catch 和 try 语句一起用于异常处理。
7. char
char(字符,character)类型,C++ 中的基本数据结构,其值一般为 0~255 的 int。这 256 个字符对应着 256 个 ASCII 码。char 类型的数据需要用单引号 ' 括起来。
8.class
class(类)是 C++ 面向对象设计的基础。使用 class 关键字声明一个类。
9. const
const(常量的,constant)所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非 const 函数。在函数的声明与定义时都要加上 const,放在函数参数列表的最后一个括号后。在 C++ 中,用 const 声明一个变量,意味着该变量就是一个带类型的常量,可以代替 #define,且比 #define 多一个类型信息,且它执行内链接,可放在头文件中声明;但在 C 中,其声明则必须放在源文件(即 .C 文件)中,在 C 中 const 声明一个变量,除了不能改变其值外,它仍是一具变量。如:
const double pi(3.14159);或const double pi = 3.14159;10. const_cast 用法:
const_cast<type_id> (expression)该运算符用来修改类型的 const 或 volatile 属性。除了 const 或 volatile 修饰之外, type_id 和 expression 的类型是一样的。常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
11. continue
continue(继续)关键字用于循环结构。它使程序跳过代码段后部的部分,与 break 不同的是,continue 不是进入代码段后的部分执行,而是重新开始新的循环。因而它是"继续循环"之意,不是 break(跳出)。
12. default
default(默认、缺省)用于 switch 语句。当 switch 所有的 case 都不满足时,将进入 default 执行。default 只能放在 switch 语句所有的 case 之后,并且是可选的。
13. delete
delete(删除)释放程序动态申请的内存空间。delete 后面通常是一个指针或者数组 [],并且只能 delete 通过 new 关键字申请的指针,否则会发生段错误。
14. do
do-while 是一类循环结构。与 while 循环不同,do-while 循环保证至少要进入循环体一次。
15. double
double(双精度)类型,C++ 中的基本数据结构,以双精度形式存储一个浮点数。
16. dynamic_cast
dynamic_cast(动态转换),允许在运行时刻进行类型转换,从而使程序能够在一个类层次结构安全地转换类型。dynamic_cast 提供了两种转换方式,把基类指针转换成派生类指针,或者把指向基类的左值转换成派生类的引用。
17. else
else 紧跟在 if 后面,用于对 if 不成立的情况的选择。
18. enum
enum(枚举)类型,给出一系列固定的值,只能在这里面进行选择一个。
19. explicit
explicit(显式的)的作用是"禁止单参数构造函数"被用于自动型别转换,其中比较典型的例子就是容器类型。在这种类型的构造函数中你可以将初始长度作为参数传递给构造函数。
20. export
为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准 C++ 新增加的关键字 export(导出)。
21. extern
extern(外部的)声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义(实现)。在文件内声明一个变量或函数默认为可被外部使用。在 C++ 中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前仅支持 C 转换标记,来支持 C 编译器链接。使用这种情况有两种形式:
extern "C" 声明语句 extern "C" { 声明语句块 }22. false
false(假的),C++ 的基本数据结构 bool 类型的值之一。等同于 int 的 0 值。
23. float
float(浮点数),C++ 中的基本数据结构,精度小于 double。
24. for
for 是 C++ 中的循环结构之一。
25. friend
friend(友元)声明友元关系。友元可以访问与其有 friend 关系的类中的 private/protected 成员,通过友元直接访问类中的 private/protected 成员的主要目的是提高效率。友元包括友元函数和友元类。
26. goto
goto(转到),用于无条件跳转到某一标号处开始执行。
27. if
if(如果),C++ 中的条件语句之一,可以根据后面的 bool 类型的值选择进入一个分支执行。
28. inline
inline(内联)函数的定义将在编译时在调用处展开。inline 函数一般由短小的语句组成,可以提高程序效率。
29. int
int(整型,integer),C++ 中的基本数据结构,用于表示整数,精度小于 long。
30. long
long(长整型,long integer),C++ 中的基本数据结构,用于表示长整数。
31. mutable
mutable(易变的)是 C++ 中一个不常用的关键字。只能用于类的非静态和非常量数据成员。由于一个对象的状态由该对象的非静态数据成员决定,所以随着数据成员的改变,对像的状态也会随之发生变化。如果一个类的成员函数被声明为 const 类型,表示该函数不会改变对象的状态,也就是该函数不会修改类的非静态数据成员。但是有些时候需要在该类函数中对类的数据成员进行赋值,这个时候就需要用到 mutable 关键字。
32. namespace
namespace(命名空间)用于在逻辑上组织类,是一种比类大的结构。
33. new
new(新建)用于新建一个对象。new 运算符总是返回一个指针。由 new 创建
34. operator
operator(操作符)用于操作符重载。这是 C++ 中的一种特殊的函数。
35. private
private(私有的),C++ 中的访问控制符。被标明为 private 的字段只能在本类以及友元中访问。
36. protected
protected(受保护的),C++ 中的访问控制符。被标明为 protected 的字段只能在本类以及其继承类和友元中访问。
37. public
public(公有的),C++ 中的访问控制符。被标明为 public 的字段可以在任何类
38.register
register(寄存器)声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器中;但对 32 位编译器不起作用,当 global optimizations(全局优化)开的时候,它会做出选择是否放在自己的寄存器中;不过其它与 register 关键字有关的其它符号都对 32 位编译器有效。
39. reinterpret_cast
用法:
reinpreter_cast<type-id> (expression)type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
40. return
return(返回)用于在函数中返回值。程序在执行到 return 语句后立即返回,return 后面的语句无法执行到。
41. short
short(短整型,short integer),C++ 中的基本数据结构,用于表示整数,精度小于 int。
42. signed
signed(有符号),表明该类型是有符号数,和 unsigned 相反。数字类型(整型和浮点型)都可以用 signed 修饰。但默认就是 signed,所以一般不会显式使用。
43. sizeof
由于 C++ 每种类型的大小都是由编译器自行决定的,为了增加可移植性,可以用 sizeof 运算符获得该数据类型占用的字节数。
44. static
static(静态的)静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为 0,使用时可改变其值。静态变量或静态函数,只有本文件内的代码才可访问它,它的名字(变量名或函数名)在其它文件中不可见。因此也称为"文件作用域"。在 C++ 类的成员变量被声明为 static(称为静态成员变量),意味着它被该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。类的静态成员变量必须在声明它的文件范围内进行初始化才能使用,private 类型的也不例外。
45. static_cast
用法:
static_cast < type-id > ( expression )该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
注意 static_cast 不能转换掉 expression 的 const、volitale、或者 __unaligned 属性。
46. struct
struct(结构)类型,类似于 class 关键字,与 C 语言兼容(class 关键字是不与 C 语言兼容的),可以实现面向对象程序设计。
47. switch
switch(转换)类似于 if-else-if 语句,是一种多分枝语句。它提供了一种简洁的书写,并且能够生成效率更好的代码。但是,switch 后面的判断只能是 int(char 也可以,但 char 本质上也是一种 int 类型)。switch 语句最后的 default 分支是可选的。
48. template
template(模板),C++ 中泛型机制的实现。
49. this
this 返回调用者本身的指针。
50. throw
throw(抛出)用于实现 C++ 的异常处理机制,可以通过 throw 关键字"抛出"一个异常。
51. true
true(真的),C++ 的基本数据结构 bool 类型的值之一。等同于 int 的非 0 值。
52. try
try(尝试)用于实现 C++ 的异常处理机制。可以在 try 中调用可能抛出异常的函数,然后在 try 后面的 catch 中捕获并进行处理。
53. typedef
typedef(类型定义,type define),其格式为:
typedef 类型 定义名;类型说明定义了一个数据类型的新名字而不是定义一种新的数据类型。定义名表示这个类型的新名字。
54. typeid
指出指针或引用指向的对象的实际派生类型。
55. typename
typename(类型名字)关键字告诉编译器把一个特殊的名字解释成一个类型。在下列情况下必须对一个 name 使用 typename 关键字:
56. union
union(联合),类似于 enum。不同的是 enum 实质上是 int 类型的,而 union 可以用于所有类型,并且其占用空间是随着实际类型大小变化的。
57. unsigned
unsigned(无符号),表明该类型是无符号数,和 signed 相反。
58. using
表明使用 namespace。
59. virtual
virtual(虚的),C++ 中用来实现多态机制。
60. void
void(空的),可以作为函数返回值,表明不返回任何数据;可以作为参数,表明没有参数传入(C++中不是必须的);可以作为指针使用。
61. volatile
volatile(不稳定的)限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:
int volatile nVint;这样的声明是不能达到最高效的,因为它们的值随时会改变,系统在需要时会经常读写这个对象的值。因此常用于像中断处理程序之类的异步进程进行内存单元访问。
62. wchar_t
wchar_t 是宽字符类型,每个 wchar_t 类型占 2 个字节,16 位宽。汉字的表示就要用到 wchar_t。
| 传值调用 | 该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。 |
|---|---|
| 指针调用 | 该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。 |
| 引用调用 | 该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。 |
后两个就是将 C 语言中的引用调用拆开了
&://引用调用 函数(int &a) main (a) // 传 *://指针调用 函数(int *a) main (&a) // 传地址/指针 /* 例如:int& b = a; 就相当于给a取了一个别名b 因此可以上述的引用调用中,传main(b)也可以 */ /* 但int *c = a;与int& c = a;不同,改地址本身c不会改变a,只有改变地址所指向的变量(*c)时才能改变变量a */C++ 的 std::string 类型支持许多常用的字符串操作方法,包括但不限于以下几种:
size() 或 length():返回字符串的长度。empty():检查字符串是否为空。append() 或 +=:将另一个字符串添加到当前字符串的末尾。substr():返回字符串的一个子串。insert():在指定位置插入一个字符串。erase():删除字符串的一部分。replace():替换字符串的一部分。find():查找子串的位置。compare():比较两个字符串。要使用 <ctime> 头文件
其中有四种与时间有关的类型,clock_t、time_t、size_t 、tm
其中的前三个为一串数,最后一个为一个结构体
struct tm { int tm_sec; // 秒,正常范围从 0 到 59,但允许至 61 int tm_min; // 分,范围从 0 到 59 int tm_hour; // 小时,范围从 0 到 23 int tm_mday; // 一月中的第几天,范围从 1 到 31 int tm_mon; // 月,范围从 0 到 11 int tm_year; // 自 1900 年起的年数 int tm_wday; // 一周中的第几天,范围从 0 到 6,从星期日算起 int tm_yday; // 一年中的第几天,范围从 0 到 365,从 1 月 1 日算起 int tm_isdst; // 夏令时};可以通过一些函数来处理它们,以便更方便的处理时间
例如:
#include <iostream>#include <ctime> using namespace std; int main( ){ // 基于当前系统的当前日期/时间 time_t now = time(0); // 把 now 转换为字符串形式 char* dt = ctime(&now); cout << "本地日期和时间:" << dt << endl; // 把 now 转换为 tm 结构 tm *gmtm = gmtime(&now); dt = asctime(gmtm); cout << "UTC 日期和时间:"<< dt << endl;}//本地日期和时间:Sat Jan 8 20:07:41 2011////UTC 日期和时间:Sun Jan 9 03:07:41 2011#include <iostream>#include <ctime> using namespace std; int main( ){ // 基于当前系统的当前日期/时间 time_t now = time(0); cout << "1970 到目前经过秒数:" << now << endl; tm *ltm = localtime(&now); // 输出 tm 结构的各个组成部分 cout << "年: "<< 1900 + ltm->tm_year << endl; cout << "月: "<< 1 + ltm->tm_mon<< endl; cout << "日: "<< ltm->tm_mday << endl; cout << "时间: "<< ltm->tm_hour << ":"; cout << ltm->tm_min << ":"; cout << ltm->tm_sec << endl;}//1970 到目前时间:1503564157//年: 2017//月: 8//日: 24//时间: 16:42:37可以使用 setw() 函数来进行格式化输入输出

下列的头文件在 C++ 编程中很重要。
| 头文件 | 函数和描述 |
|---|---|
| 该文件定义了 cin、cout、cerr 和 clog 对象,分别对应于标准输入流、标准输出流、非缓冲标准错误流和缓冲标准错误流。 | |
| 该文件通过所谓的参数化的流操纵器(比如 setw 和 setprecision),来声明对执行标准化 I/O 有用的服务。 | |
| 该文件为用户控制的文件处理声明服务。我们将在文件和流的相关章节讨论它的细节。 |
其中 cin 输入、cout 输出、cerr 显示错误消息、clog 显示日志消息
c+in 输入,c+out 输入 等

class Box{ public: double lengt; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度};就像声明基本变量一样声明类的对象Box Box1; // 声明 Box1,类型为 BoxBox Box2; // 声明 Box2,类型为 Box就像结构体一样,使用成员运算符 . 来进行访问

实例:
#include <iostream> using namespace std; class Box{ public: double length; // 长度 double breadth; // 宽度 double height; // 高度 // 成员函数的声明 double get(void); void set( double len, double bre, double hei );};// 成员函数的定义double Box::get(void){ return length * breadth * height;} void Box::set( double len, double bre, double hei){ length = len; breadth = bre; height = hei;}int main( ){ Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box Box Box3; // 声明 Box3,类型为 Box double volume = 0.0; // 用于存储体积 // box 1 详述 Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 详述 Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; // box 1 的体积 volume = Box1.height * Box1.length * Box1.breadth; cout << "Box1 的体积:" << volume <<endl; // box 2 的体积 volume = Box2.height * Box2.length * Box2.breadth; cout << "Box2 的体积:" << volume <<endl; // box 3 详述 Box3.set(16.0, 8.0, 12.0); volume = Box3.get(); cout << "Box3 的体积:" << volume <<endl; return 0;} 输出: Box1 的体积:210Box2 的体积:1560Box3 的体积:1536 如上,对于类的成员函数,我们可以把它定义到内部,也可以定义到外部。
定义到内部的话,不需要加 inline 就是类中的内联函数了
或者用范围解析运算符 :: 来单独进行定义成员函数
以下是类中声明定义的class Box{ public: double length; // 长度 double breadth; // 宽度 double height; // 高度 double getVolume(void) { return length * breadth * height; }};有三类,分别为 public、private、protected* ,
class Base { public: // 公有成员,外界可以直接调用(int a=Base.sum;) //struct默认是这一种 protected: // 受保护成员,子类(派生类)中也可以访问 private: // 私有成员,默认类型,只有类及类内的函数等才可以调用, //外界的可以通过调用可以调用的内部函数等来调用 /*说白了,就是它们的权限越来越小*/ /*在以上述的三种方法继承后,派生类的权限的最大值也相应的变为继承类型的最大权限*/ };在 C++ 中,泛型是一种编程特性,允许你编写可以处理不同数据类型的代码,而不需要为每种数据类型都编写单独的代码。
泛型在 C++ 中主要通过模板(templates)来实现。模板是一种编写代码的方式,可以处理任何数据类型。你可以创建函数模板和类模板。
以下是一个简单的函数模板的例子:
template <typename T>T max(T a, T b) { return (a > b) ? a : b;}在这个例子中,max 是一个函数模板,可以接受任何类型的参数 a 和 b。T 是一个占位符,代表任何数据类型。你可以使用这个函数模板来比较任何类型的两个值,例如:
int a = max<int>(3, 4); // 返回 4double b = max<double>(3.2, 2.2); // 返回 3.2类模板的工作方式类似,但它们用于创建可以处理任何数据类型的类。例如,C++ 标准库中的 std::vector 就是一个类模板,可以用来创建可以存储任何类型的动态数组。
这就是 C++ 的泛型。它可以让你编写更加灵活和可重用的代码。
使用#include <fstream>来对文件进行操作
| 数据类型 | 描述 |
|---|---|
| ofstream | 该数据类型表示输出文件流,用于创建文件并向文件写入信息。 |
| ifstream | 该数据类型表示输入文件流,用于从文件读取信息。 |
| fstream | 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
内容已经丢失,只有文字被保留... 2026-5-4


























分享你的想法,与大家交流讨论
Twikoo 加载失败
Twikoo 脚本加载失败