ทำไมมันไม่จบ [ปิด]


95

งานของคุณ: ในการเขียนโปรแกรมที่ควรจะยุติอย่างเห็นได้ชัด แต่ไม่เคยทำ (เท่าที่คอมพิวเตอร์พัง) ทำให้ดูเหมือนว่าควรทำงานอย่างง่าย: เพิ่มตัวเลขพิมพ์บางสิ่งบางอย่าง ... แต่มันก็ติดอยู่ในวงวนไม่สิ้นสุด

พยายามทำให้โปรแกรมของคุณชัดเจนและเรียบง่ายในขณะที่มันจะติดอยู่ในการวนรอบที่ไม่คาดฝัน ผู้ออกเสียงลงคะแนน: ตัดสินคำตอบว่าพวกเขาเป็น "คนเล่ห์เหลี่ยม" อย่างไร!

นี่คือการประกวดความนิยม: มีความคิดสร้างสรรค์!


6
ใครช่วยกรุณาอธิบายสิ่งที่ฉันสามารถทำได้เพื่อทำให้คำถามที่กว้างน้อยลง? ฉันใหม่ที่นี่ ขอขอบคุณ!
หมายเลข 9

6
นี่เป็นเพียงรายการใหญ่ของการพิมพ์ผิดและความผิดพลาดของผู้เริ่มต้นซึ่งทำให้เกิดการวนซ้ำ
Bill Woodger

คำถามที่น่าสนใจ แต่ฉันยังไม่เห็นคำตอบที่สร้างสรรค์อย่างแท้จริง ฉันสัญญาว่าจะให้คะแนนใครก็ตามที่ไม่ได้ใช้ลูปหรือการเรียกซ้ำที่ชัดเจน!
ApproachingDarknessFish

14
ฉันไม่รู้ว่าสิ่งนี้มีความสำคัญหรือไม่ แต่ Microsoft Office ของฉันมีพฤติกรรมเช่นนี้ในขณะนี้
เลเวลริเวอร์เซนต์

1
ฉันลงคะแนนเพื่อปิดคำถามนี้เป็นนอกหัวข้อเนื่องจากความท้าทายที่ไม่ได้อยู่ภายใต้หัวข้อนี้อีกต่อไป meta.codegolf.stackexchange.com/a/8326/20469
cat

คำตอบ:


185

จาวาสคริ

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

prompt () ส่งคืนสตริงและวนรอบจะเพิ่มอักขระ '1' โดยจะไม่เท่ากับ 100


13
คุณได้ฉันมากับตัวอย่างนั้น…ตัวอย่างที่ได้รับการโหวตสูงกว่านั้นล้วน แต่เป็นการใช้ไวยากรณ์ที่ไม่เหมาะสม… แต่สิ่งนั้นดีมาก!
bwoebi

4
Chrome บน Kubuntu ไม่ตอบสนองแขวนทุกอย่างและฉันต้องรีเซ็ตอย่างหนัก :)
Sergey Telshevsky

4
@Vlakarados: Python จะไม่ทำการแปลงประเภทโดยนัยของ Javascript เกี่ยวกับงูหลามรหัสเทียบเท่าใช้raw_inputหรืองูหลาม 3 ยกinput TypeError
user2357112

2
ไม่มีการตรวจสอบความจริงที่ว่าค่าต่ำกว่า 100 ดังนั้นจึงหยุดตามปกติเมื่อคุณป้อน "100": '- (
C.Champagne

1
@Sankalp +โอเปอเรเตอร์ที่นี่คือการต่อสตริงไม่ใช่การเพิ่ม
Michael M.

87

C

เป็นเพียงโปรแกรมตัวอย่างพื้นฐานที่แสดงให้เห็นถึง while-loop ใน C

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;
}

ในขณะที่ลูปไม่มี "ทำ" ก่อนที่จะทำการเปิดลอนรั้ง นี่เป็นการสร้างลูป do-while ภายในลูป (x <10) ที่ถูกยกเลิกด้วยคำสั่ง "null" ต่อไปนี้ในขณะที่ลูป เนื่องจาก x ถูกเพิ่มค่าภายในของลูปและจากนั้นลดค่าลงในสภาพของลูปในขณะที่ทำวงรอบด้านในจะไม่ยุติการทำงานและไม่ได้ทำการวนรอบนอก วน "คำสั่งเดียว" ที่สิ้นสุดจะไม่ถึง

