为什么不结束?[关闭]


95

您的任务:编写一个显然应该终止的程序,但永远不会(在计算机崩溃的情况下)终止。使它看起来像应该执行的简单任务:加号,打印内容,...但是它只是陷入无限循环中。

尝试使您的程序非常清晰和简单,而实际上它会陷入无法预料的循环中。选民:评判他们“多么卑鄙”的答案!

这是一场人气竞赛:有创意!


6
有人可以解释一下我可以做些什么来使这个问题不那么广泛吗?我刚来这地方。谢谢!
Number9

6
这将是造成循环的错别字和初学者的错误的一大清单。
比尔·伍德格

有趣的问题,但是我还没有看到任何真正有创意的答案。我向任何不使用循环或明显递归的人承诺投票!
接近

14
我不知道这是否很重要,但目前我的Microsoft Office行为与此完全相同。
级圣河

1
我投票结束这个问题是不合时宜的,因为在这里不再需要应付挑战。meta.codegolf.stackexchange.com/a/8326/20469

Answers:


185

Java脚本

var x=prompt('Enter a value under 100');
while (x != 100) {
  x=x+1;
}
console.log('End!');

prompt()返回一个字符串,并且循环将字符“ 1”附加在后面,它将永远不等于100。


13
你让我明白了那个……(实际上)投票率较高的示例都只是在滥用语法……但是那个很好!
bwoebi 2014年

4
Kubuntu上的Chrome变得反应迟钝,挂起了所有东西,我不得不硬重置:)
Sergey Telshevsky 2014年

4
@Vlakarados:Python不会执行Javascript的隐式类型转换。在Python上,使用raw_input或Python 3 的等效代码input引发TypeError
user2357112 2014年

2
没有检查值实际上小于100的事实,因此当您输入“ 100”时它通常会停止:'-(
C.Champagne

1
@Sankalp,+这里的运算符是字符串连接,而不是加法。
Michael M.

87

C

只是一个基本的示例程序,它说明了C中的三种不同的while循环。

int main() {

    int x = 0;

    // Multi-statement while loops are of the form "while (condition) do { ... }" and
    // are used to execute multiple statements per loop; this is the most common form
    while (x < 10) do {
        x++;
    }

    // x is now 10

    // Null-statement while loops are of the form "while (condition) ;" and are used
    // when the expression's side effect (here, decrementing x) is all that is needed
    while (x-- > 0)
        ; // null statement

    // x is now -1

    // Single-statement while loops are of the form "while (condition) statement;"
    // and are used as a shorthand form when only a single statement is needed
    while (x > -10)
        x--;

    // x is now -10

    return 0;
}

在循环花括号前没有while循环。这实际上在(x <10)循环内创建了一个do-while循环,该循环由以下“空语句” while循环终止。由于x在循环内部递增,然后在do-while循环的条件下递减,因此内部循环永远不会终止,外部循环也不会终止。永远不会到达最后的“单语句”循环。

如果您仍然感到困惑,请看这里(外部托管,因为codegolf.SE不喜欢扰流板上的代码块)。


8
哈哈,在查看解决方案扰流器之前,我已经弄清楚了这一点。:P
Joe Z.

54
为什么您错过了使用“转到”运算符的绝佳机会?(x --> 0)
corsiKa 2014年

2
哇哦 这真是邪恶。我花了四遍通读找到它。
Patrick M

1
@JoeZ。太简单了。最受欢迎的解决方案更好。我没有找到那个。
2014年

3
@Hat Guy,Bash具有for; do和while; do语法,因此即使他们熟悉非C / C ++语言,我也可以看到人们对此不满意。tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
nemec

85

的JavaScript

var a = true;
(function() {
  while(!a){}
  alert("infinite");
  var a = true;
})();

变量提升:JavaScript实际上将获取我的第二个定义var a = true;,在函数顶部将其声明为var a;,然后将我的赋值修改a = true;a在进入while循环时未定义的含义。


3
您能否对为什么这种情况永远不会终止进行更好的解释?请深入了解“可变吊装” :)
2014年

