跳到主要内容 C++ 基础知识详解 | 极客日志
C++
C++ 基础知识详解 C++ 基础知识涵盖了命名空间、IO 流、缺省函数、重载函数、引用、内联函数及 nullptr 关键字。内容介绍了命名空间解决冲突机制,标准 IO 流的使用及效率优化,默认参数的定义规则,编译时多态的重载原理,引用的别名特性及 const 引用对临时对象生命周期的管理,内联函数的优化机制,以及 nullptr 相比 NULL 的类型安全性优势。
雪落无声 发布于 2026/2/8 更新于 2026/4/18 6.4K 浏览C++ 基础知识
C++ 的定义
C++ 是一种静态类型、编译式、通用的高级编程语言,由 Bjarne Stroustrup 于 1979 年在 AT&T 贝尔实验室开发。C++ 是 C 语言的扩展,支持过程化编程、面向对象编程和泛型编程。
C++ 的特点
高性能 :直接操作内存,运行效率接近硬件层面
面向对象 :支持类、封装、继承和多态,提升代码可维护性
泛型编程 :通过模板实现通用数据结构,增强代码复用性
跨平台兼容 :代码可编译为 Windows、Linux、macOS 等多个系统的可执行文件
与 C 语言兼容 :作为 C 的超集,可直接使用 C 语言的库和语法
1. 命名空间
对于 C 语言的命名重复是否感到厌烦?C++ 的 namespace 恰好能够解决你的问题。
定义 :C++ 命名空间是一种解决命名冲突的重要机制,通过将全局作用域划分为不同区域来组织代码。
namespace SXR {
int num = 10 ;
}
int main () {
int num = 5 ;
std::cout << num << std::endl;
std::cout << SXR::num << std::endl;
}
运行结果为:5 10
同时也可以命名的嵌套
namespace SXR {
namespace num1 {
int num = 20 ;
}
namespace num2 {
int num = 30 ;
}
}
int main () {
int num = 5 ;
std::cout << num << std::endl;
std::cout << SXR::num1::num << std::endl;
std::cout << SXR::num2::num << std::endl;
}
运行结果为:5 20 30
当然命名空间中还可以包含函数和结构体等。
使用
分为局部与全局使用
全局 :using namespace std(通常练习中使用)
局部 :std::
2. IO 流 input/output stream (初步认识)
定义 :C++ IO 流是基于流对象实现的输入输出机制,分为标准 IO(控制台)、文件 IO(磁盘文件)、字符串 IO(内存字符串)三大类,本质是数据在'源/目标'与程序间的字节流传输。(该处主要与标准 IO 有关)
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online
包含函数 :
cin :即为 char input,是 IO 流中的输入函数。实现数据的输入,既可以单个赋值,也可多个同时赋值。(可以自动识别类型)
cout :即为 char output,是 IO 流中的输出函数。实现数据的输出,既可以单个输出,也可以多个同时输出。(可以自动识别类型)
endl :即为 end line,是 IO 流中实现换行的函数(机制复杂后面章节解释),相当于\n。
int num_1;
float num_2;
double num_3;
std::cin >> num_1;
std::cin >> num_2 >> num_3;
std::cout << SXR::num1::num << '\n' << num << ' ' ;
std::cout << SXR::num2::num << std::endl;
在竞赛中可能会需要提高输入输出的效率,那么就可以用这个代码
C++ 中提高 IO 流效率方法:
std::ios_base::sync_with_stdio (false );
std::cin.tie (nullptr );
std::cout.tie (nullptr );
3. 缺省函数
定义 :C++ 中的缺省函数(也叫'默认参数函数')是指在声明/定义函数时,为参数指定默认值,调用函数时若未传递该参数,则自动使用默认值。
类别 :根据参数的完全度分为全缺省与半缺省。全缺省即函数参数全赋值,半缺省则为函数参数部分赋值(关键:必须从左到右连续缺省)
void Fun (int a = 0 , int b = 5 ) {
cout << a << " " ;
cout << b << endl;
}
Fun (10 , 20 );
Fun (5 );
Fun ();
void Sad (int a, int b = 10 ) {
cout << a << " " << b << endl;
}
Sad (4 );
Sad (6 , 8 );
运行结果为:10 20;5 20;0 5 ; 4 10 ; 6 8
注意 :声明与定义分离时,只需要声明处给出默认值,否则编译错误
4. 重载函数
定义 :重载函数是 C++ 中的核心特性,属于多态的一种(编译时多态/静态多态),指:在同一作用域内,定义多个同名函数,但参数列表(参数个数、类型、顺序)不同,编译器会根据调用时传入的实参匹配对应的函数。
形成关键 :1. 参数个数,2. 参数类型,3. 参数顺序(无关 1.返回值类型 2.参数名不同 3.const 修饰)
void f () {
cout << "f()" << endl;
}
void f (int a) {
cout << "f(int a)" << endl;
}
int Add (int left, int right) {
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add (double left, double right) {
cout << "double Add(double left, double right)" << endl;
return left + right;
}
void f (int a, char b) {
cout << "f(int a, char b)" << endl;
}
void f (char b, int a) {
cout << "f(char b, int a)" << endl;
}
Add (10 , 20 );
Add (10.1 , 20.2 );
f ();
f (10 );
f (10 , 'a' );
f ('a' , 10 );
void f () {
cout << abc << endl;
}
void f (int a = 10 ) {
cout << a << endl;
}
此处会因为 f() 既可以指向上面的函数,又可以指向下面的缺省函数,编译报错。
5. 引用(本节重点)
定义 :引用是 C++ 特有的语法特性,本质是变量的'别名'(Alias)——它并非新开辟内存空间,而是对已有变量的内存地址做'绑定',操作引用等价于直接操作被绑定的原变量。
类型& 引用别名=引用对象;
甚至可以给一个变量起多个别名,并且变量与别名的地址一致,修改其中一个值,全部都会改变。
int num = 10 ;
int & a = num;
int & b = a;
cout << num << " " << a << " " << b << endl;
a = 15 ;
cout << num << " " << a << " " << b << endl;
特性 :
定义时必须初始化
一个变量可以有多个引用
引用一旦引用一个实体,就不能引用其他实体
使用 :主要用于引用传参和引用做返回值
void Swap (int & rx, int & ry) {
int tmp = rx;
rx = ry;
ry = tmp;
}
int main () {
int x = 0 , y = 1 ;
cout << x << " " << y << endl;
Swap (x, y);
cout << x << " " << y << endl;
return 0 ;
}
可以看到这里实现了通过 Swap 函数交换下 x,y 的值。
int & STTop (ST& rs) {
assert (rs.top > 0 );
return rs.a[rs.top];
}
int main () {
cout << STTop (st1) << endl;
STTop (st1) += 10 ;
cout << STTop (st1) << endl;
return 0 ;
}
返回的是变量的别名,在 main 中接受后,可以直接对其存储的数据进行修改
而在 C 语言中必须返回的是地址,不然只是修改副本而不能对数据本身进行处理
int * STTop (ST* rs) {
assert (rs->top > 0 );
return &rs.a[rs.top];
}
*STTop (&st1) += 10 ;
const 引用 :
const 引用(const 类型&)是 C++ 中引用的重要变种,核心作用是禁止通过引用修改绑定的变量/值,同时支持绑定常量、临时值等只读场景,是 C++ 中保证数据只读、提升代码安全性和灵活性的关键语法。
在此知识点中必须提前了解两个知识点——读写权限和临时对象:
读写权限
在 C++ 中,const 是经典的只读关键字,本质是'通过该标识符不能改变值',通过 const 使得数据分为了两种权限——可读可写与只读,而读写权限的核心规则:可收缩,不可扩张 ,就有了权限的收缩与扩张。
临时对象
C++ 中有这一种由编译器自动创建的未命名对象:临时对象,它通常用来暂存表达式的求值结果,临时对象具有常性,即是右值,因此只能由 const 修饰的左值引用 。
它的生命周期极短,默认在创建它完整表达式结束时销毁,而 const 能够延长它的生命周期(到 main 函数结束)。(完整表达式就是分号前的语句)
产生场景 :表达式计算;类型隐式转换;函数返回值;匿名对象构造
易错示例:
int main () {
double b = 3.14 ;
const int & ref = b;
cout << ref << endl;
b = 5.67 ;
cout << ref << endl;
return 0 ;
}
string getStr () {
return "hello" ;
}
int main () {
string s1 = getStr ();
const string& s2 = getStr ();
cout << s2 << endl;
return 0 ;
}
场景 2 的本质为 const 延长了临时变量的生命周期,使得引用&能够锁定 getStr 函数返回的临时对象。
int main () {
const int a = 10 ;
int & ra = a;
const int & ra = a;
int b = 20 ;
const int & rb = b;
return 0 ;
}
第一例:读写权限放大,编译错误
第二例:ra 仅为只读权限,不能进行修改
第三例:rb 为只读权限,引用对象 b 为读写,权限收缩正确
并且 const 有着核心优势,const 加引用可以绑定变量
int main () {
const int & ref1 = 5 ;
cout << ref1 << endl;
int a = 1 , b = 2 ;
const int & ref2 = a + b;
cout << ref2 << endl;
string getStr () {
return "hello" ;
}
const string& ref3 = getStr ();
cout << ref3 << endl;
return 0 ;
}
这里来分析函数参数在:const 类型&、类型&、类型的区别与优势
首先,const 引用类型可以支持函数参数为常量与表达式
其次,const 引用类型为只读权限,而后两种能够改变值,但引用改变的是传入的值,最后一种改变的是副本的值。
区分:可见指针与引用是相似的,但两则其实有着本质区别。
• 语法概念上引⽤是⼀个变量的取别名不开空间 ,指针是存储⼀个变量地址,要开空间 。
• 引⽤在定义时必须初始化 ,指针建议初始化 ,但是语法上不是必须的。
• 引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象 ;⽽指针可以在不断地改变指向对象 。
• 引⽤可以直接访问 指向对象,指针需要解引⽤才是访问指向对象。
• sizeof 中含义不同,引⽤结果为 引⽤类型的⼤⼩ ,但指针始终是地址空间所占个数 (32 位平台下占 4 个字节,64 位下是 8byte)
• 指针很容易出现空指针和野指针 的问题,引⽤很少出现,引⽤使⽤起来相对更全⼀些。
6. 内联函数
定义 :内联函数是 C++ 中用于消除函数调用开销的优化手段,本质是编译器将内联函数的代码'直接嵌入'到调用处(而非执行传统的函数调用指令),以空间换时间,提升程序执行效率。(在函数前加上 inline)
作用 :内联函数可以消除函数调用的开销(如:1. 保存当前函数栈帧 2. 跳转到函数地址执行 3. 执行完毕后返回原地址)
#include <iostream>
using namespace std;
inline void f (int i) ;
#include "F.h"
void f (int i) {
cout << i << endl;
}
#include "F.h"
int main () {
f (10 );
return 0 ;
}
特色 :inline 是编译器的建议,编译器可以忽略建议,会自行判断是否合适,一般当涉及循环、分支、递归等就会忽略建议
注意 :内联函数需要声明与定义在同一处,避免连接错误
7. nullptr 使用原因:常规的 C/C++ 中 NULL 实际是一个宏,在 stddef.h 文件中可以看到定义
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
#endif
可见 NULL 通常被定义为 0 或 (void*)0,这种情况下会出现:重载函数匹配函数错误和赋值给非指针类型(如 int),从而错误。
#include <iostream>
using namespace std;
void func (int x) {
cout << "调用 int 版本:" << x << endl;
}
void func (char * p) {
cout << "调用指针版本" << endl;
}
int main () {
func (NULL );
return 0 ;
}
定义 :nullptr 是 C++11 引入的一个关键字,用于表示空指针。与传统的 NULL 不同,nullptr 是一个类型安全的空指针常量,能够避免类型不匹配的问题
类型 :nullptr_t,本质为'指针空值类型',可转为任意指针类型
不可转为非指针类型 :无法赋值给非指针类型,编译报错
重载匹配 :优先匹配指针类型的重载函数
可替代使用 NULL 场景 :如 if (p == nullptr) 等价于 if (p == NULL)