หากคุณยังสับสนอยู่ให้ดูที่นี่ (โฮสต์จากภายนอกเพราะ codegolf.SE ไม่ชอบบล็อคโค้ดในสปอยเลอร์)


8
ฮ่าฮ่าฉันคิดเรื่องนี้ก่อนที่จะดูสปอยเลอร์วิธีแก้ปัญหา : P
Joe Z.

54
ทำไมคุณถึงผ่านโอกาสที่ยอดเยี่ยมเช่นนี้ไปใช้โอเปอเรเตอร์ "ไปที่" (x --> 0)
corsiKa

2
โอ้ว้าว. นี่มันชั่วร้ายอย่างน่าพิศวง เอาฉันสี่อ่านผ่านเพื่อค้นหา
Patrick M

1
@JoeZ วิธีง่ายเกินไป วิธีแก้ปัญหาที่ upvoted ที่สุดดีกว่า ฉันไม่พบ
ไม่ระบุชื่อ Pi

3
@Hat Guy, Bash มี for; do และ while; ทำไวยากรณ์เพื่อให้ฉันเห็นคนที่ถูกโยนทิ้งโดยสิ่งนี้แม้ว่าพวกเขาจะคุ้นเคยกับภาษาที่ไม่ใช่ภาษา 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;
})();

การยกตัวแปร: จาวาสคริปต์จริง ๆ แล้วจะคว้านิยามที่สองของฉันvar a = true;ประกาศที่ด้านบนของฟังก์ชั่นเป็นvar a;และแก้ไขการกำหนดของฉันเป็นa = true;ความหมายaจะไม่ได้กำหนดในเวลาที่มันเข้ามาในขณะที่วนรอบ


3
คุณช่วยเพิ่มคำอธิบายที่ดีขึ้นเกี่ยวกับสาเหตุที่สิ่งนี้ไม่มีวันยุติได้หรือไม่? โปรดเข้าไปที่ส่วนลึกเกี่ยวกับ "ตัวแปรรอก" :)
หมายเลข 9

1
@ หมายเลข 9 ฉันหวังว่าจะช่วยได้ google มีตัวอย่างที่ดีกว่านี้มาก)
Newbrict

25
อึศักดิ์สิทธิ์นี่มันยิ่งแย่ไปกว่าการแทรกอัฒภาค +1!
tomsmeding

2
ปัญหาเดียวที่ฉันเห็นในโปรแกรมนี้คือมันดูไม่เหมือนว่ามันทำงานง่าย ๆ ... ดูเหมือนว่ามันไม่ควรทำอะไรเลย อาจเพิ่มalertหลังจากวง
PeterT

2
คุณควรเปลี่ยนไปa = 1 a = trueรหัสจะยังคงมีวงวนไม่สิ้นสุดด้วยวิธีนี้ แต่จะชัดเจนว่าเหตุผลนั้นไม่ใช่การเล่นโวหารในการแปลงจาวาสคริปต์จาก ints ถึง booleans
Rory O'Kane

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' แต่เป็น '20' ที่มีตัวต่อท้าย'L' ( ประเภทข้อมูลยาว ) ตัวพิมพ์เล็ก จำนวนจะล้นอย่างรวดเร็วโดยไม่ต้องกดปุ่ม 6432 แต่โปรแกรมจะดำเนินต่อไปจนกว่าจะเปิดการตรวจสอบโอเวอร์โฟลว์ในตัวเลือกบิลด์
อย่างสมเหตุสมผล Visual Studio 2013 (และอาจเป็นเวอร์ชั่นอื่น ๆ ด้วย) ให้คำเตือนสำหรับรหัสนี้แนะนำให้คุณใช้ 'L' แทน 'l'


12
โอ้ที่lควรจะมีลักษณะเหมือน1! ฉันโง่. : \
Joe Z.

6
คำแนะนำสำหรับการปรับปรุง: แทนที่ 1 ในส่วนเอาท์พุทที่คาดหวังด้วย ls เช่นกัน (ง่ายกว่าที่จะมองเห็นตัวละครแปลก ๆ เมื่อคุณมี 1s จริงเพื่อเปรียบเทียบกับ)
Allen Gould