1
@ Number9我希望对您有所帮助,谷歌有比这更好的例子了;)
Newbrict 2014年

25
天哪,这甚至比分号插入更糟。+1!
tommmeding

2
我在该程序中看到的唯一麻烦是,它看起来好像并没有执行简单的任务……看起来它实际上应该什么也不做。也许alert在循环之后添加一个。
PeterT 2014年

2
您应该更改a = 1a = true。这样,代码仍将具有无限循环,但更清楚的是,原因不是JavaScript从int到boolean的转换中有一些古怪之处。
罗里·奥肯

49

C#

class Program
{
    // Expected output:
    // 20l
    // 402
    // 804
    // l608
    // 32l6
    // game over man

    static void Main()
    {
        var x = 20l;
        while (x != 6432)
        {
            Console.WriteLine(x);
            x *= 2;
        }
        Console.WriteLine("game over man");
    }
}

函数第一行中的数字文字不是'201',而是带有小写'L'(数据类型)后缀的'20' 。该数字将很快溢出,而不会达到6432,但是程序将继续运行,除非在构建选项中打开了溢出检查功能。
明智地,Visual Studio 2013(可能还有其他版本)会对此代码发出警告,建议您使用“ L”而不是“ l”。


12
哦,l应该看起来像1!我真笨。:\
JoeZ。2014年

6
改进建议:用ls替换预期输出部分中的1(当您将实数与1比较时,更容易发现怪异的字符)
Allen Gould 2014年

3
是的,它似乎确实是特定于环境的。@Michael的字体看起来与我的家用计算机(imgur.com/PKIuJpr-Chrome,Windows 8)上的字体非常不同,即使我的家用计算机上的技巧非常相似,该技巧似乎在我的工作计算机上也能更好地工作眼镜。我的手机的浏览器似乎没有以固定间距的字体显示代码,并且该技巧完全不起作用。
BenM

1
FTR,这是我的工作计算机(imgur.com/Opfs3BH-Firefox,Windows 7)上的外观。我认为甚至可以愚弄精明的人。
BenM 2014年

15
人们为什么会继续滥用相同的字符?
2014年

39

C

精度如何?

int main(void)
{
    double x = 0;
    while(x != 10) x += 0.1;
    return 0;
}

假设您必须在计算机内存中存储一​​定范围的整数<0; 3>。此范围内只有4个整数(0,1,2,3)。使用2位将其存储在内存中就足够了。现在,假设您必须存储一定范围的浮点数<0; 3>。问题是在此范围内有无限数量的浮点数。如何存储无数个数字?是不可能的。我们只能存储有限数量的数字。这就是为什么像0.1这样的数字实际上不同的原因。如果为0.1,则为0.100000000000000006。强烈建议在使用浮点数的情况下不要使用==或!=。


1
这是如何运作的?
Mhmd 2014年

5
舍入错误。0.1实际上是0.100000000000000006,因为二进制的0.1就像十进制的1/3-它的二进制扩展是无限的和周期性的。
Orion

3
并不是舍入错误。浮点值是数字的近似表示。在近似值之间进行精确比较是行不通的。
AKHolland 2014年

4
这就是为什么(几乎)永远不要比较浮点数/双精度数是否相等的原因。
伊曼纽尔·兰德霍尔姆

1
我正等着看这个。真好
戴维·康拉德

33

HTML / JavaScript

假设您的页面中有一个输入框:

<input onfocus="if (this.value === '') alert('Input is empty!');">

现在,您要在其中输入内容...在Chrome中尝试:http : //jsfiddle.net/jZp4X/

使用alertfunction 调用的标准浏览器对话框是模态的,因此在显示时,它将焦点从文本框中移出,但是在取消显示时,文本框将接收焦点。


5
在firefox中,输入没有自动聚焦于警报关闭,从第二次输入开始,我不再显示更多警报,然后我可以正常地在文本框中书写内容
Einacio 2014年

6
好东西。+1表示没有循环或递归。
接近

5
Firefox或Chrome中没有循环。FF在单击对话框时显示一次警报,您将其关闭,然后结束。可以再次单击以重复。Chrome的功能与此相同,但框会集中在焦点上,您甚至可以键入它。抱歉,也许在旧版本中这是一个问题,但现在不再存在。
RomanSt

