1.函数控制流图
由节点和边组成的有向图
-
节点表示一条或多条语句
-
边表示节点之间的控制走向,即语句的执行
带交叉的矩形框表示:程序的入口或出口节点,即程序开始或结束的地方。
无交叉的矩形框表示:执行的语句
菱形框表示:判定节点
三角形表示:与 判定节点 对应的结束节点
(程序中 菱形 和 三角形 总是成对出现的)
作用:
- 直观反映函数的内部逻辑结构
- 展示程序中明显的缺陷
- 揭示程序是否隐含缺陷
2.孤立节点
孤立节点意味着孤立的语句,也就是永远执行不到的路径,必然代表着一个明显的编码缺陷。
2.出口节点
理想的程序是单入口单出口的
多出口会导致空指针、内存未释放,增大环复杂度。
3.环复杂度
环复杂度不应大于10,否则,我们认为程序结构过于复杂。导致环复杂度过高的主要原因通常包括:
- 出口节点数量太多
- 判定节点数目太多
- 未采用结构化的程序设计等。
其中,有
10个独立出口节点,形成的独立区域:
9个判定结构,形成的独立区域:
1个循环结构,形成的独立区域:
4.非结构化设计
造成的后果是导致程序的非正常执行结构,程序可读性差,同时增加测试的难度和工作量,不仅容易导致缺陷,而且在测试中不易发现,造成测试漏洞。
结构化设计,如图所示:
非结构化设计由于存在强制跳入或跳出的情况,导致并非所有分支都执行到结束节点,而是会出现执行到其他节点退出的情况。
非结构化设计,如图所示:(虚线)
5.如何改进程序结构
- 孤立节点:编码时注意避免孤立节点;
- 多出口:尽量避免在同一个函数中多次使用return语句;尽量将有效性校验前置,放到函数外部处理,保证从函数接口传递进来的参数是有效的,避免极短执行路径的函数退出节点。
- 环复杂度:将完成单一功能的语句块改为函数调用的方式;
- 非结构化设计:尽量不使用强制跳转或强制结束语句,如:goto、break等语句。