3
ใช่มันดูเหมือนจะค่อนข้างเฉพาะสภาพแวดล้อม @ แบบอักษรของ Michael ดูแตกต่างจากแบบอักษรบนคอมพิวเตอร์ที่บ้านของฉัน ( imgur.com/PKIuJpr - Chrome, Windows 8) และเคล็ดลับดูเหมือนว่าจะทำงานได้ดีกับคอมพิวเตอร์ที่ทำงานของฉันมากกว่าคอมพิวเตอร์ที่บ้านถึงแม้ว่าพวกเขาจะค่อนข้างคล้ายกัน รายละเอียด ดูเหมือนว่าเบราว์เซอร์ของโทรศัพท์ของฉันจะไม่แสดงรหัสในแบบอักษรที่มีระดับเสียงคงที่และเคล็ดลับไม่สามารถใช้งานได้เลย
BenM

1
FTR นี่คือลักษณะของคอมพิวเตอร์ที่ทำงานของฉัน ( imgur.com/Opfs3BH - Firefox, Windows 7) ฉันคิดว่าคน ๆ หนึ่งอาจหลอกคนที่ค่อนข้างฉลาดได้
BenM

15
ทำไมคนจึงต้องละทิ้งตัวละครที่ดูเหมือนเดิม?
ผู้ไม่ประสงค์ออกนาม Pi

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

5
ข้อผิดพลาดในการปัดเศษ 0.1 คือ 0.100000000000000006 จริง ๆ แล้วเพราะ 0.1 ในไบนารี่เท่ากับ 1/3 ในทศนิยม - การขยายฐานสองนั้นไม่มีที่สิ้นสุด & เป็นระยะ
orion

3
ไม่ใช่ข้อผิดพลาดในการปัดเศษ ค่าจุดลอยตัวเป็นตัวแทนของตัวเลขโดยประมาณ ทำการเปรียบเทียบที่ถูกต้องระหว่างค่าโดยประมาณจะไม่ทำงาน
AKHolland

4
นี่คือเหตุผลที่คุณ (เกือบ) ไม่ควรเปรียบเทียบ float / doubles เพื่อความเท่าเทียมกัน
Emanuel Landeholm

1
ฉันรอดูอันนี้ ดี
David Conrad

33

HTML / JavaScript

ลองนึกภาพคุณมีกล่องใส่ในหน้าของคุณ:

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

และตอนนี้คุณต้องการที่จะพิมพ์อะไรบางอย่างที่อยู่ในนั้น ... ลองใน Chrome: http://jsfiddle.net/jZp4X/

กล่องโต้ตอบเบราว์เซอร์มาตรฐานที่เรียกว่าalertฟังก์ชั่นนั้นเป็นโมดัลดังนั้นเมื่อมันแสดงขึ้นมันจะทำการโฟกัสออกจากกล่องข้อความ แต่เมื่อมันถูกไล่ออกกล่องข้อความจะได้รับการโฟกัสกลับ


5
ใน firefox อินพุตไม่ได้มีระบบโฟกัสอัตโนมัติเมื่อปิดการแจ้งเตือนและจากครั้งที่สองก็ให้ฉันไม่แสดงการแจ้งเตือนเพิ่มเติมจากนั้นฉันสามารถเขียนในกล่องข้อความตามปกติ
Einacio

6
ทำได้ดีนี่. +1 โดยไม่มีลูปหรือเรียกซ้ำ
ApproachDarknessFish

5
ไม่มีลูปใน Firefox หรือ Chrome FF แสดงการแจ้งเตือนหนึ่งครั้งเมื่อมีการคลิกกล่องโต้ตอบคุณจะปิดและนั่นคือจุดสิ้นสุด สามารถคลิกอีกครั้งเพื่อทำซ้ำ Chrome ทำเช่นเดียวกัน แต่ปล่อยให้กล่องโฟกัสและคุณสามารถพิมพ์ลงไปได้ ขออภัยอาจเป็นรุ่นเก่ากว่านี้เป็นปัญหา แต่ไม่ใช่อีกต่อไป
RomanSt

6
IE11 ทำงานเหมือนกับ Chrome สำหรับฉัน ฉันคิดว่าคุณได้พบตัวอย่างของสิ่งที่ทำงานทางเดียวในเบราว์เซอร์สมัยใหม่ทุกเครื่องบน Mac และอีกวิธีหนึ่งในทุกเบราว์เซอร์สมัยใหม่บน Windows!
RomanSt

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 >=0เป็นจริงเสมอเนื่องจาก size_t ไม่ได้ลงนาม


2
Nice หนึ่งคอมไพเลอร์โดยปกติแล้วจะส่งคำเตือนสำหรับเรื่องนี้;)
Synxis

2
@Synxis ใช่คอมไพเลอร์ทำ แต่ถ้าคุณเปิดคำเตือนคอมไพเลอร์ g++จะไม่เตือนคุณเกี่ยวกับสิ่งนี้หากไม่มีพวกเขา
FDinoff

5
คุณควรใช้-Wall --pedanticอยู่ดี
Martin Ueding

3
@queueoverflow คำเตือนไม่แสดงพร้อมกับแฟล็กเหล่านั้นเท่านั้น คุณต้องซึ่งสามารถเปิดด้วย-Wsign-compare -Wextra
FDinoff

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]}

แทนที่จะกำหนดสตริง 'ใช่' ให้กับ foo [2] สิ่งนี้จะเรียกคำสั่งระบบyesซึ่งเติมค่า foo [2] ด้วยจำนวนที่ไม่สิ้นสุดของ "ใช่ \ n"


ในที่สุดbashหน่วยความจำหมดและเกิดปัญหา
Digital Trauma

4
ใช่แน่นอนมันทำ แต่ความผิดพลาดได้รับอนุญาตโดยชนิดของคำถาม :)
GreenAsJade

ใช่แค่การสังเกต :) upvoted
บาดเจ็บทางดิจิตอล

ในความเป็นจริงฉันคิดว่าโปรแกรมในคอมพ์เล็ก ๆ น้อย ๆ นี้ที่ทำให้เครื่องของคุณพังหรือการปฏิเสธการบริการอื่น ๆ ควรได้รับคะแนนโบนัส)
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 เข้า int เขารู้ดีว่า ascii ดีพอที่จะรู้ว่าพวกเขามีค่าที่ไม่เป็นลบเสมอ ดังนั้นเขาก็เปลี่ยนถ่านที่ไม่ได้ลงชื่อเข้าถ่าน เขารวบรวมรหัสและกลับบ้านภูมิใจในงานที่ดีที่เขาทำ โปรแกรมมีลักษณะดังนี้:

#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" หายไปและถึงแม้ว่ามันควรจะอยู่ใน "desert_file" ที่มี "abc" โปรแกรมกำลังค้นหามันตลอดไปพิมพ์ออกมาเท่านั้น:

Searching file for missing letter a...

พวกเขาไล่คนออกและย้อนกลับไปสู่รุ่นก่อนหน้าโดยระลึกว่าไม่ควรเพิ่มประสิทธิภาพประเภทข้อมูลในรหัสการทำงาน

แต่บทเรียนที่พวกเขาควรเรียนรู้ที่นี่คืออะไร

ก่อนอื่นถ้าคุณดูตาราง ascii คุณจะสังเกตเห็นว่าไม่มี EOF นั่นเป็นเพราะ EOF ไม่ใช่ตัวละคร แต่เป็นค่าพิเศษที่ส่งคืนจาก fgetc () ซึ่งสามารถส่งคืนอักขระที่ขยายเป็น int หรือ -1 หมายถึงจุดสิ้นสุดของไฟล์
ตราบใดที่เราใช้ char ที่ลงชื่อแล้วทุกอย่างทำงานได้ดี - char เท่ากับ 50 จะขยายโดย fgetc () เป็น int เท่ากับ 50 เช่นกัน จากนั้นเราแปลงมันกลับเป็นถ่านและยังมี 50 เหมือนกันเกิดขึ้นกับ -1 หรือผลลัพธ์อื่น ๆ ที่มาจาก fgetc ()
แต่ดูสิ่งที่เกิดขึ้นเมื่อเราใช้ถ่านที่ไม่ได้ลงชื่อ เราเริ่มต้นด้วย char ใน fgetc () ขยายไปยัง int แล้วต้องการถ่านที่ไม่ได้ลงนาม ปัญหาเดียวคือเราไม่สามารถรักษา -1 ในถ่านที่ไม่ได้ลงนาม โปรแกรมจัดเก็บเป็น 255 ซึ่งไม่เท่ากับ EOF

ข้อแม้
หากคุณดูที่หัวข้อ 3.1.2.5 ประเภทในสำเนาของเอกสาร ANSI Cคุณจะพบว่าการลงชื่อเข้าใช้หรือไม่นั้นขึ้นอยู่กับการใช้งานเพียงอย่างเดียว ดังนั้นคนที่แต่งตัวประหลาดอาจไม่ควรถูกไล่ออกเนื่องจากเขาพบข้อผิดพลาดที่ยุ่งยากมากที่ซ่อนอยู่ในรหัส มันอาจออกมาเมื่อเปลี่ยนคอมไพเลอร์หรือย้ายไปที่สถาปัตยกรรมอื่น ฉันสงสัยว่าใครจะถูกไล่ออกหากเกิดข้อผิดพลาดในกรณีเช่นนี้;)

PS โปรแกรมถูกสร้างขึ้นรอบข้อผิดพลาดที่กล่าวถึงใน PC Assembly Language โดย Paul A. Carter


7
ฉันรักที่มีเรื่องราวกับวิธีแก้ปัญหา
jpmc26

ฮ่าฮ่า! ฉันเดาว่ามันเป็นสิ่งเดียวเท่านั้น ขอบคุณที่อ่าน!
Legat

1
ฉันรักคุณ.
เลี้ยงดู

มันยอดเยี่ยมมาก!
kirbyfan64sos

21

regex

ด้วยอินพุตที่เหมาะสม regex ต่อไปนี้สามารถทำให้เอนจินการย้อนรอยกลับส่วนใหญ่เข้าสู่ backtracking hell:

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

อินพุตอย่างง่ายเช่น"Programming Puzzles and Code Golf Stack Exchange - Mozilla Firefox"หรือ"AVerySimpleInputWhichContainsAnInsignificantSentence."(ทั้งสองสตริงที่ยกมาเพื่อความชัดเจน) ก็เพียงพอที่จะทำให้เอนจินการ regex ส่วนใหญ่ทำงานอยู่เป็นเวลานาน

เนื่องจาก(\s*\w+)*ช่วยให้การขยายตัว\w+\w+\w+... \w+ซึ่งหมายความว่าเครื่องยนต์ regex โดยทั่วไปจะพยายามหาวิธีที่เป็นไปได้ทั้งหมดเพื่อแยกสายอักขระที่เป็นตัวอักษรคำว่า นี่คือต้นกำเนิดของนรกย้อนรอย
มันสามารถได้รับการแก้ไขโดยการเปลี่ยน\s*ไป\s+แล้ว(\s+\w+)*เท่านั้นที่สามารถขยายได้ถึง...\s+\w+\s+\w+\s+\w+


3
ฉันเกลียดเอ็นจิ้นการติดตามย้อนรอย
David Conrad

2
ฉันลองมันกับ Perl ก่อน แต่ดูเหมือนว่า Perl จะสังเกตเห็นลูปที่นี่ ฉันไม่ได้ลอง AWK เพราะไม่มีนิพจน์ทั่วไปที่สามารถทำให้เกิดพฤติกรรมดังกล่าวใน AWK PHP สร้างนิพจน์ปกติโดยอัตโนมัติซึ่งใช้เวลานานเกินไปที่จะจับคู่ล้มเหลว (ซึ่งเป็นเรื่องโง่ แต่นั่นคือ PHP สำหรับคุณ - มันจะแทรกข้อบกพร่องลงในโปรแกรมโดยอัตโนมัติ) อย่างไรก็ตามมันใช้งานได้จริงใน Python
Konrad Borowski

1
@ แก้ไข: สำหรับเหตุผลที่ 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 และมีค่าทศนิยม 40


73
ฉันพบสิ่งนี้ชัดเจน :-)
Justin

6
ฉันไม่รู้ว่า javascript ทำเช่นนี้ แต่หลังจากที่ได้อ่านรหัสฉันกล่าวว่า: "050 จะเป็นวิธีการของการเป็นตัวแทน 40 บางมีอาจจะเป็นฐาน 8 หรือบางสิ่งบางอย่าง"
Cruncher

สิ่งนี้จะต้องซ่อนตัวให้ดีขึ้น
Paŭlo Ebermann

เห็นได้ชัดว่า ..
โอลิเวอร์ Ni

18

Haskell

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

ลองคิดดูสิ! มันจะเป็นเช่นเดียวกับคือก็ควรจะกลับมาhead $ "Hello" ++ (repeat '!')'H'

ในรายการ haskell เป็นโครงสร้างแบบเรียกซ้ำโดยองค์ประกอบแรกจะอยู่ด้านบนสุด ในการต่อท้ายรายการคุณจะต้องยกเลิกการเปิดใช้งานองค์ประกอบทั้งหมดวางภาคผนวกของคุณและนำองค์ประกอบที่ยกกลับมา ที่จะไม่ทำงานในรายการไม่มีที่สิ้นสุด ในทำนองเดียวกันการย้อนกลับรายการไม่มีที่สิ้นสุดจะไม่ทำให้คุณได้รับผล"Hello"ตอบแทนอย่างน่าอัศจรรย์ มันจะแขวนตลอดไป


1
น่าเสียดายที่นี่ใช้งานไม่ได้: - /
John Dvorak

1
มันใช้งานไม่ได้อย่างไร
danmcardle

@crazedgremlin เมื่อฉันทดสอบสิ่งนี้บน Fedora ในที่สุดระบบปฏิบัติการก็หยุดกระบวนการนี้ (<5 นาที) เพราะมันใช้หน่วยความจำหมดในระบบ
FDinoff

ที่น่าสนใจ! ฉันไม่ได้ตระหนักว่าสิ่งนี้เกิดขึ้น ฉันไม่กล้าเข้าไปในดินแดนที่กลืนกินความทรงจำทั้งหมดที่มักเกิดขึ้น
danmcardle

4
ยังคงเป็นทางออกที่ถูกต้อง: มันไม่ได้ออกจากมันจะทำงานตราบเท่าที่มันสามารถจนกว่าระบบจะไม่สามารถรองรับได้อีกต่อไป ...
GreenAsJade

16

Java ภายใต้ Windows

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();
    }
}

โปรแกรมอาศัยสตรีมเอาท์พุทมาตรฐานที่ติดอยู่จาก commandline เพื่อติดขัด ไดเรกทอรี WinSXS ภายใต้ windows มีไฟล์หลายพันไฟล์ที่มีชื่อยาวดังนั้นจึงเกือบจะรับประกันว่าจะเกิดการอุดตัน stdout และwaitForไม่สามารถส่งคืนได้ดังนั้นโปรแกรมจึงถูกปิดกั้น


1
บางทีฉันอาจจะหนาแน่น แต่จะไม่กลับมาในที่สุด? อาจใช้เวลาสักครู่ บางทีฉันอาจไม่ได้สิ่งที่คุณหมายถึงโดย "อุดตัน [ging] stdout"
asteri

4
หากสตรีมไม่ได้ล้างบล็อคโปรแกรมทำให้ฉันปวดหัวอยู่แล้วนั่นเป็นเหตุผลว่าทำไมฉันถึงใช้มัน; ไดเรกทอรีแบบยาวช่วยให้มั่นใจได้ว่าบัฟเฟอร์จะทำงานเต็ม
masterX244

อ้า gotcha ดี! +1
asteri

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
ไอ้เจ้าเล่ห์เจ้าไปก็ไร้เดียงสาในเรื่องนี้ :)
orion

จะใช้ vodoo แบบสุ่ม ()
masterX244

1
อ่า "2"! = 2; ได้มัน
masterX244

2
ดี "2" อาจไม่สามารถเป็น 2 แต่ถ้าคุณใช้จำนวนที่มากขึ้น (และทวีคูณของอย่างน้อย 4) มันอาจเกิดขึ้นได้)
orion

1
@orion: ใช่คุณพูดถูก และข้ามไปก็ยังคงชั่วร้าย แต่การหล่อแบบไม่ดีนั้นยิ่งร้าย!
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; int 64 บิตจะใช้เวลาจริงนานจริงๆ (585 ปีถ้าการวนซ้ำแต่ละครั้งใช้เวลาเป็นนาโนวินาที)
พอลเดรเปอร์

11

C ++

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

สไตล์การแสดงความคิดเห็นที่แปลกเป็นเคล็ดลับ คำแนะนำ: trigraphs


นี่เป็นตัวอย่างพื้นฐานของการวนซ้ำไม่สิ้นสุด
Ismael Miguel

64
Trigraphs เหล่านั้นมากจนเกินไปที่นี่ :(
TimWolla

75
ฉันเกือบรู้สึกว่า trigraphs ควรจะอยู่ใน Standard Loopholes ที่ไม่ตลกอีกต่อไป
undergroundmonorail

6
@TheDoctor: ?? / เป็น trigraph สำหรับอักขระเครื่องหมายทับขวาดังนั้นเครื่องหมายแบ็กสแลชจะประกบกันบรรทัดที่ x ถูกกำหนด 0 ถึงจุดสิ้นสุดของความคิดเห็นทำให้เป็นส่วนหนึ่งของความคิดเห็น
CasaDeRobison

4
@undergroundmonorail โพสต์
Justin

11

ชวา

ฉันชอบผลข้างเคียงของการเพิ่มประสิทธิภาพ autoboxing นี้โดยเฉพาะ:

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วัตถุจะทำหน้าที่เหมือนints ทั่วไปที่นี่ยกเว้นในกรณีเดียว: i != maxในforลูปจะเปรียบเทียบการอ้างอิง (ตัวตน) ของIntegerวัตถุไม่ใช่ค่า (ความเท่าเทียมกัน) สำหรับค่ามากถึง 100 สิ่งนี้ "ได้ผลอย่างน่าประหลาดใจ" อย่างไรก็ตามเนื่องจากการปรับให้เหมาะสมใน JVM: Java จะทำการจัดสรรIntegerวัตถุล่วงหน้าสำหรับ "ค่าที่พบบ่อยที่สุด" และนำมาใช้ซ้ำเมื่อทำการออโตบอท ดังนั้นสำหรับค่ามากถึง 100 เราจะมีตัวตน <==> ความเท่าเทียมกัน


5
ระบุว่าคน Java บางคนยังคงพิจารณาการบรรทุกเกินพิกัดของผู้ให้บริการ C + + ว่าเป็นสิ่งที่เลวร้าย ...
Daniel

คุณไม่จำเป็นต้องเริ่มต้น= new Integer(0)เนื่องจากคุณกำลังเริ่มต้นค่าหลังจากนั้น (นี่อาจทำให้เหตุผลชัดเจนน้อยลง)
Paŭlo Ebermann

@ PaŭloEbermann: จุดดีฉันได้แก้ไขรหัสแล้ว
แดเนียล

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 , นับถอยหลัง 9-1 ใน STDOUT เมื่อทำงานใน Ruby จะไม่ยุติเพราะ

0 ไม่ใช่ค่าเท็จใน Ruby


ทำภาษาในครั้งเดียว ... น่าประทับใจ
พอลเดรเปอร์

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

1
อ่าใช่แล้วมันคือ Javascript ผมจำได้เพื่อเปิดใช้งาน hilighting ไวยากรณ์ แต่ต้องลืมที่จะใส่ไว้ในชื่อมากเกินไป :)
Aleksi Torhamo

1
ฉันพบสิ่งนี้ชัดเจน :-)
rafaelcastrocouto

@rafaelcastrocouto ใช่มันเป็นเรื่องง่าย แต่ก็เป็นเรื่องง่ายที่จะพลาดเช่นเมื่อย้ายลูปจากฟังก์ชั่นหนึ่งไปยังอีกฟังก์ชั่นหนึ่งหรือเพียงแค่ดูรหัส นอกจากนี้โปรดทราบว่าวิธีนี้ใช้งานได้จริงในบางภาษารวมถึง C เนื่องจากการแชโดว์แบบผันแปร :)
Aleksi Torhamo

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);(สำหรับตารางรหัส) ในวงของคุณ
Paŭlo Ebermann

@ PaŭloEbermann: ความคิดที่ยอดเยี่ยม
RafałCieślak

ผมใช้เคล็ดลับนี้ในห้องเรียนของฉันกับตัวละครที่ไม่ได้ลงชื่อพิมพ์ระหว่าง 32 และ 128 :)
cpri

7

หลาม

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

มันควรจะเป็นและไม่ได้exit() exitอย่างที่ฉันเข้าใจมันexit()เป็นคำสั่งให้ออกจากตัวแปลหลาม ในกรณีนี้การเรียกร้องคือการเป็นตัวแทนของฟังก์ชั่นและไม่เห็นฟังก์ชั่น: ทางออกอภิปราย หรือbreakจะเป็นทางเลือกที่ดีกว่า