6
IE11对我来说与Chrome完全一样。我认为您无意中找到了一个示例,该示例在Mac上的每个现代浏览器上都可以以一种方式工作,而在Windows上的每个现代浏览器上都可以以不同的方式工作!
RomanSt

1
在MSIE11上正常工作(无循环)
kinokijuf 2014年

32

C ++

#include <iostream>
#include <cstddef>

int main() {
    size_t sum = 0;
    for (size_t i = 10; i >= 0; --i) {
         sum += i;
    }
    std::cout << sum << std::endl;
    return 0;
}

该条件i >=0始终为true,因为size_t是无符号的。


2
不错,但是编译器通常会为此发出警告;)
Synxis 2014年

2
@Synxis是的,编译器可以。但仅当您打开编译器警告时。g++没有他们,不会就此警告您。
FDinoff 2014年

5
-Wall --pedantic无论如何,您都应该始终使用。
Martin Ueding 2014年

3
@queueoverflow该警告不只显示那些标志。您需要-Wsign-compare使用可以打开它-Wextra
FDinoff 2014年

7
-pedantic破折号。#pedantic
David Conrad

29

重击

(有没有循环或递归的请求)

#!/bin/bash

# Demo arrays

foo=("Can I have an array?")

echo $foo

echo ${foo[0]}

foo[2] = `yes`

echo $foo

echo ${foo[2]}

而不是将字符串'yes'分配给foo [2],而是调用系统命令yes,该命令以永无止境的“ yes \ n”填充foo [2]。


最终用尽bash内存并将其崩溃
Digital Trauma 2014年

4
是的,的确如此。但问题是允许崩溃的:)
GreenAsJade 2014年

是的,只是观察:)。已投票。
Digital Trauma 2014年

实际上,我认为这个
小组件中的程序实际上会使

更正:yes这只是一个coreutils程序。不是系统调用。
mniip

28

C

字母“ x”在文件中丢失。编写了一个程序来查找它:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  FILE* fp = fopen("desert_file", "r");
  char letter;
  char missing_letter = argv[1][0];

  int found = 0;
  printf("Searching file for missing letter %c...\n", missing_letter);
  while( (letter = fgetc(fp)) != EOF ) {
    if (letter == missing_letter) found = 1;
  }
  printf("Whole file searched.\n");
  fclose(fp);
  if (found) {
    printf("Hurray, letter lost in the file is finally found!\n");
  } else {
    printf("Haven't found missing letter...\n");
  }
}

它被编译并运行,最后大喊:

Hurray, letter lost in the file is finally found!

多年来,以这种方式挽救了信件,直到新家伙出现并优化了代码。他熟悉数据类型,并且知道对非负值使用无符号比有符号更好,因为它具有更广泛的范围并且可以防止溢出。因此他将int更改为unsigned int。他也非常了解ascii,以知道它们始终具有非负值。因此,他也将char更改为unsigned char。他编译了代码,并为自己的出色工作而自豪。该程序如下所示:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  FILE* fp = fopen("desert_file", "r");
  unsigned char letter;
  unsigned char missing_letter = argv[1][0];

  unsigned int found = 0;
  printf("Searching file for missing letter %c...\n", missing_letter);
  while( (letter = fgetc(fp)) != EOF ) {
    if (letter == missing_letter) found = 1;
  }
  printf("Whole file searched.\n");
  fclose(fp);
  if (found) {
    printf("Hurray, letter lost in the file is finally found!\n");
  } else {
    printf("Haven't found missing letter...\n");
  }
}

第二天他又遭受了重创。字母“ a”丢失了,即使应该在包含“ abc”的“ desert_file”中,程序也一直在搜索它,仅打印出来:

Searching file for missing letter a...

他们解雇了那个家伙,回滚到以前的版本,以为永远不要在工作代码中优化数据类型。

但是他们在这里应该学到什么呢?

