なぜ終わらないのですか?[閉まっている]


95

あなたの仕事:明らかに終了するはずのプログラムを書くが、それは決して(コンピューターのクラッシュの程度まで)しません。単純なタスクを実行するように見えるようにします:数字を追加したり、何かを印刷したりします...しかし、無限ループに陥ります。

プログラムは実際には予期せぬループに巻き込まれますが、プログラムを非常に明確かつシンプルにしてください。有権者:彼らがいかに「人手不足」であるかについての答えを判断してください!

これは人気コンテストです。クリエイティブになりましょう!


6
誰かが質問の幅を狭めるために私にできることを説明してもらえますか?私はここでは新人です。ありがとうございました!
Number9 14年

6
これは、ループを引き起こすタイプミスと初心者のミスの大きなリストになります。
ビル・ウッドジャー14年

興味深い質問ですが、私はまだ真に創造的な答えを見ていません。ループや明らかな再帰を使用しない人には投票を約束します!
ApproachingDarknessFish 14年

14
これが重要かどうかはわかりませんが、現時点では、Microsoft Officeはこのように動作しています。
レベルリバーセント14年

1
ここでは、手に負えない課題はもはやトピックではないため、この質問をトピック外として終了することに投票しています。meta.codegolf.stackexchange.com/a/8326/20469
cat

回答:


185

Javascript

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

prompt()は文字列を返し、ループは文字「1」を追加します。100に等しくなることはありません。


13
あなたはそれで私を手に入れました...(実際には)より投票された例はすべて構文を乱用しています...しかしそれは素晴らしいです!
bwoebi 14年

4
Kubuntu上のChromeが応答しなくなり、すべてがハングし、ハードリセットする必要がありました:)
セルゲイテルシェフスキー14年

4
@Vlakarados:Pythonは、Javascriptが行う暗黙の型変換を行いません。Pythonでは、raw_inputまたはPython 3 inputを使用した同等のコードはを発生させTypeErrorます。
user2357112 14年

2
値が実際に100未満であるという事実のチェックはないため、「100」と入力すると正常に停止します: '-(
C.Champagne

1
@Sankalp、+ここの演算子は文字列の連結であり、加算ではありません。
マイケルM.

87

C

Cの3種類の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ループには、開き中括弧の前に「do」がありません。これは、実際には、次の「nullステートメント」whileループで終了する(x <10)ループ内にdo-whileループを作成します。xはループ内でインクリメントされ、do-whileループの条件でデクリメントされるため、内側のループは終了せず、外側のループも終了しません。最後の「単一ステートメント」ループに到達することはありません。

まだ混乱している場合は、こちらをご覧ください(codegolf.SEはスポイラーのコードブロックを好まないため、外部でホストされています)。


8
ハハ、ソリューションスポイラーを見る前にこれを考え出した。:P
ジョーZ. 14年

54
「goes to」演算子を使用するこのような素晴らしい機会を放棄したのはなぜですか?(x --> 0)
corsiKa 14年

2
ああすごい。これは驚くほど邪悪です。私はそれを見つけるために4回読んでくれました。
パトリックM 14年

1
@JoeZ。簡単すぎる。最も賛成のソリューションが優れていました。私が見つけられなかったもの。
匿名Pi 14年

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は実際にの2番目の定義を取得し、var a = true;関数の先頭でasを宣言し、whileループに入った時点で意味var a;への割り当てを変更します。a = true;a


3
これが終了しない理由について、より良い説明を追加できますか?「可変巻き上げ」について詳しく説明してください:)
Number9 14年

1
@ Number9役に立てば幸いです。グーグルにはこれよりはるかに良い例があります;)
Newbrict 14年

25
これはセミコロン挿入よりもひどいです。+1!
tomsmeding

2
私がこのプログラムで見た唯一の問題は、単純なタスクを実行するように見えないことです。本質的に何もしないはずです。たぶんalertループの後に追加します。
PeterT 14年

