C++从入门到实战(二十二)stack的介绍和使用

C++从入门到实战(二十二)stack的介绍和使用

  • 前言
  • 一、什么是stack
    • [1.1 stack的核心特性](#1.1 stack的核心特性)
    • [1.2 stack与序列容器的核心差异](#1.2 stack与序列容器的核心差异)
  • 二、stack的核心接口详解
    • [2.1 构造函数:stack()](#2.1 构造函数:stack())
    • [2.2 判空操作:empty()](#2.2 判空操作:empty())
    • [2.3 大小获取:size()](#2.3 大小获取:size())
    • [2.4 栈顶访问:top()](#2.4 栈顶访问:top())
    • [2.5 入栈操作:push()](#2.5 入栈操作:push())
    • [2.6 出栈操作:pop()](#2.6 出栈操作:pop())
  • 三、stack的综合使用示例
  • 四、stack核心接口总结

前言

  • 在前几篇博客中,我们系统学习了vector(动态数组)、list(双向循环链表)、string(动态字符串)等序列式容器------它们都支持随机访问或双向遍历,可直接操作任意位置的元素。
  • 本篇将聚焦STL中的适配器容器 ------stack(栈):它并非独立的容器,而是基于其他序列容器(如dequevector)封装而成的"适配容器",核心遵循后进先出(LIFO) 原则,仅支持栈顶的插入、删除和访问操作。
  • 我们将从stack的核心特性入手,详解其常用接口的用法、底层实现逻辑,并结合示例说明其典型应用场景,帮助你掌握栈的核心使用技巧。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482


C++官方stack文档
https://cplusplus.com/reference/stack/stack/

一、什么是stack

std::stack 是C++ STL中的容器适配器 (Container Adapter),而非原生容器------它封装了底层序列容器(默认是deque双端队列(后续我们也会详细讲解)),并仅暴露符合"栈"特性的接口,核心规则是:最后入栈的元素最先出栈(LIFO, Last In First Out)

1.1 stack的核心特性

  • 单向操作 :仅能对栈顶 进行插入(push)、删除(pop)和访问(top)操作,无法访问栈中间或栈底的元素。
  • 无随机访问 :不支持下标([])、迭代器遍历,也没有begin()/end()接口。
  • 适配器特性 :底层可复用dequevectorlist等序列容器(需满足back()push_back()pop_back()empty()size()接口),默认选择deque(兼顾效率和内存特性)。
  • 轻量级封装stack本身仅提供接口封装,无额外内存开销,性能依赖底层容器。

1.2 stack与序列容器的核心差异

对比维度 stack(栈) vector(动态数组) list(双向链表)
访问方式 仅栈顶(top() 随机访问([]/at() 双向遍历(迭代器)
插入/删除位置 仅栈顶(push()/pop() 任意位置(insert()/erase() 任意位置(insert()/erase()
迭代器支持 不支持 支持随机访问迭代器 支持双向迭代器
底层实现 容器适配器(默认deque 连续内存 离散节点(双向循环链表)
核心规则 后进先出(LIFO) 顺序存储 顺序存储

二、stack的核心接口详解

stack的接口极简,仅包含构造、判空、大小、栈顶访问、入栈、出栈6个核心接口,以下是详细说明:

2.1 构造函数:stack()

语法

cpp 复制代码
stack<T> st;  // T为存储的元素类型(如int、string等)
// 或指定底层容器:stack<T, Container> st;

作用

  • 创建一个空的栈,底层容器默认初始化(如deque的默认构造)。

示例

cpp 复制代码
#include <stack>
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main() {
    // 1. 默认构造(底层deque)
    stack<int> st1;

    // 2. 指定底层容器为vector
    stack<int, vector<int>> st2;

    // 3. 指定底层容器为list
    stack<int, list<int>> st3;

    cout << "st1是否为空:" << st1.empty() << endl;  // 输出:1(true)
    return 0;
}

2.2 判空操作:empty()

语法

cpp 复制代码
bool empty() const;

作用

  • 检测栈是否为空(无元素),为空返回true,否则返回false

示例

cpp 复制代码
stack<int> st;
cout << st.empty() << endl;  // 空栈,输出:1(true)

st.push(10);
cout << st.empty() << endl;  // 非空,输出:0(false)

2.3 大小获取:size()

语法

cpp 复制代码
size_t size() const;

作用

  • 返回栈中元素的个数,类型为size_t(无符号整数)。

示例

cpp 复制代码
stack<int> st;
st.push(1);
st.push(2);
st.push(3);

cout << "栈的大小:" << st.size() << endl;  // 输出:3

2.4 栈顶访问:top()

语法

cpp 复制代码
// 普通版本:返回栈顶元素的引用(可修改)
T& top();
// const版本:返回栈顶元素的const引用(只读)
const T& top() const;

作用

  • 返回栈顶元素的引用(栈顶是最后入栈的元素),注意:空栈调用top()会导致未定义行为

示例

cpp 复制代码
stack<int> st;
st.push(10);
st.push(20);

// 普通版本:修改栈顶元素
st.top() = 30;  
cout << "栈顶元素:" << st.top() << endl;  // 输出:30

// const版本:只读
const stack<int> cst(st);
cout << "const栈顶元素:" << cst.top() << endl;  // 输出:30
// cst.top() = 40;  // 错误!const引用不可修改


2.5 入栈操作:push()

语法

cpp 复制代码
// 拷贝入栈:将val拷贝到栈顶
void push(const T& val);
// 移动入栈(C++11):将val移动到栈顶(效率更高)
void push(T&& val);
// 原地构造(C++11):直接在栈顶构造元素,避免拷贝
template <class... Args>
void emplace(Args&&... args);

作用

  • 将元素添加到栈顶,底层调用容器的push_back()(或emplace_back())。

示例

cpp 复制代码
stack<int> st;
// 普通拷贝入栈
st.push(1);
st.push(2);

// emplace原地构造(效果同push(3),但效率更高)
st.emplace(3);

cout << "栈顶元素:" << st.top() << endl;  // 输出:3
cout << "栈的大小:" << st.size() << endl;  // 输出:3

2.6 出栈操作:pop()

语法

cpp 复制代码
void pop();

作用

删除栈顶元素(仅删除,不返回),底层调用容器的pop_back();注意:空栈调用pop()会导致未定义行为

示例

cpp 复制代码
stack<int> st;
st.push(1);
st.push(2);
st.push(3);

cout << "出栈前栈顶:" << st.top() << endl;  // 输出:3
st.pop();  // 删除栈顶元素3
cout << "出栈后栈顶:" << st.top() << endl;  // 输出:2
cout << "出栈后大小:" << st.size() << endl;  // 输出:2

三、stack的综合使用示例

stack的核心操作是"入栈→访问栈顶→出栈"的循环,以下是完整示例,包含栈的基本操作和"遍历"技巧(stack无迭代器,需借助临时栈):

cpp 复制代码
#include <stack>
#include <iostream>
using namespace std;

int main() {
    // 1. 初始化栈并入栈元素
    stack<int> st;
    st.push(10);
    st.push(20);
    st.push(30);
    st.push(40);

    // 2. 基本属性
    cout << "栈是否为空:" << st.empty() << endl;  // 输出:0
    cout << "栈的大小:" << st.size() << endl;    // 输出:4
    cout << "栈顶元素:" << st.top() << endl;     // 输出:40

    // 3. 出栈操作(删除栈顶)
    st.pop();
    cout << "出栈后栈顶:" << st.top() << endl;  // 输出:30

    // 4. 模拟遍历栈(需借助临时栈,遍历后原栈为空)
    stack<int> temp;  // 临时栈
    cout << "栈的元素(从栈顶到栈底):";
    while (!st.empty()) {
        int val = st.top();
        cout << val << " ";  // 输出:30 20 10
        temp.push(val);      // 保存到临时栈
        st.pop();            // 原栈出栈
    }
    cout << endl;

    // 5. 恢复原栈(从临时栈倒回)
    while (!temp.empty()) {
        st.push(temp.top());
        temp.pop();
    }
    cout << "恢复后栈的大小:" << st.size() << endl;  // 输出:3

    return 0;
}

输出结果

四、stack核心接口总结

接口名 语法 功能描述 注意事项
构造 stack<T> st; 创建空栈,默认底层容器为deque 可指定底层容器(如vector/list)
empty() bool empty() const; 判断栈是否为空,空返回true 无参数,时间复杂度O(1)
size() size_t size() const; 返回栈中元素个数 返回值为无符号整数
top() T& top(); 返回栈顶元素的引用(可修改) 空栈调用会导致未定义行为
push() void push(const T& val); 将val拷贝入栈顶 底层调用push_back()
emplace() void emplace(Args&&... args); 栈顶原地构造元素 C++11新增,效率高于push()
pop() void pop(); 删除栈顶元素(无返回值) 空栈调用会导致未定义行为

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482

|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |

相关推荐
行者963 分钟前
Flutter适配OpenHarmony:国际化i18n实现中的常见陷阱与解决方案
开发语言·javascript·flutter·harmonyos·鸿蒙
csbysj20204 分钟前
RSS 阅读器:全面解析与使用指南
开发语言
xie_pin_an9 分钟前
C++ 从入门到进阶:核心知识与实战指南
java·c++·算法
溪海莘12 分钟前
如何部署使用uv管理依赖的python项目 ?
开发语言·python·uv
我送炭你添花13 分钟前
Python与串口:从基础到实际应用——以Pelco KBD300A模拟器项目为例
开发语言·python·自动化·运维开发
No0d1es14 分钟前
2025年12月 GESP CCF编程能力等级认证C++八级真题
开发语言·c++·青少年编程·gesp·ccf
hqwest33 分钟前
码上通QT实战10--监控页面02-绘制温度盘
开发语言·qt·自定义控件·qwidget·提升部件·qt绘图
fqbqrr34 分钟前
2601C++,概念与约束及推导本
c++
m0_6265352040 分钟前
快速排序学习 l方法 h方法
开发语言·python
superman超哥1 小时前
Rust String与&str的内部实现差异:所有权与借用的典型案例
开发语言·后端·rust·rust string·string与str·内部实现·所有权与借用