程序框图绘制指南:符号规范、循环画法与环形复杂度

发布时间:2026/10/31 19:24:42

程序框图绘制指南:符号规范、循环画法与环形复杂度 上周帮一位同学看他写的选课辅助脚本两百多行挤在一个函数里四个条件判断套着两个循环我盯了十几分钟才在脑子里把执行路径捋顺。他自己也说不清某个分支到底在什么情况下会走到因为写的时候是边想边改的。这种事见得太多了问题根本不在代码写得好不好而在动手写之前有没有把逻辑落在纸上。程序框图也就是大家常说的流程图就是干这件事的——把一段程序的执行顺序、判断条件、循环出口用方框、菱形和箭头画出来让脑子里的想法变成别人也能看懂的东西。它适合所有写代码的人新手用它理清思路避免写出绕不出来的嵌套老手用它做设计评审和交接文档哪怕不写代码的产品、测试同学看懂流程图也能快速判断一段逻辑有没有漏洞。下面我拿一个完整的例子把从需求到成图的整个过程拆一遍顺带把符号规范、循环画法和踩过的坑都讲透。1. 动手之前先搞清楚这张图是给谁看的很多人一上手就打开绘图工具拖方框拖到一半发现结构不对又全部推倒重来。我在实际项目里养成一个习惯落笔前先问自己一句这张图最终会出现在谁的面前。这个问题的答案直接决定你用多粗的笔、写多细的节点、要不要保留变量名。1.1 三种用途对应三种截然不同的画法给自己理思路用的草图我从来不管美观。随手抓张纸方框画得歪七扭八箭头甚至会画到纸的边角再折回来。这种图的作用是逼自己把“如果……否则……”完整地想一遍画完就可以扔。判断标准只有一个盖上代码你能不能照着这张图把逻辑重新讲一遍。讲得通就说明想清楚了讲不通说明某个分支你自己也没搞明白。给同事做设计评审或者代码交接用的图规范就必须守住。节点里的文字要能独立读懂不能出现i、tmp、flag这种只有作者自己明白的命名判断框的两个出口必须明确标注“是/否”或者“真/假”每一个循环都要让人一眼看出入口条件和退出条件。这类图我通常会保留真实变量名因为它最终要跟代码对照着看用score比用“分数”更省事。给业务方、测试同学或者非技术背景的合作者看的图要做一次“翻译”。把if (retryCount maxRetry)这种表达换成“重试次数已经用完了吗”把技术性的中间变量全部藏起来只留业务语义。这类图层级不能深超过三层嵌套就拆成两张图否则对方看到第三层就已经放弃阅读了。用途精度要求命名方式是否需要存档常见问题自己理思路低能看懂就行随意外号否画完就忘回头找不到设计评审 / 交接高需与代码一致真实变量名是命名随意导致无人能懂业务 / 测试沟通中逻辑完整业务语言是层级过深读者放弃1.2 为什么我坚持先画图再写代码有个很直观的对比需求变更的时候改一张流程图平均五分钟改一段已经写好的嵌套代码平均两小时还得重新跑一遍测试。图是逻辑的草稿纸草稿纸上改一笔几乎没有成本代码里改一笔要考虑变量作用域、边界值、已有的测试用例会不会挂掉。更关键的是画图这个过程本身会暴露你“没想到的地方”。我印象最深的一次是做一个批量文件的处理脚本思路很清楚读目录、逐个处理、写结果。伪代码三行就写完了。可当我真的去画框图画到“逐个处理”这个框的时候卡住了——如果中间某一个文件处理失败是跳过继续还是整体中断如果全部失败要不要回滚已经写出去的结果这些问题在写伪代码的时候被“逐行处理”四个字完美地掩盖了只有当你必须把它拆成一个个方框和判断菱形时它们才会跳出来逼你回答。所以我的建议很实在任何超过三十行、带两个以上分支的函数动键盘之前先在纸上或白板上把框图撸一遍。这个投入产出比高得离谱。2. 符号规范六个框加两条线真的够用了初学画框图的人容易走两个极端。一种是觉得符号越多越专业把各种特殊图形全用上结果图上一半的符号连自己都要查手册另一种是完全不管规范判断和赋值全用矩形看图的人得靠猜。规范这东西的意义不在于好看而在于消除歧义——同一个图形在全世界的解读应该是一致的。2.1 六种基本图形与它们的语义边界真正高频使用的图形就那么几个我把它们和最容易混淆的地方整理在一起。图形名称表示什么最常见的误用圆角矩形 / 椭圆起止框流程的开始与结束一张图里出现多个入口矩形处理框赋值、计算、函数调用把判断条件塞进矩形里菱形判断框条件分支只画一个出口或出口不标注平行四边形输入输出框读数据、打印、返回与处理框混用不区分内外双边矩形子程序框调用另一个已定义的流程直接展开导致主图爆炸小圆圈连接符跨页或跨区域的断点续接只画一半找不到对应点这里有个特别值得说的细节很多人分不清“处理框”和“输入输出框”。判断标准其实很干脆——这个动作有没有和外部的数据源发生交换。读文件、收用户输入、打印结果、向接口发请求这些都属于输入输出用平行四边形纯粹在内存里算比如sum sum i、字符串拼接、格式化那才是处理框。严格区分的好处是当你要把这段逻辑改成从数据库读而不是从文件读时一眼就能在图里定位到要改的那几个框。2.2 连线和出口标注的三条硬规矩第一条判断框必须有两个或两个以上的出口而且每一个出口都要标注条件。我见过太多只画一个出口的图读者根本不知道“不满足”的时候往哪走。标注用“是/否”最省事条件复杂的时候直接写具体的判断结果比如“余额充足 / 余额不足”比写“是/否”更不容易看错。第二条主干方向自上而下、自左向右箭头在主干上可以省略非主干的回连和横连必须画箭头。这条规矩的目的是让读者的眼睛有固定的扫描路径。一旦你开始在下半部分画向上指的箭头就说明这里是一个循环回边必须画清楚不能省。第三条一条连线不能同时承载两种含义。有些图为了省地方让一条箭头从判断框出来之后又分叉这在规范里是不允许的——分叉必须经过一个新的判断框否则逻辑上就说不清是哪条路径被选中了。2.3 图太大怎么办分层与连接符一张图超过十五个框可读性就开始崩塌。我处理的办法是“主图 子图”两层结构。主图里只保留主干流程和高层的判断遇到需要展开的复杂段落画一个双边矩形写上子流程的名字另起一张纸画它的内部。这样主图永远能在一屏内看完需要抠细节的时候再翻到子图。跨页或者跨区域的时候用连接符规则是成对出现、编号对应。画一个小圆圈写A另一处再画一个圆圈写A读者就知道流程从这跳到那。这里有个小坑连接符只解决“位置不够”的问题不解决“逻辑混乱”的问题。如果一张图里出现七八个连接符来回跳那说明结构本身该拆了靠连接符硬凑只会让图更难读。3. 完整例子成绩等级判定从需求到成图理论说再多不如完整走一遍。我选一个足够简单但分支够多的例子——根据分数输出等级同时处理非法输入。这个例子麻雀虽小判断、分支、合并、异常处理全都有。3.1 先把边界钉死再谈怎么画需求描述通常是模糊的“输入分数输出对应等级”。这句话里有三个必须提前确认的点分数的合法范围是什么边界值归哪一档非法输入怎么处理。我的习惯是先列一张边界表把所有可能的取值区间穷举出来。这一步花不了五分钟但能省掉后面反复改图的时间。输入范围输出说明小于 0 或大于 100数据非法越界直接拒绝90 到 100A含 9080 到 89B含 8060 到 79C含 600 到 59D含 0注意“含”与“不含”必须写清楚。如果需求里没说我就按最常见的左闭右开或者整数分档处理并且在图的注释里写明避免以后有人拿 89.5 来问你为什么算 B。3.2 伪代码是个不可或缺的中间态从需求直接跳到画图中间容易断片。我的做法是先写一段极简伪代码把顺序和判断关系定下来再把它“翻译”成图形。伪代码不需要严谨能表达清楚分支走向就行。score 读取输入() if score 0 或 score 100: 输出(数据非法) elif score 90: 输出(A) elif score 80: 输出(B) elif score 60: 输出(C) else: 输出(D)这段伪代码有个容易被忽略的细节判断是从高到低依次进行的后面的条件实际上隐含了“前面的条件都不满足”。比如走到score 80这一步时已经确定分数不超过 89所以不需要再写score 80 且 score 90。这个隐含关系在代码里靠elif保证但在框图里必须体现出来——每个菱形的“否”出口连向下一个菱形“是”出口直接连到输出框。画图的时候如果不注意这点很容易把条件写成并列的四个菱形读者就得自己去做交集运算这就是典型的“图画了但没画明白”。3.3 落笔主干、分支、异常的先后顺序我画图的固定顺序是先画主干再补分支最后补异常。主干就是最顺的那条路——输入、判断、输出、结束。先把这条线拉直图就有了骨架。下面是我用纯文本画的示意图实际动手时用纸笔或者绘图工具都行结构是一样的┌──────────┐ │ 开始 │ └────┬─────┘ ↓ ┌───────────────┐ │ 输入 score │ └───────┬───────┘ ↓ ╱─────────╲ ╱ score0 ╲ ╱ 或 100 ? ╲──── 是 ──→ ┌────────────┐ ╲ ╱ │ 输出非法 │ ╲───────────╱ └──────┬─────┘ │ 否 │ ↓ │ ╱─────────╲ │ ╱ score90 ╲─── 是 ──→ ┌──────┐ │ ╲ ╱ │ 输出A│ │ ╲─────────╱ └──┬───┘ │ │ 否 │ │ ↓ │ │ ╱─────────╲ │ │ ╱ score80 ╲─── 是 ──→ ┌──────┐ │ ╲ ╱ │ 输出B│ │ ╲─────────╱ └──┬───┘ │ │ 否 │ │ ↓ │ │ ╱─────────╲ │ │ ╱ score60 ╲─── 是 ──→ ┌──────┐ │ ╲ ╱ │ 输出C│ │ ╲─────────╱ └──┬───┘ │ │ 否 │ │ ↓ │ │ ┌─────────┐ │ │ │ 输出 D │ │ │ └────┬────┘ │ │ │ │ │ └────────┬──────────┴─────┘ ↓ ┌──────────┐ │ 结束 │ └──────────┘画到这里有两个地方要注意。第一所有输出框最终必须汇聚到一个结束框不能出现“输出 A 之后流程就断了”的情况那意味着这段逻辑没有归宿读者会怀疑是不是漏画了。第二异常分支要先于正常分支判断这一点在图上体现为越界判断放在最上面。顺序反了的话负数分数会一路掉到“输出 D”这就成了逻辑错误而不仅仅是画法问题。3.4 用环形复杂度给图做一次“体检”图画完了怎么判断它复杂不复杂、测试要覆盖多少条路径这里有个很实用的量化指标——环形复杂度。它的算法有两种结果一样一是数边的数量减去节点数量再加二二是判定节点的数量加一。拿上面这张图来数。节点一共 12 个开始、输入、四个判断、五个输出非法、A、B、C、D、结束。边一共 15 条。代入公式得到 15 − 12 2 5。用判定节点数验证四个判断加一同样是 5。两个结果吻合说明图画得是自洽的。这个 5 意味着什么意味着这段逻辑至少有 5 条互相独立的执行路径测试的时候至少要设计 5 个用例才能把它们全覆盖到一个越界值、一个 95、一个 85、一个 70、一个 30。如果你画的图算出来是 12那就要掂量一下是不是拆得不够细是不是该把某一段抽成子流程了。我个人经验是单个函数的框图环形复杂度超过 10就该考虑重构因为对应的代码大概率已经难以维护。4. 循环最容易画错三类翻车现场判断分支画错了顶多逻辑不对循环画错了整张图的可读性会直接归零。我自己和身边同事踩过的坑基本都能归到下面三类。4.1 判断在入口还是在出口差别是“可能一次都不执行”有一种循环是先判断再执行条件不满足就一次都不进另一种是先执行再判断至少会跑一次。这两者在图上长得完全不一样但很多人在画的时候没意识到要区分。前者的画法是判断菱形放在循环体的上方“是”出口向下进入循环体循环体末尾用一条回边连回菱形上方。后者的画法是循环体先画末尾接判断菱形“继续”的回边指回循环体开头“退出”连向后续流程。如果你去看别人的图发现判断菱形在下面那说明这段逻辑至少会执行一次——如果你本来想要的是“可能一次都不执行”那图就画错了代码八成也写错了。这个区别在真实场景里很要命。比如“逐条读取待处理任务”如果队列是空的正确的行为应该是一次都不进循环直接结束。这时候判断必须在入口。反过来“先执行一次再决定是否重试”这种场景判断就得放在出口。4.2 循环变量的更新必须画出来不能省这是新手最常犯的错循环体里只画了“做事”的框忘了画“计数器加一”或者“指针后移”的框。图的表面上看是有回边的逻辑上似乎能绕回来但少了这个更新步骤回边就变成了一个永远满足条件的死循环。我见过一张图累加求和的循环里画了“sum 加上当前项”回边直接连回判断框唯独漏了“下标加一”。看图的人第一反应是这段代码会死循环第二反应是作者可能压根没意识到自己漏了。这种图比不画图还糟糕因为它传递的是错误信息。所以我的检查习惯是每画完一个循环先在脑子里空跑两轮确认第二轮进入时的状态和第一轮不一样。如果两轮状态完全一样那这个循环就是死的。4.3 嵌套循环和提前退出别画成意大利面两层循环叠在一起如果每一层都画完整的判断和回边图形会迅速变成一团乱麻。我的处理办法是分两张图外层循环一张内层抽成子流程主图里只留一个双边矩形标上“处理单行数据”。这样读者先理解整体节奏需要细节的时候再翻子图。提前退出是另一个麻烦点。在循环体中间用break跳出在代码里只占一行但在图上意味着一条从深层直接连到循环外部的长箭头这条箭头往往要横穿大半个图非常难看。规范的做法是用标志位在循环条件里加一个“未找到”的判断找到之后把标志位置为真循环自然结束后续流程再根据标志位决定走哪条路。这样图上不会出现跨越层级的箭头逻辑也更容易被测试覆盖。5. 工具怎么选手绘、拖拽、文本生成工具这件事没有标准答案关键在于你处在流程的哪个阶段。我把常用的三类工具按使用场景排了个序你可以对照自己的情况挑。5.1 三类工具的适用场景对比类型上手成本修改成本版本管理适合场景纸笔 / 白板极低高改一处可能要重画无讨论阶段、快速验证思路拖拽式绘图中需熟悉对齐和连线中挪动方框会牵动连线弱靠文件另存对外交付、汇报材料文本描述生成中需要记语法极低改一行字即可强可与代码同库存放长期维护的设计文档拖拽式绘图工具最大的痛点是“挪一个框五条线全歪”。如果你的图需要反复迭代这个成本会累积得很快。文本描述生成的思路正好相反——你用几行文字定义节点和连线工具负责排版改动的时候只改文字布局自动重排。它的短板是初期要花时间熟悉语法而且复杂布局的精细控制不如手动拖拽。5.2 我日常的组合拳实际工作中我是这么搭配的讨论阶段直接在纸上或白板上画怎么快怎么来画完拍照留存确定方案之后用文本描述的方式把结构重新写一遍扔进代码仓库里跟源码放在一起需要给非技术同事看的时候再从同一份文本导出成图片或者手动整理一版更美观的。文本描述的好处在于它能进版本管理。改了什么、谁改的、什么时候改的一清二楚。而拖拽出来的图片文件本质上是二进制两个人同时改就冲突历史版本也没法对比。我现在的习惯是凡是会长期存在的设计文档一律用文本描述维护只在最终交付时导出一份图片。下面是一段文本描述的写法示例各家工具的语法细节不同但思想一致先声明节点再声明连线连线上的标注写成标签。节点定义 start 开始 input 输入数据 check 数据合法吗 err 输出错误提示 handle 执行处理 end 结束 连线定义 start - input input - check check - err [标签: 否] check - handle [标签: 是] err - end handle - end这份描述只有十几行但已经把结构说清楚了而且改动起来毫无压力——加一个分支就是在末尾补两行不用去拖方框。5.3 出图前的五项自检不管用什么工具图出完我都要过一遍清单这五条能拦住八成的低级错误起止框是否唯一。一张图只能有一个入口结束框可以有多条线汇入但入口多了读者就不知道该从哪看起。每个判断框的两个出口是否都标了条件。空着的出口等于没画。是否存在走不到结束的路径。逐条路径扫一遍每条都得有归宿。是否有没有任何连线的孤立节点。通常是画到一半改了结构留下的残余。图里的变量名和代码里的变量名是否一致。不一致的话这张图在评审时基本废掉一半。6. 常见问题速查与排查思路最后把我这些年被问得最多、以及自己踩过的坑整理成一份速查表。遇到问题的时候按症状对号入座通常能快速定位。6.1 症状对照表症状大概率原因处理办法图看着很满但说不清逻辑判断条件写成了并列没有体现先后顺序把并列的判断改成一串级联的菱形别人问“这种情况走哪”答不上来某个分支的出口没有标注补全每个出口的条件文字图越画越大一屏放不下没有做子流程拆分把超过八个框的段落抽成子图循环看起来永远出不来漏画了循环变量更新或退出条件在循环体末尾补上更新框回边箭头横穿整张图用了跨层跳出的写法改成标志位控制让循环自然结束代码和图对不上图是早期版本代码改过没同步把图放进仓库和代码一起改同一张图里存在两种画法风格多人协作拼凑统一对齐方向和标注习惯后再合图6.2 几个不太写在手册里的小技巧第一画图之前先数分支。把所有的判断条件列成一张清单数一数有几个心里就有底了。分支超过六个的流程我基本会先考虑能不能用查表代替一长串判断——把“如果 A 输出 1如果 B 输出 2”这种结构改成一张映射表加一次查询图画出来会清爽一个量级。第二判断框里的条件尽量写成肯定句。写“是否合法”比写“是否不合法”好读因为读者不需要在心里做一次取反。这个细节看起来无关紧要但在一张有十几个判断的图里累积起来的认知负担相当可观。第三凡是涉及数值区间一律在图上标注端点归属。写“60 到 79”是不够的要写“60 ≤ x 80”或者至少在注释里说明。我吃过这个亏图和代码对边界理解不一致测试提了个边界值的 bug 才发现是图画得含糊代码照着含糊的图写自然也含糊。第四给图配上版本说明。哪怕只是一行“v2新增越界校验”也能让半年后的自己少花十分钟回忆当初为什么这么改。第五别在图上写代码。节点里写score 90 score 100这种表达式图就退化成代码的另一种排版形式了失去了“用图形降低理解门槛”的意义。节点里写人能读懂的判断复杂表达式放在注释或者旁边的说明里。我个人的体会是画程序框图这件事的价值不在图本身而在画的那个过程。图是给别人看的思考是给自己留的。很多人觉得画图费时间实际上是省下了后面排查和交接的时间只是这笔账要过一阵子才能算出来。等到哪天你需要接手一段三个月前自己写的、只有图没有注释的逻辑就能明白当初那五分钟花得有多值。
延伸阅读