首先,如果您查看ascii表,您会发现没有EOF。这是因为EOF不是字符,而是从fgetc()返回的特殊值,该值可以返回扩展到int的字符或表示文件结尾的-1。
只要我们使用带符号的char,一切都可以正常工作-等于50的char也可以通过fgetc()扩展为等于50的int。然后我们将其转换回char并仍然有50。-1或任何其他来自fgetc()的输出也会发生同样的情况。
但是看看当我们使用无符号字符时会发生什么。我们从fgetc()中的char开始,将其扩展为int,然后想要一个未签名的char。唯一的问题是我们不能在无符号字符中保留-1。程序将其存储为255,不再等于EOF。

警告
如果您查看ANSI C文档副本中的 3.1.2.5类型一节您会发现是否对char签名仅取决于实现。因此,可能他不应该被解雇,因为他发现代码中隐藏着一个非常棘手的错误。更改编译器或移至其他体系结构时可能会出现。我不知道如果在这种情况下出现错误,谁会被解雇;)

PS。程序是根据Paul A. Carter在PC汇编语言中提到的bug构建的。


7
我喜欢解决方案有个故事。
jpmc26 2014年

哈哈!我想那是唯一的。感谢您的通读!
Legat 2014年

1
我爱你。用您的故事喂我:(
YoYoYonnY

这绝对是太棒了!
kirbyfan64sos

21

正则表达式

通过适当的输入,以下正则表达式可以使大多数回溯正则表达式引擎进入回溯地狱:

^\w+(\s*\w+)*$

简单的输入(例如"Programming Puzzles and Code Golf Stack Exchange - Mozilla Firefox""AVerySimpleInputWhichContainsAnInsignificantSentence."(为了清晰起见,都用引号引起来)都足以使大多数回溯正则表达式引擎长时间运行。

由于(\s*\w+)*允许扩展\w+\w+\w+... \w+,这意味着正则表达式引擎将基本上尝试所有可能的方法来拆分一串单词字符。这就是回溯地狱的源头。
它可以很容易地通过改变被固定\s*\s+,那么(\s+\w+)*只能扩展到\s+\w+\s+\w+... \s+\w+


3
我讨厌回溯正则表达式引擎。
戴维·康拉德

2
我首先在Perl上尝试过,但似乎Perl可以在这里注意到一个循环。我没有尝试过AWK,因为没有正则表达式会导致AWK中的这种行为。PHP会自动生成正则表达式,而匹配失败会花费很长时间(这很愚蠢,但这对您来说是PHP-它会自动将错误插入程序中)。但是,它实际上可以在Python中工作。
Konrad Borowski 2014年

1
@xfix:至于为什么Perl设法避免回溯地狱,本文解释了原因。但是,这还不足以应对此处显示的情况(向下滚动至“性能”部分)。PHP(实际上是PCRE库)具有回溯限制,并且正确的程序应始终检查函数的返回值,以决定执行是暂停还是完成。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2014年

1
太滑了
alvonellos 2014年

20

的JavaScript

function thiswillLoop(){
var mynumber = 40;
while(mynumber == 40){
mynumber = 050;
}
return "test";
}
thiswillLoop();

050是Javascript中的一个八进制常量,它的十进制值为40。


73
我发现这很明显。:-)
贾斯汀

6
我不知道javascript是这样做的。但是在阅读代码后,我说:“ 050必须以某种方式表示40,可能以8为底的东西”
Cruncher 2014年

这需要更好地隐藏。
圣保罗Ebermann

很明显..
奥利弗·尼

18

哈斯克尔

head $ reverse $ (repeat '!') ++ "olleH"

好吧,想一想!它将与相同head $ "Hello" ++ (repeat '!'),即应该返回'H'

haskell列表中的是递归结构,第一个元素是最高的。要追加到列表中,必须展开所有这些元素,放置附录,然后将抬起的元素放回原处。那在无限列表上是行不通的。同样,反转无限列表也不会神奇地使您"Hello"退缩。它会永远挂着。


1
太糟糕了,这实际上是行不通的:-/
John Dvorak

1
它如何运作?
danmcardle 2014年

当我在Fedora上测试此@crazedgremlin时,操作系统最终终止了该过程。(<5分钟),因为它耗尽了系统上的所有内存。
FDinoff 2014年

有趣!我没有意识到这件事发生了。我不经常冒险涉足所有内存领域。
danmcardle 2014年

4
那仍然是一个有效的解决方案:它不会退出,它会一直运行,直到系统不再支持它为止……
GreenAsJade 2014年

16

Windows下的Java

public class DoesntStop
{
    public static void main(String[]a) throws InterruptedException, IOException
    {
        ProcessBuilder p = new ProcessBuilder("cmd.exe","/c","dir");
        p.directory(new File("C:\\windows\\winsxs"));
        Process P = p.start();
        P.waitFor();
    }
}

程序依赖于命令行中阻塞的标准输出流来阻塞。Windows下的WinSXS目录包含成千上万个长名称的文件,因此几乎可以保证它会阻塞stdout,并且waitFor无法返回,因此程序处于死锁状态


1
也许我很稠密,但最终不会回来吗?可能要花一点时间。也许我不明白“ clog [ging] stdout”的意思。
asteri 2014年

4
如果流没有被清空,程序块就已经让我有些头疼,这就是为什么我使用它;长目录仅保证缓冲运行满
masterX244

啊,知道了 真好!+1
asteri

15

比较C和苹果

让我印象深刻的是,这里没有使用goto... 的代码(您知道:Goto是邪恶的!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    char *oranges = "2";
    long int apples;

next_harvest:

    apples = random() % 3;

    printf("%ld apples comp. %s oranges ...\n", apples, oranges);

    if( apples != (long int)oranges )
    {
        sleep(1);
        goto next_harvest;
    }

    return 0;
}

睡眠只是为了能够阅读它。如果没有足够的时间等待从未发生的事情,请按^ C键;-)


9
您这个卑鄙的混蛋,goto在这个过程中是无辜的:)
Orion

是vodoo使用的random()吗?
masterX244 2014年

1
啊,“ 2”!= 2;知道了
masterX244 2014年

2
那么“ 2”可能永远不会是2,但是如果您使用更大的数字(至少是4的倍数),则可能会发生;)
Orion

1
@orion:是的,你是对的,可能是。goto仍然是邪恶的,但是不良的类型转换甚至更加邪恶!
max.haredoom

12

C,带有某些优化的编译器

该程序递增一个整数变量,直到溢出。

#include <stdio.h>
#include <stdint.h>
int main()
{
    int32_t x = 0;
    while(x + 1 > x)
        x++;
    printf("Got overflow!\n");
    return 0;
}

有符号整数溢出是未定义的行为。通常在实践中,当优化关闭时,它会自动包装。启用优化后,编译器可以并且确实x + 1 > x会始终如此。


也许用int32_t; 一个64位的int会花很长的时间(如果每次迭代花费一纳秒,则将花费585年)。
Paul Draper 2014年

11

C ++

int main()
{
  int x = 1;
  //why doesn't this code terminate??/
  x = 0;
  while(x) {} //no-op/
  return 0;
}

怪异的评论风格是窍门。提示:三部曲。


这是一个无限循环的太基本的例子。
Ismael Miguel

64
这些Trigraph在这里
太过

75
我几乎觉得三合会应该放在不再有趣的标准漏洞中。
Undergroundmonorail

6
@TheDoctor:?? /是反斜杠字符的三元组,因此反斜杠将x赋值为0的行拼接到注释的末尾,使其成为注释的一部分。
CasaDeRobison

4
@undergroundmonorail 发表
贾斯汀

11

爪哇

我特别喜欢自动装箱优化的副作用:

class BoxingFun {
  public static void main( String[] args) {
    Integer max;
    Integer i;

    max = 100;
    for( i = 1; i != max; i++ ) {
      System.out.println("Not endless");  
    }
    max = 200;
    for( i = 1; i != max; i++ ) {
      System.out.println("Endless");  
    }
  }
}

由于具有自动装箱功能,因此Integer对象int在这里的行为几乎与plain s相同,但有一个例外:循环中的i != maxin for比较对象的引用(标识)Integer,而不是对象的值(相等)。对于高达100的值,由于JVM中的优化,这令人惊讶地“起作用”:Java Integer为“最常见的值” 预分配对象,并在自动装箱时重新使用它们。因此,对于不超过100的值,我们具有身份<==>相等性。


5
鉴于某些Java专家仍然认为C ++运算符重载是邪恶的 ……
Daniel

您不需要初始化= new Integer(0),因为无论如何您随后都要初始化值。(这可能使原因不那么明显。)
PaŭloEbermann 2014年

@PaŭloEbermann:好的,我已经编辑了代码。
丹尼尔(Daniel)

9

红宝石/ C

#include <stdio.h>
#ifdef llama
def int(*args)
end
def main(arg)
  yield
end
void = nil
#endif
#define do {
#define end }
int main(void) {
  int x = 10;
  while(x-=1) do
    printf("%i\n",x);
  end
    return 0;
}

可以在C中正常工作,在STDOUT中从9倒数到1。在Ruby中运行时,它不会终止,因为

0在Ruby中不是一个假值。


立刻做语言...令人印象深刻。
Paul Draper 2014年

7

的JavaScript

// This multiplies the elements in the inner lists and sums the results.
function sum_of_products(var items)
{
        var total = 0;
        for(var i = 0; i < items.length; i++) {
                var subitems = items[i];
                var subtotal = 1;
                for(var i = 0; i < subitems.length; i++) {
                        subtotal *= subitems[i];
                }       
                total += subtotal;
        }
        return total;
}

// Should return 1*2 + 3*4*5 + 6*7*8*9 + 10*11 = 3196
sum_of_products([[1, 2], [3, 4, 5], [6, 7, 8, 9], [10, 11]]);

两个循环都使用相同的循环变量,因此,取决于输入,内部循环可以防止外部循环完成。


这是什么语言?
RononDex 2014年

@ronondex Javascript
凌晨

1
啊,是的,它是Javascript。我记得启用了语法提示功能,但也不得不忘记将其放在标题中:)
Aleksi Torhamo 2014年

1
我发现这很明显。:-)
rafaelcastrocouto 2014年

@rafaelcastrocouto是的,但是确实很容易错过,例如,将循环从一个函数移到另一个函数或仅浏览代码时。另外,请注意,由于变量阴影,此方法在某些语言(包括C)中实际上可以正常工作。:)
Aleksi Torhamo 2014年

7

C

这应该为所有ASCII字符(从0到255)打印一个代码表。A char足够大以遍历它们。

#include <stdio.h>

int main(){
    char i;
    for(i = 0; i < 256; i++){
        printf("%3d 0x%2x: %c\n", i, i, i);
    }
    return 0;
}

所有字符均小于256。由于溢出,255 ++给出0,因此该条件i < 256始终成立。有些编译器对此有所警告,有些则没有。


制作似乎在做些有用的事,也许printf("%3d %2x: %c", i, i, i);在循环中使用类似的东西(对于代码表)。
圣保罗Ebermann

@PaŭloEbermann:好主意。
拉斐尔·西埃拉克(RafałCieślak)2014年

我在教室中使用此技巧,可打印的无符号字符在32到128之间。:)
cpri

7

蟒蛇

a = True
m = 0
while a:
    m = m + 1
    print(m)
    if m == 10:
        exit

应该是exit(),不是exit。据我了解,exit()是退出python解释器的命令。在这种情况下,调用的是函数的表示形式,而不是函数,请参见:exit-discussion。或者,break将是更好的选择。


您能解释一下exit实际是什么吗?它似乎是一类,但是它的作用是什么?你也可以改变print m,以print(m)使这也与Python 3作品
马丁托马

1
这些事情……就像我的elseif因为elif而无法工作时。
2014年

感谢@moose更新的印刷声明和扰流板消息
Willem

6

C ++

经典的C ++程序员陷阱如何?

int main()
{
   bool keepGoing = false;

   do {
       std::cout << "Hello, world!\n";
   } while( keepGoing = true );

   return 0;
}

我不明白吗?关于使用。=而不是==?
Mhmd 2014年

完全是@ user689。keepGoing = true本意是比较的值keepGoing,而是分配keepGoing; 此外,整个语句的keepGoing = true计算结果是true(导致您可以编写类似的内容a=b=c=d=0)导致无限循环。
CompuChip 2014年

3
这是使用尤达条件的更多理由。
瑞安

@RyanEdwardDougherty哈哈,就像我从未听过他们被呼唤一样。对于早晨笑声谢谢。
CompuChip 2014年

@RyanEdwardDougherty:当然== true(或Yoda风格true ==)是多余的,条件应该简单地阅读while (keepGoing)
celtschk 2014年

6

Java脚本

var а = 0;
a = 1;
while(а<10){
    a++;
}

第一和第三行中使用的变量与第二和第三行中使用的变量不同。
一个使用一个(U + 0061),而另一种使用а(U + 0430)


我在这里没有问题。我运行了它,效果很好。我想念什么?
Andrew Shepherd

因为Unicode可能会转换,所以这很可能在任何地方都可以使用。得到+1,因为它是您所能获得的最隐形的东西!
rafaelcastrocouto

只是要完全隐藏它(用U + 0430替换á),如果这是您的代码,请找到问题的好运:var a;var points = 0;function fiftyfifty() {points++;if (Math.random() > 0.5)return true;}; á = fiftyfifty(); while (a === undefined) {á = fiftyfifty();} console.log("Points: " + points);我会放弃,永久删除它,清理我的计算机,也许是病毒扫描程序只是为了确定并完全重写它。编辑:因为var a = 0; a = 1;不是很现实
2015年

6

Java:

public class LoopBugThing{
   public static void main(String[] args)
   {
      int i = 0;
      while(i < 10)
      {
         //do stuff here
         i = i++;
      }
      System.out.println("Done!");
   }
}

“ i = i ++”是一个很常见的初学者错误,很难找到


5

C ++

有点随机吗?

class Randomizer
{
   private:
   int max;

   public:
   Randomizer(int m)
   {
      max = m;
      srand(time(NULL));
   }

   int rand()
   {
      return (rand() % max);
   }
};

int main()
{
  Randomizer r(42);
  for (int i = 0; i < 100; i++)
  {
     i += r.rand();
  }
  return (0);
}

不调用该函数rand,而是递归地调用该Randomizer::rand函数。


5
在返回语句中加括号,parent。
戴维·康拉德

1
不过,这最终导致段错误。
kirbyfan64sos

5

哈斯克尔

一些代码可以定时计算给定值的阿克曼函数。对于非常低的值,通常会终止。在我的机器上,极低的值意味着3和5或更小值的编译代码和-O。在ghci中,低值表示类似3 3。

'符号似乎弄乱了语法高亮显示,不确定为什么。在某些地方,它们是必需的,因此无法将其全部删除。

编辑更改的语言。

{-# LANGUAGE NamedFieldPuns #-}
import Control.Concurrent.STM
import Control.Concurrent
import Data.Time.Clock.POSIX

data D = D { time :: !POSIXTime
           , m :: !Integer
           , n :: !Integer
           , res :: !(Maybe Integer)
           } deriving Show

startvalue = D 0 3 8 Nothing

-- increment time in D. I belive lensen make code like
-- this prettier, but opted out.
inctime t t' (d@D{time}) = d {time = time + t' - t }

-- Counting time
countTime :: TVar D -> POSIXTime -> IO ()
countTime var t = do
    t' <- getPOSIXTime
    atomically $ modifyTVar' var (inctime t t')
    countTime var t'

-- Ackermann function
ack m n
    | m == 0    = n + 1
    | n == 0    = ack (m - 1) 1
    | otherwise = ack (m - 1) (ack m (n - 1))

-- Ackerman function lifted to the D data type and strict
ack' (d@D{m, n}) = let a = ack m n
                   in seq a (d { res = Just a })

-- fork a counting time thread, run the computation
-- and finally print the result.
main = do
    d <- atomically (newTVar startvalue)
    forkIO (getPOSIXTime >>= countTime d)
    atomically $ modifyTVar' d ack'
    (atomically $ readTVar d) >>= print