2
に変更する必要a = 1がありa = trueます。コードにはそのように無限ループが残っていますが、理由は、intからbooleanへのJavaScript変換の奇妙なものではないことが明確になります。
ロリーオケイン14年

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' です。数値は64​​32に達することなく非常にすばやくオーバーフローしますが、ビルドオプションでオーバーフローチェックがオンになっていない限り、プログラムは続行します。
おそらく、Visual Studio 2013(およびおそらく他のバージョンも)はこのコードに対して警告を表示し、「l」ではなく「L」を使用することを推奨します。


12
ああ、のlように見えるはず1です!私は愚かだ。:\
ジョーZ.

6
改善のための提案:予想される出力セクションの1もlsに置き換えます(実際の1を比較すると変なキャラクターを見つけやすくなります)
アレングールド14年

3
ええ、それはかなり環境に固有のようです。@Michaelのフォントは、自宅のコンピューター(imgur.com/PKIuJpr-Chrome、Windows 8)のフォントとは非常に異なって見えます。スペック。私の携帯電話のブラウザは固定ピッチのフォントでコードを表示していないようで、そのトリックはまったく機能しません。
BenM

1
FTR、これは私の仕事用コンピューター(imgur.com/Opfs3BH-Firefox、Windows 7)での表示です。私は非常に抜け目のない人をだますことさえできると思います。
BenM 14年

15
なぜ同じように見えるキャラクターを虐待し続けるのですか?
匿名Pi 14年

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 14年

5
丸めエラー。0.1は実際には0.100000000000000006です。これは、バイナリの0.1は10進数の1/3に似ているためです。バイナリ展開は無限で周期的です。
オリオン14年

3
実際には丸め誤差ではありません。浮動小数点値は、数値の近似表現です。近似値間で正確な比較を実行しても機能しません。
AKHolland

4
これが、(ほとんど)等しいかどうかfloat / doubleを比較するべきではない理由です。
エマニュエルランドホルム14年

1
これを見るのを待っていました。いいね
デビッドコンラッド14年

33

HTML / JavaScript

ページに入力ボックスがあると想像してください。

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

そして今、あなたはそれに何かを入力したい... Chromeで試してみてください:http//jsfiddle.net/jZp4X/

alert関数で呼び出される標準のブラウザダイアログボックスはモーダルです。したがって、表示されるとテキストボックスからフォーカスが外されますが、閉じられるとテキストボックスはフォーカスを受け取ります。


5
Firefoxでは、入力が警報近くにオートフォーカスを持っていない、2回目からは、より多くのアラートを表示しないようにして、私は通常、テキストボックスに書くことができます私を提供しています
Einacio

6
良いですね。ループや再帰がない場合は+1。
近づい

5
FirefoxまたはChromeでループは発生しません。FFは、ダイアログがクリックされたときにアラートを一度表示し、それを閉じると終了です。もう一度クリックして繰り返します。Chromeも同じことを行いますが、ボックスに焦点を当てたままにして、入力することもできます。申し訳ありませんが、古いバージョンではこれは問題でしたが、もう問題ではありませんでした。
RomanSt 14年

6
IE11は、Chromeとまったく同じように機能します。Macのすべての最新のブラウザーで1つの方法で動作し、Windowsのすべての最新のブラウザーで異なる方法で動作するものの例を偶然見つけたと思います!
RomanSt 14年

1
MSIE11で正常に動作する(ループなし)
kinokijuf

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 >=0size_tには符号がないため、条件は常に真です。


2
良いものですが、コンパイラは通常これに対して警告を出力します;)
Synxis 14年

2
@Synxis Yesコンパイラはそうです。ただし、コンパイラの警告を有効にする場合のみ。g++それらがなくてもこれについては警告しません。
FDinoff 14年

5
-Wall --pedanticとにかく常に使用する必要があります。
マーティンUeding

3
@queueoverflow警告は、これらのフラグのみでは表示されません。-Wsign-compareで有効にする必要があります-Wextra
FDinoff 14年

7
-pedanticのダッシュ。#pedantic
デビッドコンラッド

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、foo [2]を終わらない量の "yes \ n"で埋めます。


最終的bashにメモリを使い果たし、クラッシュする
デジタル外傷

4
はい、確かにそうです。しかし、クラッシュは一種の質問によって許可されました:)
GreenAsJade 14年

はい、ただの観察:)。賛成。
デジタル外傷14年

