停车场模拟程序核心实现:栈与队列建模、出库周转与计费避坑指南
简介这是一份基于VC开发的停车场模拟程序完整工程由西电研究生编写面向计算机专业学生及需要完成课程设计的开发者。程序模拟车辆进入、离开、停车位分配与管理等运营场景通过多个模块类车辆、车位、输入处理等实现核心逻辑帮助理解数据结构、算法与事件驱动编程。压缩包共60个文件大小约1.74MB包含头文件(.h)、源文件(.cpp)、工程配置(.dsp/.dsw)、可执行程序(.exe)及界面资源(.rc/.ico/.bmp)等可完整查看从代码到界面的实现。已有272人浏览学习。从中可获取完整的项目源码、可执行程序及ReadMe说明代码结构清晰可学习用队列管理入场车辆、用栈模拟后进先出离场规则、设计停车位状态管理以及用户交互和异常处理等关键技巧适合作为模拟程序设计或课程设计的参考。1. vc 停车场模拟程序先用明白再动手改这份骨架能省你两个通宵拿到一份 VC 停车场模拟程序和自己在学校里写的版本最大的区别是里面不只有出入场的弹窗还有一套勉强能看的业务逻辑和数据结构。所谓「模拟」重点不在界面有多华丽而在你能不能解释清楚每一辆车进场后停在哪、出场时又从哪儿走以及那几块钱停车费是怎么按分钟算出来的。本文我会从栈和队列的建模说起一直讲到具体函数的填法、容易翻车的几个细节最后给你两个能直接拿去演示的进阶技巧。适合要交课程设计、或者想给旧代码补功能的人读——新手跟步骤能跑通熟手看参数和边界就够了。2. 核心数据模型为什么是栈套队列而不是数组硬怼很多第一次接触这个项目的同学第一反应是用一个结构体数组存所有车每辆车上记录一个车位号。这个方案在「只存数据不模拟过程」的时候是成立的一旦要模拟「停车场的车必须从出口倒出去」这个动作数组就会变得非常难维护。所以真正合理的模型是车库内部用栈车库外部的便道用队列。2.1 车库内部用栈后进先出的出库顺序先看栈。栈的特点是先进后出这和真实停车场的物理结构是对应的——或者说是对应老式的那种只有一个出入口、车要倒进去再倒出来的停车场。你把车 A 停进最里面的 1 号位然后车 B 停在它前面最后车 C 停在出口附近。此时如果 B 要离场C 必须先把位置让出来开出去等着B 再倒出来最后 C 按原来的顺序重新回到栈里。这个过程在数据结构课上叫「中间车临时出栈再回栈」代码上就是多做一次临时栈的周转。这个设计的选型理由不是「课本这么写的」而是它天然匹配了业务的异常分支。比如栈里有五辆车你要让栈底的第二辆离场程序必须先把栈顶的三辆依次挪到临时栈等目标车离开后再把这临时栈的车一辆辆压回原栈。如果没有栈这个结构你要自己维护一个「后面几辆车先挪走」的数组逻辑会散落在函数各处找 bug 的时候相当痛苦。2.2 便道用队列先到先等的公平性车库满了之后新来的车不能直接进得在便道上排队。这个场景对应的数据结构就是队列。队列和栈正好相反先进先出——先到便道的车等里面有空位时先进去。这里有一个容易忽略的细节从便道压入车库时其实是从队头出队直接压进车库的栈顶。很多初学的人在写这一步时会顺手写一个「从队尾取车」的逻辑那是错的。便道队列的容量一般是固定的典型参数是 5~10 辆。超出便道容量后可以选择「拒绝入场」或「继续等待」这两种策略在代码里的差别只有一句判断。在多数课程设计里超出便道容量的车会收到「停车场已满」的提示然后离开——简单直接也方便验收时讲清楚。2.3 车辆信息的结构体与自定义链表节点不管栈还是队列内部节点都建议用自定义链表节点而不是直接塞一个结构体数组。原因有两点第一链表在临时栈周转时不需要整块拷贝数据只需要改指针第二链表可以方便地在中间插入或删除这在处理「便道上有车等不了走了」这种例外时非常省事。一个典型的车辆信息结构体大概长这样typedef struct tagCarInfo { char plate[12]; // 车牌号预留 12 字节够存蓝牌和绿牌 int carType; // 0 表示小型车1 表示大型车 time_t inTime; // 入场时间用 time_t 存方便后面用 difftime 算时长 time_t outTime; // 出场时间出场时再赋值 int isMember; // 0 非月卡1 月卡计费时会用到 } CarInfo; typedef struct tagStackNode { CarInfo data; struct tagStackNode* next; } StackNode;在实际工程里这份资源通常还会给每个节点加一个pos字段用来标记当前在栈里的位置序号。这里给个建议pos字段不用每次出入场都全量更新只有在你需要「显示每一个车位当前停着谁」时才去遍历重算。否则频繁的写操作会让你的调试过程多出一堆无谓的改动。3. 工程实现步骤从空工程到能跑通的出入场流程拿到这份资源后第一步不是打开就看代码而是先按「入口 → 数据结构初始化 → 主循环 → 计费输出」的顺序把文件的脉络理出来。一份典型的 VC 停车场模拟程序主要工程文件就四五个理清楚之后你会发现核心逻辑非常集中。3.1 工程文件结构一份班底里你真正要改哪几个文件以常见的控制台模拟版为例完整工程大约包含以下几个文件文件名作用是否常改main.cpp程序入口负责打印菜单和调用业务函数少改park.h/park.cpp栈和队列的定义以及出入场、计费的主体逻辑重点改carinfo.h车辆信息结构体定义少改utils.cpp时间格式化、车牌输入合法性校验等辅助函数偶尔改data.txt可选车辆进出场的记录文件用于持久化运行后自动生成打开工程后的第一步建议先在park.cpp里搜索三个函数InCar、OutCar和CalcFee。这三个函数占整个项目工作量的七成以上你只需要确认它们在哪个文件、函数多少行就能大致判断这份代码的封装水平。如果你看到某个函数超过一百五十行说明它很可能把数据结构操作和界面打印混在一起这时候优先看调用关系不要逐行读。编译之前先做一件事确认工程的字符集设置。老版本 VC 工程的默认字符集是多字节而新版本 Visual Studio 默认是 Unicode直接打开老工程会有一堆CString和char*的类型转换报错。解决方法是把项目属性里的「字符集」改成「使用多字节字符集」这是复现这类老工程的第一步也是最容易被忽略的一步。3.2 入场逻辑压栈、排队与登记三个动作的先后顺序入场流程的整体顺序是先判断车库栈满没满满了就尝试入便道队列没满就压入栈顶同时记录当前时间。这是标准流程。但有一个细节车辆入场时需要在界面显示「当前车位余量」和「便道排队数量」。这两个信息如果每次都用遍历去数链表长度在演示场景里问题不大但如果你的模拟程序要跑几千辆车的事件流建议用一个全局变量维护stackSize和queueSize入场出场--。入场的核心代码可以这样写// 返回值0 成功入场1 车库满已入便道2 车库和便道都满 int InCar(Stack* garage, Queue* lane, CarInfo* car) { if (garage-size GARAGE_CAPACITY) { StackPush(garage, *car); // 压入车库栈顶 garage-size; return 0; } if (lane-size LANE_CAPACITY) { QueuePush(lane, *car); // 进入便道队列尾部 lane-size; return 1; } return 2; // 都满了拒绝入场 }这里有几个参数值得说明GARAGE_CAPACITY和LANE_CAPACITY在课程设计里通常定义成全局常量建议放在一个独立的头文件里方便答辩时改参数演示不同容量下的表现。StackPush内部要处理链表头插入的逻辑QueuePush则是尾插入。这两个函数的区别在代码里要用注释标出来防止后面有人复制错了。还有一个容易漏掉的动作入场成功后要把车辆信息写入记录文件。写入的格式一般是「车牌号入场时间入库类型」这个文件既是调试用的日志也是答辩时证明程序真实运行的依据。很多同学翻车就翻在这里——入场时没写文件出场时才想起要读结果读取时发现文件里根本没记录。3.3 出场与计费临时栈周转和阶梯计价的核心代码出场是全场最复杂的一块。假设目标车在栈的中间位置你要做的是把其上面的车全部挪到临时栈等目标车出库后再把临时栈里的车按原有顺序压回来。整个过程是栈顶弹出一辆放临时栈 → 循环直到栈顶是目标车 → 弹出目标车并计费 → 把临时栈全部弹回原栈。这个逻辑的每一步都在动指针有一个顺序写反就会导致链表成环程序直接死循环。核心代码片段如下void OutCar(Stack* garage, Stack* tempStack, Queue* lane, const char* plate) { CarInfo found; bool isFound false; // 第一步从栈顶开始找目标车 while (garage-top ! NULL) { StackNode* node StackPop(garage); if (strcmp(node-data.plate, plate) 0) { found node-data; free(node); isFound true; break; } StackPush(tempStack, node-data); // 非目标车先挪到临时栈 free(node); } if (isFound) { // 第二步计费并输出 double fee CalcFee(found); PrintReceipt(found, fee); // 第三步临时栈的车按原序压回 while (tempStack-top ! NULL) { StackNode* node StackPop(tempStack); StackPush(garage, node-data); free(node); } // 第四步便道有车则补充一辆进来 if (lane-size 0) { CarInfo nextCar QueuePop(lane); StackPush(garage, nextCar); } } }第二步的CalcFee函数建议做成独立模块不要像一些粗糙代码那样直接把计费公式写在OutCar里。常见的计费策略是两小时内收五元超过两小时后每小时加两元不足一小时按一小时算。用difftime得到秒数后换算成小时向上取整即可。月卡车辆的计费则是直接返回零这个判断放在计费函数的第一行别放在外面判断——否则你会在界面打印里看到「月卡已缴」和「本次停车费 0 元」同时出现那种重复提示很影响观感。还要注意一个边界当车库栈只有一辆车且目标车就是栈顶时第一步的循环一次就找到了临时栈完全用不上此时代码必须能正常跳过「压回临时栈」的步骤不要出现对空的tempStack做弹栈操作。这个边界在调试时最容易触发因为你自己测试通常只停一辆车就急着出场。4. 常见问题与避坑六个我反复踩的坑老工程之所以叫老工程是因为它身上带着一堆历史遗留问题。下面这几条是我在复现和改造这类程序时真实遇到过的每一条都能对应到一个具体的报错或者逻辑异常。按「现象 → 原因 → 解决」写清楚你遇到类似情况可以直接照方抓药。4.1 输入车牌后程序没有任何反应现象在控制台输入车牌号回车后界面既不提示成功也不提示失败程序像卡住了一样。原因最常见的不是死循环而是scanf或cin读取时把换行符留在了输入缓冲区。第二次读取时gets或fgets直接读到了那个残留的换行符导致字符串长度为 0后续strcmp自然匹配不上。解决在每次读取字符串之前加一次缓冲区的清空操作。用fflush(stdin)在某些编译环境下不可靠我一般用while (getchar() ! \n);来吃掉残留换行。如果你用的是新版本的 Visual Studio也可以改用fgets配合手动去除末尾换行的方式这个更稳。4.2 中间车出场后后面几辆车的顺序全乱了现象车库内有 A、B、C 三辆车B 要出场。程序执行完后车库内的顺序变成了 C、A而正确结果应该是 A、C。原因临时栈周转时从原栈弹出的顺序是 C、B碰到 B 时弹出然后压回临时栈的顺序是 C、AA 在 B 下面被先弹出先压入。关键在第三步——你按弹出顺序直接压回临时栈会导致顺序反转。要正确恢复需要再倒一手或者干脆在弹出时直接逆序放入临时栈。解决最简单的方法是造第二个临时栈。原栈弹出的非目标车先压入临时栈一等目标车出库后把临时栈一里的车全部弹出压入临时栈二再从临时栈二弹回原栈。两步反转顺序就对了。很多精简版代码只用一个临时栈这就是顺序错乱的根源。4.3 计费金额和实际时间对不上现象入场时 10 点 00 分出场时 10 点 30 分理论上收费 5 元但程序算出 9 元或者 1 元。原因时间类型混用。入场时间用了time_t存出场时却用clock()算时长。clock()返回的是 CPU 运行时间不是墙上时间如果你的程序中间有一大段打印信息或者人机交互这个值会严重偏大或偏小。解决统一用time()获取系统时间用difftime计算秒数差。注意difftime的返回类型是double计算小时数时要用ceil(seconds / 3600.0)向上取整而不是整数除法。整数除法会把 3599 秒算成 0 小时直接导致免费出场。4.4 工程从老版本迁移到新版本后字符串全变成乱码现象中文菜单和提示全部变成问号或者乱码英文正常。原因老工程是 GB2312 编码新开发环境默认编译为 UTF-8 或 Unicode。最典型的是把CString赋值给char*时出现C2664编译错误或者运行时界面显示乱码。解决两个方案二选一。第一个是在项目属性里把字符集改为「使用多字节字符集」并把源码文件重新用 GB2312 编码保存第二个是把所有用到的CString换成std::string然后统一在输入输出时做转换。我建议选第一个改动最小而且老代码里大量使用%s格式符换成std::string后还要到处.c_str()容易漏。4.5 栈和队列容量常量改小后程序运行一段时间后崩溃现象把GARAGE_CAPACITY从 10 改成 3程序跑到第五六辆车时崩溃报错是访问空指针。原因容量改小时入场判断里的分支走得更频繁但相关的数组或链表初始化代码没有跟着改。常见的是原本用一个定长数组做便道队列容量常量改了但数组长度还是写死的 10。一旦队列元素超过实际数组长度写越界破坏内存。解决所有内存分配全部改成动态分配。队列和栈的节点都用malloc/new创建不要预分配大数组。改完以后容量常量只是判断逻辑里的一个数字不再影响内存布局再怎么改都不会越界。排查上面这些问题时有个笨但有效的方法在小规模的测试用例下一步一步把栈顶指针的地址打印出来每次push和pop都输出当前栈的前三个节点地址。改完代码跑一次基本能定位到所有指针操作层面的 bug。5. 进阶随机车流测试与状态可视化的两个实用技巧程序跑通只是第一步。答辩或者演示的时候最尴尬的时刻是手动一辆一辆地输入车牌、等待、出场整个过程又慢又容易出错。我后来给自己加了一个随机车流生成器把所有的手动输入变成自动事件流演示效率提升明显。核心实现思路是生成随机车牌、随机入场时间间隔、随机停车时长然后按时间顺序压进一个事件队列模拟程序不断从事件队列里取动作执行。这个生成器不用写得很复杂几十行函数就够了。车牌随机生成要注意一点不能用纯随机数因为会生成重复的车牌。我会在生成后用一个哈希表做去重冲突就重新生成。停车时长的分布不要用均匀分布——现实中大多数车停一两个小时偶尔才有停一整天的用简单的指数分布或者直接写一个分段函数让 70% 的时长落在 0.5~3 小时之间演示效果会真实很多。第二个技巧是状态可视化。控制台程序虽然不如图形界面直观但你可以在每辆车进出场时打印一张状态表车位编号、车牌号、入场时间、当前状态在场/已离场。关键是每次打印前清屏保证界面上始终只有一张表而不是流水账一样往下滚。清屏在 Windows API 里是system(cls)注意别在循环里高频调用否则光标闪烁会很难受。数据量大的时候我只在事件发生后才刷新间隔控制在 200 毫秒以上。我还习惯在OutCar返回前加一个统计接口记录「总服务车辆数、总收费金额、平均停车时长」。这些数据在演示总结时非常好用能给答辩老师一个量化的结果而不是停留在「程序能跑」的层面。从那以后我每次拿到这类模拟类的课程设计第一件事就是先把计费和统计模块单独拆出来跑一遍边界测试再碰界面代码——这个习惯帮我少熬了好几个夜。这份资源里的逻辑骨架是完整的你只需要把它看懂、把上面几个坑绕开剩下的改造空间很大。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Python+Pygame实现超级马里奥:横版游戏开发与碰撞检测实战

Python+Pygame实现超级马里奥:横版游戏开发与碰撞检测实战

简介:这是一份使用Python与Pygame库实现的超级马里奥游戏完整源码,面向具备一定Python基础、希望进阶学习游戏开发的同学。项目以马里奥第一关为蓝本,将角色、敌人、平台、道具等抽象为类,完整展示了面向对象设计、事件监听、碰撞…

2026/10/13 11:30:58 阅读更多 →
EasyDL训练与Jetson Nano部署:边缘端目标检测实战指南

EasyDL训练与Jetson Nano部署:边缘端目标检测实战指南

1. 从零到一:为什么选择EasyDL加Jetson Nano这条技术路线搞过边缘端视觉项目的人都有一个共同的痛:模型训练和硬件部署之间隔着一道巨大的鸿沟。训练的时候在服务器上跑得好好的模型,一到嵌入式设备上就各种水土不服——推理速度慢、内存爆掉…

2026/10/13 11:30:58 阅读更多 →
Hive性能优化实战:从执行计划到数据组织的深度调优

Hive性能优化实战:从执行计划到数据组织的深度调优

1. 这不是“调参手册”,而是 Hive 生产环境里活下来的血泪经验很多人一看到“Hive 优化策略”这六个字,第一反应就是翻文档、查参数、背命令——set hive.exec.paralleltrue;set hive.map.aggrtrue;set hive.groupby.skewindatatr…

2026/10/13 11:29:57 阅读更多 →

最新新闻

鸽哒IM源码:生产级私有化即时通讯系统解析

鸽哒IM源码:生产级私有化即时通讯系统解析

简介:这是一套完整的跨平台即时通讯(IM)系统源码,面向中高级Java/Android/iOS开发者及全栈工程师,用于学习和搭建企业级实时通信服务。资源涵盖Web(WebSocketHTML5)、Android(JavaFC…

2026/10/13 21:08:58 阅读更多 →
Python+React低代码平台:元数据驱动的业务系统快速构建方案

Python+React低代码平台:元数据驱动的业务系统快速构建方案

简介:这是一套面向全栈开发初学者与低代码实践者的前后端一体化低代码平台学习资源,聚焦React前端框架与Python后端框架的协同开发模式,帮助非专业开发者快速构建可运行的Web应用,降低传统编码门槛。资源共229个文件,涵…

2026/10/13 21:08:58 阅读更多 →
2020数学建模B题沙漠穿越:Matlab动态规划与剪枝实战解析

2020数学建模B题沙漠穿越:Matlab动态规划与剪枝实战解析

简介:面向备战2020年数学建模B题的参赛者,完整Matlab源代码覆盖四关求解流程,从第一关基础路径规划到第四关随机天气下的最优策略,涉及距离矩阵处理、单目标优化、动态规划、数学期望与随机分布建模等方法。第二关重点解决双地图与…

2026/10/13 21:08:58 阅读更多 →
CEF4Delphi 控件:Delphi 与 JavaScript 双向通信及避坑指南

CEF4Delphi 控件:Delphi 与 JavaScript 双向通信及避坑指南

简介:CEF4Delphi控件是一套面向Delphi开发者的Chromium谷歌内核浏览器集成方案,适合需要在桌面程序中嵌入现代网页渲染能力的开发者,覆盖从Delphi 7到Delphi 10.2的多个版本,作者已亲自测试调试安装正常。资源包共462个文件&#…

2026/10/13 21:08:58 阅读更多 →
数据库大作业图书销售系统:核心是约束设计而不是页面数量

数据库大作业图书销售系统:核心是约束设计而不是页面数量

简介:面向数据库课程大作业的图书销售管理系统数据库设计文档,完整覆盖从问题描述、需求分析、概念模型设计、逻辑模型设计到建立数据库、录入数据及数据库操作的全过程,并配有全局与局部ER图、表结构、外键关系说明,以及实施中遇…

2026/10/13 21:08:58 阅读更多 →
Java 8 Stream 实战指南:从传统循环到声明式流水线

Java 8 Stream 实战指南:从传统循环到声明式流水线

如果你写过几年 Java 业务代码,大概率见过这类场景:一个方法里塞了三四个 for 循环,循环里面套 if,if 里面再往 List 或 Map 里 put 数据,看完要花好几分钟才理清楚这段逻辑到底在干嘛。这种代码不能说错,但…

2026/10/13 21:07:57 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →