目录

前言

一、指针和引用的区别

1.基本定义

2.主要区别

3.代码说明

3.1 初始化与绑定

3.2 空值处理

3.3 函数返回值

4.总结

二、堆和栈的区别

1.基本定义:

2.主要区别

3.代码说明

4.总结


前言

本教程旨在提取最精炼、实用的C++面试知识点,供读者快速学习及本人查阅复习所用。本文配套精简版本《C++面试宝典》已整理,免费领取地址:https://pan.quark.cn/s/c991f40d40a7

一、指针和引用的区别

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.总结

栈:

        优点:快速、自动管理、线程安全

        缺点:空间有限、生命周期固定

堆:

        优点:空间大、灵活、跨作用域使用

        缺点:速度慢、需手动管理、可能碎片化

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