実際に、私は実際にあなたのマシン、またはサービスの他のいくつかの拒否をクラッシュこの小さなコンプでのプログラムは、ボーナスマークを取得する必要があることを数える)
GreenAsJade

修正: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変更しました。彼はまた、常に非負の値を持っていることを知るのに十分なほどアスキーを知っていました。それで彼は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を返すことができるためです。
signed charを使用している限り、すべてが正常に機能します。50に等しいcharは、fgetc()によって50に等しいintにも拡張されます。次に、それをcharに変換しなおし、50を保持します。-1またはfgetc()からのその他の出力についても同様です。
しかし、unsigned charを使用するとどうなるかを見てください。fgetc()のcharから始めてintに拡張し、次にunsigned charを取得します。唯一の問題は、unsigned charに-1を保持できないことです。プログラムはEOFと等しくない255として保存しています。

警告
ANSI Cドキュメントのコピーの セクション3.1.2.5の型を見ると、charが署名されているかどうかは実装のみに依存していることがわかります。そのため、コードに潜んでいる非常にトリッキーなバグを見つけたため、その男はおそらく解雇されるべきではありません。コンパイラを変更したり、別のアーキテクチャに移行したりするときに出てくる可能性があります。そのような場合にバグが出たら誰が解雇されるのだろうか;)

PS。プログラムは、Paul A. CarterによるPC Assembly Languageに記載されているバグを中心に構築されました。


7
ソリューションに物語があることが大好きです。
jpmc26 14年

ハハ!それだけだと思います。読んでくれてありがとう!
レガ14年

1
わたしは、あなたを愛しています。あなたのストーリーを教えてくださいpls :(
YoYoYonnY

これは絶対に素晴らしいです!
kirbyfan64sos

21

正規表現

適切な入力を使用すると、次の正規表現により、ほとんどのバックトラッキング正規表現エンジンがバックトラッキング地獄に入ります。

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

"Programming Puzzles and Code Golf Stack Exchange - Mozilla Firefox"or などの単純な入力"AVerySimpleInputWhichContainsAnInsignificantSentence."(両方の文字列を明確にするため引用符で囲んでいます)は、ほとんどのバックトラッキング正規表現エンジンを長時間実行し続けるのに十分です。

(\s*\w+)*拡張を可能にするので\w+\w+\w+... ... \w+つまり、正規表現エンジンは基本的に単語文字列を分割するために考えられるすべての方法を試します。これがバックトラッキングヘルの原因です。
それは簡単に変更することで固定することができます\s*\s+、その後、(\s+\w+)*のみに拡張することができます\s+\w+\s+\w+... \s+\w+


3
正規表現エンジンのバックトラッキングが嫌いです。
デビッドコンラッド14年

2
最初にPerlでこれを試しましたが、Perlはここでループに気付くようです。AWKでこのような動作を引き起こす正規表現はないため、AWKは試しませんでした。PHPは自動的に正規表現を作成し、一致に失敗するには時間がかかりすぎます(これはばかげていますが、それはあなたにとってPHPです-バグをプログラムに自動的に挿入します)。ただし、実際にはPythonで動作します。
コンラッドボロウスキ14年

1
@xfix:Perlがなんとかバックトラッキングの地獄を避けることができた理由については、この記事でその理由を説明します。ただし、ここに示すように、ケースに対して十分ではありません(パフォーマンスセクションまでスクロールします)。PHP(実際にはPCREライブラリ)にはバックトラッキングの制限があり、適切なプログラムは常に関数の戻り値をチェックして、実行が停止したか、実行が完了したかを判断する必要があります。
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

1
これはとても滑らかです。
alvonellos

20

JavaScript

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

050はJavascriptの8進定数であり、たまたま10進値の40を持っています。


73
これは明らかです。:
ジャスティン14年

6
javascriptがこれを行ったことを知りませんでした。しかし、コードを読んだ後、私は言った:「050は、おそらく8か何かをベースに、40を表すいくつかの方法であることがある」
たけた

これはもっとよく隠す必要があります。
パウロEbermann

それは明らかです。..
オリバー・ニッケル

18

ハスケル

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

考えてみてください!それは同じですhead $ "Hello" ++ (repeat '!')、すなわちただ戻るべき'H'です。

haskellでは、リストは再帰構造であり、最初の要素が最上位にあります。リストに追加するには、これらの要素をすべて展開し、付録を配置し、持ち上げた要素を元に戻す必要があります。無限のリストでは機能しません。同様に、無限のリストを反転しても、魔法のようにあなたの"Hello"背中を与えることはありません。いつまでもハングします。


1
残念なことに、これは実際には機能しません:-/
ジョンドヴォルザーク14年

1
どのように機能しないのですか?
danmcardle 14年

@crazedgremlinがFedoraでこれをテストしたとき、OSは最終的にプロセスを強制終了しました。(<5分)システム上のすべてのメモリを使い果たしたため。
FDinoff

面白い!私はこれが起こったことを知りませんでした。私はあんなに頻繁にすべてを記憶する領域に挑戦しません。
danmcardle

4
それがまだ有効なソリューションです:それは終了しません、それは...限り、それはシステムまで、もうそれをサポートすることはできませんとして実行
GreenAsJade

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」で意味が分からないかもしれません。
アステリ14年

4
ストリームが空になっていない場合、プログラムはブロックされ、頭痛の種になりました。長いディレクトリは、バッファがフルに動作することを保証します
masterX244

ああ、落とした。いいね!+1
アステリ14年

15

リンゴとオレンジを比較するには... C

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
あなたは卑劣なろくでなし、後藤はこれで無実です:)
オリオン14年

random()はvodooを使用しましたか?
masterX244 14年

1
ahh、 "2"!= 2; 得たこと
masterX244

2
「2」はおそらく2にはならないでしょうが、もっと大きな数(少なくとも4の倍数)を使用すると、それが起こる可能性があります;)
orion 14年

1
@オリオン:はい、そうです。また、gotoは依然として悪ですが、悪い型キャストはさらに悪です!
max.haredoom 14年

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ビット整数は、本当に、本当に、本当に長い時間がかかります(各反復にナノ秒かかる場合は585年)。
ポールドレーパー14年

11

C ++

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

奇妙なコメントスタイルがトリックです。ヒント:トライグラフ。


これは、無限ループの非常に基本的な例です。
イスマエルミゲル14年

64
これらの
Trigraphsは

75
もはやおもしろくない標準の抜け穴にトライグラフを入れるべきだと思う。
地下

6
@TheDoctor:?? /はバックスラッシュ文字の3文字表記であるため、バックスラッシュは、xがコメントの最後に0を割り当てられた行をスプライスし、コメントの一部にします。
CasaDeRobison 14年

4
@undergroundmonorail 投稿
ジャスティン14年

11

Java

オートボクシング最適化のこの副作用が特に気に入っています。

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ここではほとんどプレーンのように動作しますが、1つの例外i != maxがありforます。ループ内では、オブジェクトの値(等式)ではなく、オブジェクトの参照(同一性)を比較しますInteger。最大100の値の場合、JVMの最適化により、これは驚くほど「機能」します。Java Integerは、「最も一般的な値」にオブジェクトを事前に割り当て、オートボクシング時にそれらを再利用します。したがって、最大100の値に対して、同一性<==>が等しくなります。


5
いくつかのJavaの連中は、まだ検討していることを考えるとC ++オペレータのオーバーロードなどの ...
ダニエル

= new Integer(0)とにかく値を初期化するので、初期化は必要ありません。(これにより、理由がより明白でなくなる可能性があります。)
PaŭloEbermann 14

@PaŭloEbermann:いいですね、コードを編集しました。
ダニエル14年

9

Ruby / 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で実行すると、終了しません。

Rubyでは0は偽の値ではありません。


一度に言語を実行します...印象的です。
ポールドレーパー14年

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

@ronondex Javascript
tomsmeding 14年

1
ああ、はい、それはJavascriptです。シンタックスハイライトを有効にすることを思い出しましたが、タイトルにもそれを入れることを忘れなければなりません
でした

1
これは明らかです。:-)
rafaelcastrocouto 14年

@rafaelcastrocoutoええ、それはちょっとですが、たとえば、ある関数から別の関数にループを移動したり、コードをちらっと見たりするときも見逃しがちです。また、Cを含むいくつかの言語では、変数のシャドーイングにより、これが実際に正しく機能することに注意してください。:)
アレクシトルハモ14年

