添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
例如在C语言程序中,语句“while(1)printf("*");”就是一个死循环,运行它将无休止地打印*号。
不存在一种算法,对任何一个程序及相应的 输入数据 ,都可以判断是否会出现死循环。因此,任何 编译系统 都不做死循环检查。
设计程序 时,若遇到死循环,我们可以通过按下Ctrl+Pause/Break的方法,结束死循环。
然而,在编程中死循环并不是一个需要避免的问题,相反,在实际应用中,经常需要用到死循环。例如,我们使用的 Windows操作系统 下的窗口程序中的窗口都是通过一个叫 消息循环 的死循环实现的。在单片机、 嵌入式编程 中也经常要用到死循环。在各类编程语言中,死循环都有多种实现的方法,以C语言为例,可分别使用while.for,goto实现。
死循环的C语言实现:
1、while(1);
2、for(;;);
3、goto
Loop:
...
goto Loop;
以下是一些死循环的例子。
C++的例子
#include< iostream >
intmain()
{
for(inti=0;;++i)
{
cout<<char(i);
}
return0;
}
C语言 的死循环:
#include< stdio.h >
intmain()
{
inta=0;
while(a>=0)
{
printf("%d\n",a);
if(a==5){
printf("aequals5!\n");
}
a++;
}
return0;
}
上述程序会一直显示"Infinite Loop" 字符串
BASIC 语言的死循环:
10 PRINT"Infinite Loop"
20 GOTO10'跳到 行号 =10的位置
X86汇编语言的例子:
loop :
; Code to loop here
jmploop
Python 的例子:
while True:
print ("Infinite Loop")

死循环 逻辑错误

以下是一个 Visual Basic 死循环的例子:
dim x asintegerdountil x > 5'根本不会有x>5的情形x = 1 x = x + 1 loop
每一次运行循环时x会先设置为1,然后变为2,因为数值未大于5,所以永远不会退出。若将x = 1由循环内部移到循环之前即可以改善此一情形。
有些程序员可能因为不熟悉特定 编程语言 的语法而造成死循环,例如以下是一段 C语言 的程序:
#include <stdio.h>
main()
    int a=0;
    while(a<10)
        printf("%d\n",a);
        if(a=5){ printf("a equals 5!\n"); 
//a设定为5,进入无穷回圈
}
        a++;
    return 0;
}
其预期输出是数字0至9,其中5和6中间会显示"a equals 5!",但程序员在编写程序时将设置用的= 运算符 及判断相同的==运算符弄混了,因此程序会在每次运行循环时都会将a设置为5,因此变量a永远无法到达10,此循环就变成了死循环。
printf("x = %f\n",x);     x=x+0.1; }
在有些操作系统中,上述程序会运行10次循环然后退出,但有些系统中,上述程序却可能会一直运行,无法退出,问题主要在循环的退出条件(x != 1.1)要在二个 浮点数 相等时才退出,结果会依系统处理浮点数的方式而定,只要系统运行10次循环后的结果和1.1差一点点,上述程序就会变成死循环。
若将退出条件改为(x < 1.1)就没有这个问题,程序可能会多运行一次循环,但不会变成死循环。另一种解决方式则是用一个整数变量作为循环变量,再依此变量判断是否要退出循环。
在数值分析程序中也可能会出现无预期的死循环,例如程序需一直迭代到误差小于某特定值为止,但若因为运算中的舍去误差,使得误差一直无法小于该特定值,就会产生死循环。

死循环 奥尔德森循环

奥尔德森循环(Alderson loop)是指一个循环有设置退出条件,但因为程序的写法(多半是编程错误),造成永远无法满足退出条件,在针对 用户界面 程序调试时最容易出现这类的问题。
以下C的 伪代码 中有一个奥尔德森循环,程序是要计算用户输入一串数字的和,用户输入0时退出循环,但程序中用了不正确的运算符:
sum =0;while( true ){printf("Input a number to add to the sum or 0 to quit");i=getUserInput();if(i*0){ // 若i乘0为真,则使sum加上i的值 sum+=i;// 但这 不可能发生 ,因为不论i为何值(i * 0)都是0。如果条件中用的是!=而非*,代码就能正常运行}if(sum>100){ break ; // 终止循环。结束条件存在,但从来没有达到过,因为sum永远不会增加 }}
“奥尔德森循环”是来自一个 Microsoft Access 的程序员,他编写的程序产生一个有模式的对话框,用户需要回应,程序才能继续运作,但对话框没有OK键或取消键,因此只要此对话窗出现,Access程序就无法继续运作。
无穷递归是一种由递归造成的死循环。例如以下计算 阶乘 的C语言程序
unsigned int fac(unsigned int a){
    //n!=n*(n-1)!
    return(fac(a-1)*a);
}
一般 递归 的程序会有一特定条件,此条件成立时直接计算结果,而不是通过递归来计算结果,若程序中 未定义 此条件,就会出现无穷递归。
无穷递归会造成 堆栈溢出 ,而无穷递归不会退出,因此也是死循环的一种。不过若 递归程序 是使用 尾部递归 的处理方式,在有些编程语言(如 Scheme )中会优化成循环,因此不会造成堆栈溢出。
上述的程序可以修改成没有无穷递归的程序。
unsigned int fac(unsigned int a){
    if(a==0)
    {    //定义0!=1
        return 1;
        return(fac(a-1)*a);
假死循环是指一个循环看似不会退出,但只是一个运行很长时间,最后仍会退出的循环。
以下是一个C语言for循环的程序:
for(i=1;i!=0;i++)
{/* loop code */}
上述程序每次运行时都将i加1,若i等于0时才会退出循环,此程序看似不会退出,但最后还是会退出。程序中型态为unsigned int的变量,其数值有一定上限,当数值已到上限,再加1时,变量数值就会变为0,因此让程序退出。实际的上限值依系统及编译器而不同,假如unsigned int是一个16个比特的字符组,上述的循环会运行65536次。若使用高精度计算,程序会一直运行到存储器无法存储i为止。