更多相关文章

2026/10/31 19:19:41

国产CAD软件如何实现高效低成本设计

1. 国产CAD软件的市场现状与用户痛点在工程设计、建筑规划、机械制造等领域,CAD软件长期被国外品牌垄断。这种局面导致企业面临三大核心痛点:首先是高昂的授权费用,一套正版国外CAD软件动辄数万元,大型企业需要采购多套不同功能的…

2026/10/31 19:19:41

语音识别技术如何克服口音障碍:原理与实践

1. 项目背景与问题定义卡内基梅隆大学的研究团队最近破解了一个困扰全球语音技术领域多年的难题——为什么主流手机语音助手(如Siri、Alexa、Google Assistant等)在处理非母语口音的英语时表现糟糕。这个发现不仅解释了技术瓶颈的本质,更为改…

2026/10/31 19:19:41

2025届学术研究必备的六大AI工具推荐

1. 项目概述 "2025届必备的六大AI学术方案推荐"这个标题直指一个明确的需求场景:为即将进入学术研究领域的学生群体提供人工智能技术工具的选择指南。在当下AI技术快速迭代的背景下,学术研究者面临着工具选择的困境——既要考虑技术的前沿性&a…

2026/10/31 20:44:49

Redis实战:缓存三兄弟与分布式锁解决方案