7

C

これにより、0〜255のすべてのASCII文字のコードテーブルが出力されます。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:素晴らしいアイデア。
ラファウチェエラク14年

私は教室でこのトリックを使用します。印刷可能な符号なし文字は
32〜128です。

7

Python

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

あるべきでexit()はないexit。私が理解しているようにexit()、Pythonインタープリターを終了するコマンドです。この場合、呼び出しは関数の表現に対するものであり、関数に対するものではありません:exit-discussionを参照してください。あるいはbreak、より良い選択でしょう。


exit実際に何であるか説明していただけますか?クラスのように見えますが、何のために使用されますか?また、変更される可能性print mprint(m)、これはまた、Pythonの3で動作するように
マーティン・トーマ

1
それらの種類...私のelseifエリフであったために動作しなかったときのように。
匿名Pi 14年

@moose更新された印刷ステートメントとネタバレメッセージに感謝します
ウィレム

6

C ++

古典的なC ++プログラマのtrapはどうですか?

int main()
{
   bool keepGoing = false;

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

   return 0;
}

これがわからない?使用することについてですか。===の代わりに?
Mhmd

@ user689正確に。keepGoing = trueの値を比較するためのものでしたがkeepGoing、代わりに値を割り当てますkeepGoing; さらに、ステートメント全体がkeepGoing = true評価されtrue(これによりのような記述が可能になりますa=b=c=d=0)、無限ループになります。
CompuChip 14年

3
これはヨーダの条件を使用するより多くの理由です。
ライアン14年

@RyanEdwardDoughertyハハは、彼らが呼ばれるのを聞いたことがない。朝は笑ってくれてありがとう。
CompuChip 14年

@RyanEdwardDougherty:もちろん== true(またはヨーダスタイルtrue ==)はとにかく冗長であり、条件は単に読み取る必要がありますwhile (keepGoing)
celtschk 14年

6

Javascript

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

1行目と3行目で使用される変数は、2行目と3行目で使用される変数とは異なります。
1つは(U + 0061)を使用しもう1つはа(U + 0430)を使用します


ここには問題はありません。私はそれを実行し、それはうまくいきました。私は何が欠けていますか?
アンドリューシェパード14年

ユニコードはおそらく変換されるため、これはおそらくどこでも動作します。あなたが得ることができるようにそれが最も見えないので、+ 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;あまり現実的ではないため
YoYoYonnY

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
returnステートメントの余分な括弧、yuck。
デビッドコンラッド14年

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

これにより、ライブロックが発生します。カウントスレッドは、Ackermannの計算が同じTVarに触れるため、繰り返しロールバックします。


lang-haskellの代わりにlang-hsとしてマークすることはよりうまく機能するようです(これはgoogle prettifierの拡張機能の1つです)
Einacio 14年

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!");
     }
}

私は何を間違えましたか?プログラムが終了しないのはなぜですか?助けてください!

イデオネのリンクはこちら

これは壊滅的なバックトラッキングのばかげた例です。複雑さはO(2 n / 2)です。このプログラムは無期限に実行されないかもしれませんが、おそらく生きているオブジェクトと生きていないオブジェクトの両方の周りで生き残ります


5

C

必要なのは2つのループのうち1つだけですが、必要なループはコンパイラーによって異なります。

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を非終了値にリセットする単純な境界オーバーラン。コンパイラーは、スタック上のaの上または下に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 ++」でなければなりません)。これはそれほど卑劣なトリックではありませんが、私が過去に犯した実際のエラーの多くです;)


2
これには通常、デバッグに少なくとも5分かかります。私はこれをしたときに嫌いです。
ace_HongKongIndependence 14年

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として指定しない限り、別のスレッドによって変更されるため、ループのようなループは終了しない可能性があります。詳細については、このStackOverflowの質問を参照してください。このバグは.NET実装に依存しているため、影響を受ける場合と影響しない場合があります。しかし、通常、x64プロセッサでリリースビルドを実行すると問題が表示されるようです。(「csc.exe / o + / debug- infinite.cs」で試しました。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.