C++高频面试问题总结
·
目录
前言
一、指针和引用的区别
1.基本定义
指针:一个变量,存储另一个变量的内存地址
语法:类型* 指针名;
示例:
int* p = &x;
引用:某个变量的别名,本质上是变量的另一个名字
语法:类型& 引用名=变量;
示例:
int& ref=x;
2.主要区别
| 特性 | 指针 | 引用 |
| 初始化 | 可以不初始化 | 必须初始化,且不可更改绑定对象 |
| 空值 | 可以为nullptr | 不能为nullptr |
| 重绑定 | 可以指向其他变量 | 不可重绑定 |
| 内存占用 | 4/8字节 |
不占用额外空间 |
| 数组/函数参数 | 可以指向数组/函数 | 仅能绑定单个变量 |
引用无法重绑定:

3.代码说明
3.1 初始化与绑定
指针:可以延迟初始化/重新赋值
int x = 10;
int* p; // 合法,但危险(野指针)
p = &x; // 绑定到x
int y = 20;
p = &y; // 重绑定到y
引用:必须初始化且不可重绑定
int x = 10;
int& ref = x; // 必须初始化
// ref = y; // 错误!不能重绑定
3.2 空值处理
指针:可以为空
int* p = nullptr;
if (p != nullptr) {
*p = 10; // 安全检查
}
引用:不能为空,必须绑定有效对象

3.3 函数返回值
指针:可以返回局部变量的地址,但危险,除非静态/动态分配
int* getPtr() {
static int x = 10; // 静态变量可行
return &x;
}
引用:更安全地返回局部变量(需确保生命周期)
int& getRef() {
static int x = 10; // 静态变量可行
return x;
}
4.总结
指针:更灵活,但更危险,适合底层操作和动态内存
引用:更安全且语法简介,适合函数参数和别名场景
二、堆和栈的区别
1.基本定义:
栈(Stack)
由编译器自动管理,用于存储局部变量、函数参数和返回地址
分配和释放速度快,先进后出(LIFO)
控件有限(通常几MB)
堆(Heap)
由程序员手动管理(通过new/delete或malloc/free),用于动态内存分配
分配速度慢,需要手动控制生命周期
空间大,但可能产生内存碎片
2.主要区别
| 特性 | 栈 | 堆 |
| 管理方式 | 自动 | 手动 |
| 分配速度 | 快 | 慢 |
| 内存大小 | 较小 | 较大 |
| 生命周期 | 函数结束自动释放 | delete/free |
| 内存碎片 | 无 | 可能产生 |
| 访问效率 | 高 | 低 |
| 多线程安全 | 每个线程有独立栈 | 需要同步机制 |
3.代码说明
栈:变量在作用域结束自动释放
void foo() {
int x = 10; // 分配在栈上
// 函数结束时x自动释放
}
堆:显示分配和释放,否则导致内存泄漏
void bar() {
int* p = new int(20); // 分配在堆上
delete p; // 必须手动释放
// 若忘记delete,会导致内存泄漏
}
栈:空间有限,递归过深会导致栈溢出
for (int i = 0; i < 1000; i++) {
int* p = new int(i); // 频繁分配可能产生碎片
delete p;
}
堆:空间大,但频繁分配小对象可能导致内存碎片
for (int i = 0; i < 1000; i++) {
int* p = new int(i); // 频繁分配可能产生碎片
delete p;
}
4.总结
栈:
优点:快速、自动管理、线程安全
缺点:空间有限、生命周期固定
堆:
优点:空间大、灵活、跨作用域使用
缺点:速度慢、需手动管理、可能碎片化
更多推荐
所有评论(0)