1. Redis实战问题整理:黑马点评项目深度解析作为一款高性能的内存数据库,Redis在现代互联网项目中扮演着越来越重要的角色。我在参与黑马点评项目开发过程中,遇到了各种Redis相关的典型问题,从基础配置到高级应用场景都有涉及。这…

2026/10/31 20:44:49

分时电价与需求响应:优化用电负荷的技术解析

1. 分时电价与需求响应概述分时电价(Time-of-Use Pricing)是电力市场中的一种定价机制,它将一天划分为不同时段(如峰时、平时、谷时),并针对不同时段制定差异化的电价。这种定价方式的核心目的是通过价格信…

2026/10/31 20:44:49

Tailwind CSS实用指南:从入门到微信小程序适配

1. 为什么选择Tailwind CSS?作为一名长期奋战在前端开发一线的工程师,我经历过从手写CSS到Bootstrap再到各种CSS-in-JS方案的完整演进历程。当第一次接触Tailwind CSS时,那种"相见恨晚"的感觉至今记忆犹新。与传统CSS框架不同&…

2026/10/31 20:44:49

电力市场双层博弈与交易商风险管理策略

1. 电力市场与双层博弈的碰撞:交易商的风险管理新战场电力市场交易从来就不是简单的买卖游戏。当传统的电力交易遇上现代博弈论中的双层决策模型,交易商们突然发现自己站在了一个全新的风险与机遇并存的十字路口。双层博弈(Bilevel Game&…

2026/10/31 20:44:49

JDK 8u231免安装版部署指南:绿色解压、环境配置与兼容性验证

简介:本资源为JDK 1.8.0_231 x64 Windows免安装版,专为Java初学者、企业开发人员及多环境部署需求者设计,解决标准安装繁琐、跨机器配置重复、磁盘占用高等痛点,支持快速解压即用与灵活环境切换。压缩包共1469个文件,总…

2026/10/31 20:39:49

来料加工企业数字化转型:管理软件选型与实施策略

1. 来料加工企业数字化转型背景与挑战来料加工行业作为制造业的重要组成部分,长期以来面临着生产效率低、管理粗放、信息孤岛等问题。随着全球供应链重构和产业升级压力加大,传统依靠人工记录、Excel表格管理的模式已难以满足现代生产需求。我曾服务过一…

2026/10/30 20:55:10

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/30 20:55:10

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/30 20:55:09

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/31 0:02:41

猫狗目标检测数据集:VOC/COCO/YOLO三格式一体化实战包

简介:本资源是一套面向计算机视觉初学者与YOLO目标检测实践者的猫狗图像数据集及配套开发工具包,专为快速上手目标检测模型训练而设计。资源包含1000张真实场景高清猫狗图片,标注质量高,同时提供VOC(XML)、…

2026/10/31 0:02:41

HDU2017多校标程复现:算法竞赛工程化真题沙盒

简介:本资源为2017年HDU多校联合训练第一场官方配套资料,面向ACM程序设计竞赛备赛学生、算法爱好者及高校编程集训队成员,旨在提供权威解题参考与完整测试验证环境。压缩包共40个文件,含15份C标程(覆盖全部赛题&#x…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