这将导致一个活锁。由于计数线程接触同一TVar,因此反复使Ackermann计算回滚。


将其标记为lang-hs而不是lang-haskell似乎更好(它是google
prettifier

5

Java-没有循环或递归

我刚刚开始学习正则表达式,并编写了第一个程序来测试我的字符串是否与正则表达式匹配。

不幸的是,该程序没有产生任何结果。它支撑了终端。请帮助发现问题。我没有使用任何循环,没有涉及递归。我完全困惑。

import java.util.regex.*;

public class LearnRegex {
     public static void main(String[] args) {
         Pattern p = Pattern.compile("(x.|x.y?)+");
         String s = new String(new char[343]).replace("\0", "x");
         if (p.matcher(s).matches())
             System.out.println("Match successful!");
     }
}

我做错了什么?为什么我的程序没有结束?请帮忙!

Ideone链接在这里

这是灾难性回溯的愚蠢示例。复杂度为O(2 n / 2)。尽管该程序可能不会无限期地运行,但它可能会超过周围和周围没有生命的物体


5

C

您只需要两个循环之一,但是您需要哪个取决于您的编译器。

main()
{
        int i, a[10];

        i = 0;
        while (i <= 10) {
            i++;
            a[i] = 10 - i;
            printf("i = %d\n", i);
        }

        /* Now do it in reverse */

        i = 10;
        while (i >= 0) {
            i--;
            a[i] = 10 - i;
            printf("i = %d\n", i);
        }

}

一个简单的边界超限,将i重置为非终止值。编译器可以在它们是否分配不同的上方或下方一个堆栈上,所以我已经包括在两个方向上溢出。


5

C / C ++

C ++只允许在此使用简单的内联变量声明,但是在普通的旧C语言中犯此错误也很容易...

#include <stdio.h>

int main(void)
{
    int numbers[] = {2, 4, 8};

    /* Cube each item in the numbers array */
    for(int i = 0; i < 3; i++) {
      for(int j = 0; j < 3; i++) {
        numbers[j] *= numbers[j];
      }
    }

    /* Print them out */
    for(int i = 0; i < 3; i++) {
      printf("%d\n", numbers[i]);
    }

    return 0;
}

在内部循环中,比较“ j”,但永不递增。(“ i ++”实际上应该是“ j ++”)。这不是一个狡猾的trick俩,而是更多我过去犯过的实际错误;)有一些需要注意的地方。


2
这通常需要至少5分钟的时间进行调试。我讨厌这样做。
ace_HongKong独立

4

C#

以下是使用后台线程在大型输入数组上执行算术运算(求和)的简单类。其中包含一个示例程序。

但是,即使它非常简单,也永远不会终止。请注意,手没有技巧(字符相似,隐藏/缺少分号,三字组;-等)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

class Program
{
    static void Main()
    {
        var summer = new BackgroundSummer(Enumerable.Range(1, 1234567));
        Console.WriteLine(summer.WaitAndGetResult());
    }
}

public class BackgroundSummer
{
    private IEnumerable<int> numbers;
    private long sum;
    private bool finished;

    public BackgroundSummer(IEnumerable<int> numbers)
    {
        this.numbers = numbers;
        new Thread(ComputingThread).Start();
    }

    public long WaitAndGetResult()
    {
        while (!finished) { /* wait until result available */ }
        return sum;
    }

    private void ComputingThread()
    {
        foreach(var num in numbers)
        {
            sum += num;
        }
        finished = true;
    }
}

这是一个现实世界中令人讨厌的错误的示例,该错误也可能会出现在您的代码中。根据.NET内存模型和C#规范,WaitAndGetResult除非将变量指定为volatile,否则诸如in in之类的循环可能永远不会终止,因为它是由另一个线程修改的。有关详细信息,请参见此StackOverflow问题。该错误取决于.NET的实现,因此它可能会或可能不会影响您。但是通常,在x64处理器上运行发行版似乎会显示问题。(我使用“ csc.exe / o + / debug- infinite.cs”进行了尝试。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.