คุณช่วยอธิบายสิ่งที่exitเป็นจริงได้ไหม ดูเหมือนว่าจะเป็นชั้นเรียน แต่มันใช้เพื่ออะไร คุณสามารถเปลี่ยนprint mเป็นprint(m)เพื่อให้ทำงานกับ Python 3 ได้เช่นกัน
Martin Thoma

1
ผู้ที่ชนิดของสิ่งที่ ... เช่นเมื่อฉันelseifไม่ได้ทำงานเพราะมันเป็นelif
ผู้ไม่ประสงค์ออกนาม Pi

ขอบคุณ@mooseคำสั่งพิมพ์ปรับปรุงและข้อความสปอยเลอร์
วิลเล็ม

6

C ++

แล้ว C ++ แบบคลาสสิค - กับดักของโปรแกรมเมอร์คืออะไร?

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

3
นี่เป็นเหตุผลที่ใช้เงื่อนไขโยดามากขึ้น
Ryan

@RyanEdwardDougherty ฮ่าฮ่าเหมือนที่ฉันไม่เคยได้ยินพวกเขาถูกเรียก สำหรับตอนเช้าหัวเราะขอบคุณ
CompuChip

@RyanEdwardDougherty: แน่นอน== true(หรือ Yoda สไตล์true ==) while (keepGoing)เป็นซ้ำซ้อนอยู่แล้วและสภาพก็ควรอ่าน
celtschk

6

จาวาสคริ

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

ตัวแปรที่ใช้ในบรรทัดที่ 1 และ 3 นั้นแตกต่างจากที่ใช้ในบรรทัดที่ 2 และ 3
หนึ่งใช้(U + 0061) ในขณะที่คนอื่น ๆ ใช้а (U + 0430)


ฉันไม่เห็นปัญหาที่นี่ ฉันวิ่งแล้วก็ใช้งานได้ดี ฉันพลาดอะไรไป
Andrew Shepherd

สิ่งนี้จะทำงานได้ทุกที่ตั้งแต่ยูนิโค้ดอาจถูกแปลง ได้ +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
David Conrad

1
ในที่สุดนี้จะ segfault แม้ว่า
kirbyfan64sos

5

Haskell

บางรหัสเวลาการคำนวณค่าที่กำหนดของฟังก์ชัน Ackermann สำหรับค่าที่ต่ำมากมันมักจะยุติ ในเครื่องของฉันมีค่าต่ำมากหมายถึงบางอย่างเช่น 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-hs แทน lang-haskell ดูเหมือนว่าจะทำงานได้ดีขึ้น (เป็นหนึ่งในส่วนขยายในprettifier ของ Google )
Einacio

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 ที่นี่

นี่คือตัวอย่างที่โง่ของbacktracking ภัยพิบัติ ความซับซ้อนคือ 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 ++') นี่ไม่ใช่เคล็ดลับลับ ๆ ล่อๆ แต่เป็นข้อผิดพลาดที่เกิดขึ้นจริงในอดีต;) สิ่งที่ต้องระวัง


2
ปกติจะใช้เวลาอย่างน้อย 5 นาทีในการดีบัก ฉันเกลียดเมื่อฉันทำสิ่งนี้
ace_HongKongIndependence

4

C #

ต่อไปนี้เป็นคลาสแบบง่าย ๆ ที่ดำเนินการทางคณิตศาสตร์ (ผลรวม) บนอาร์เรย์อินพุตขนาดใหญ่โดยใช้เธรดพื้นหลัง ตัวอย่างโปรแกรมรวมอยู่ด้วย

อย่างไรก็ตามแม้ว่ามันจะค่อนข้างตรงไปตรงมา แต่ก็ไม่เคยยุติ โปรดทราบว่าไม่มีมือที่คล่องแคล่ว (ตัวละครตัวละครอัฒภาคซ่อน / ขาด, trigraphs ;-) ฯลฯ )

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อาจไม่สิ้นสุดจนกว่าคุณจะระบุตัวแปรเป็นสารระเหยเนื่องจากมีการแก้ไขโดยเธรดอื่น ดูคำถาม StackOverflow นี้สำหรับรายละเอียด ข้อผิดพลาดขึ้นอยู่กับการติดตั้ง. NET ดังนั้นมันอาจจะมีหรือไม่มีผลกับคุณ แต่โดยปกติแล้วการรัน build build บนตัวประมวลผล x64 ดูเหมือนจะแสดงปัญหา (ฉันลองด้วย“ csc.exe / o + / debug- infinite.cs” )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.