equals运算符及判断相同的==运算符弄混了,因此程序会在每次运行循环时都会将a设置为5,因此变量a永远无法到达10,此循环就变成了死循环。
在有些操作系统中,上述程序会运行10次循环然后退出,但有些系统中,上述程序却可能会一直运行,无法退出,问题主要在循环的退出条件(x != 1.1)要在二个
浮点数相等时才退出,结果会依系统处理浮点数的方式而定,只要系统运行10次循环后的结果和1.1差一点点,上述程序就会变成死循环。
若将退出条件改为(x < 1.1)就没有这个问题,程序可能会多运行一次循环,但不会变成死循环。另一种解决方式则是用一个整数变量作为循环变量,再依此变量判断是否要退出循环。
奥尔德森循环(Alderson loop)是指一个循环有设置退出条件,但因为程序的写法(多半是编程错误),造成永远无法满足退出条件,在针对
用户界面程序调试时最容易出现这类的问题。
以下C的
伪代码中有一个奥尔德森循环,程序是要计算用户输入一串数字的和,用户输入0时退出循环,但程序中用了不正确的运算符:
sum=0;while(true// 若i乘0为真,则使sum加上i的值sum+=i;// 但这
不可能发生,因为不论i为何值(i * 0)都是0。如果条件中用的是!=而非*,代码就能正常运行}if(sum>100){break;// 终止循环。结束条件存在,但从来没有达到过,因为sum永远不会增加}}
“奥尔德森循环”是来自一个
Microsoft Access的程序员,他编写的程序产生一个有模式的对话框,用户需要回应,程序才能继续运作,但对话框没有OK键或取消键,因此只要此对话窗出现,Access程序就无法继续运作。
一般
递归的程序会有一特定条件,此条件成立时直接计算结果,而不是通过递归来计算结果,若程序中
未定义此条件,就会出现无穷递归。
无穷递归会造成
堆栈溢出,而无穷递归不会退出,因此也是死循环的一种。不过若
递归程序是使用
尾部递归的处理方式,在有些编程语言(如
Scheme)中会优化成循环,因此不会造成堆栈溢出。
死循环也可能因为多个模块之间的交互而产生。考虑一台服务器若收到无法理解的需求时,会回应
错误信息,此架构中不会有死循环。但若有二台上述的服务器(A和B),互相交换数据,A收到由B所提交无法理解的需求,会回应错误信息给B,但若B也无法理解A提交的需求(其实是A的错误信息),会再以自己的格式回应错误信息给,A收到后无法理解,会再回应错误信息给B……。像邮件循环就是这类的例子。
上述程序每次运行时都将i加1,若i等于0时才会退出循环,此程序看似不会退出,但最后还是会退出。程序中型态为unsigned int的变量,其数值有一定上限,当数值已到上限,再加1时,变量数值就会变为0,因此让程序退出。实际的上限值依系统及
编译器而不同,假如unsigned int是一个16个比特的字符组,上述的循环会运行65536次。若使用
高精度计算,程序会一直运行到
存储器无法存储i为止。