왜 끝나지 않습니까? [닫은]


95

당신의 작업 : 분명히 종료해야하지만 결코 (컴퓨터 충돌의 한도) 결코 끝나지 않는 프로그램을 작성하는 것. 숫자를 추가하고, 무언가를 인쇄하는 등 간단한 작업을 수행해야하는 것처럼 보이게하십시오. 그러나 그것은 무한 루프에 빠지게됩니다.

실제로 예상치 못한 루프에 빠지는 동안 프로그램을 매우 명확하고 간단하게 만드십시오. 유권자 : 그들이 어떻게 "손이 닿았는지"에 대한 답을 판단하십시오!

이것은 인기 콘테스트입니다 : 창의력을 발휘하십시오!


6
질문의 폭을 좁히기 위해 내가 무엇을 할 수 있는지 설명해 주시겠습니까? 나 여기 처음이야. 감사합니다!
Number9

6
이것은 루프를 일으키는 오타와 초보자의 실수의 큰 목록이 될 것입니다.
Bill Woodger

흥미로운 질문이지만 아직 창의적인 답은 아직 보지 못했습니다. 루프 나 명백한 재귀를 사용하지 않는 사람에게 투표를 약속합니다!
ApproachingDarknessFish

14
이것이 중요한지 모르겠지만 Microsoft Office는 현재 이와 똑같이 동작합니다.
Level River St

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
Kubuntu의 Chrome이 응답하지 않고 모든 것을 중단했으며 하드 리셋해야했습니다. :)
Sergey Telshevsky

4
@Vlakarados : Python은 Javascript가 수행하는 암시 적 유형 변환을 수행하지 않습니다. Python에서 raw_input또는 Python 3 input을 사용하는 해당 코드 는 a를 발생 TypeError시킵니다.
user2357112

2
값이 실제로 100 미만임을 확인하지 않으므로 "100"을 입력하면 정상적으로 중지됩니다
.'-

1
@Sankalp, +여기 의 연산자는 문자열 연결입니다.
Michael M.

87

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 루프는 여는 중괄호 앞에 "do"가 없습니다. 이것은 실제로 "x <10) 루프 안에 do-while 루프를 생성하고 다음"null 문 "while 루프로 종료됩니다. 루프 내부에서 x가 증가한 다음 do-while 루프 상태에서 감소하기 때문에 내부 루프는 종료되지 않으므로 외부 루프도 종료되지 않습니다. 끝에있는 "단일 문"루프에는 도달하지 않습니다.

여전히 혼란 스럽다면 여기를보십시오 (codegolf.SE는 스포일러의 코드 블록을 좋아하지 않기 때문에 외부에서 호스팅됩니다).


8
Haha, 나는 솔루션 스포일러를보기 전에 이것을 알아 냈습니다. : P
Joe Z.

54
"goes to"연산자를 사용할 수있는 훌륭한 기회를 왜 포기 했습니까? (x --> 0)
corsiKa

2
오 와우. 이것은 엄청나게 악하다. 그것을 찾기 위해 네 개의 책을 읽었습니다.
Patrick M

1
@JoeZ. 너무 쉬운 방법입니다. 가장 많이지지 된 솔루션이 더 좋습니다. 내가 찾지 못한 것.
익명 Pi

3
@Hat Guy, Bash는 for; do and while; do 구문을 사용하여 사람들이 C / C ++가 아닌 언어에 익숙하더라도 이것에 의해 던져지는 것을 볼 수 있습니다. tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
nemec

85

자바 스크립트

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

변수 게양 : JavaScript는 실제로의 두 번째 정의를 가져 와서 var a = true;함수 맨 위에로 선언 하고 while 루프에 들어갈 때 정의되지 않은 의미로 var a;내 할당을 수정 합니다.a = true;a


3
왜 이것이 끝나지 않는지 더 잘 설명해 주시겠습니까? "가변 호이 스팅"에 대해 깊이 들어가십시오 :)
Number9

1
@ Number9 도움이 되길 바랍니다. 구글이 이것보다 훨씬 더 좋은 예를 가지고 있습니다.)
Newbrict

25
이런 젠장, 세미콜론 삽입보다 더 나쁘다. +1!
tomsmeding

2
이 프로그램에서 볼 수있는 유일한 문제는 간단한 작업을 수행하는 것처럼 보이지 않는다는 것입니다 ... 본질적으로 아무것도하지 않아야하는 것처럼 보입니다. 어쩌면 alert루프를 추가하십시오 .
PeterT

2
로 변경해야 a = 1합니다 a = true. 코드에는 여전히 무한 루프가 있지만, 이유는 int에서 부울로 JavaScript를 변환하는 데 어려움이 없다는 것이 분명합니다.
Rory O'Kane

49

씨#

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! 내가 바보. : \
Joe Z.

6
개선을위한 제안 : 예상 출력 섹션의 1을 ls로 교체하십시오 (실제 1을 비교할 때 이상한 문자를 발견하는 것이 더 쉽습니다)
Allen Gould

3
예, 환경에 따라 상당히 다릅니다. @Michael 의 글꼴은 내 가정용 컴퓨터 ( imgur.com/PKIuJpr-Chrome , Windows 8) 의 글꼴과 매우 다르게 보이며 트릭은 가정용 컴퓨터보다 내 컴퓨터보다 더 잘 작동하는 것 같습니다. 명세서. 휴대 전화의 브라우저가 고정 된 글꼴로 코드를 표시하지 않는 것 같습니다. 트릭이 전혀 작동하지 않습니다.
BenM

1
FTR, 내 업무용 컴퓨터 ( imgur.com/Opfs3BH-Firefox , Windows 7) 에서 다음과 같이 보입니다 . 나는 심지어 사람들을 아주 멍청하게 속일 수 있다고 생각합니다.
BenM

15
사람들이 왜 같은 인물을 쫓아 버리는가?
익명 Pi

39

정밀도는 어떻습니까?

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

컴퓨터 메모리에 정수 범위 <0; 3>을 저장해야한다고 상상해보십시오. 이 범위 (0,1,2,3)에는 4 개의 정수만 있습니다. 메모리에 2 비트를 저장하면 충분합니다. 이제 다양한 부동 소수점 숫자 <0; 3>을 저장해야한다고 상상해보십시오. 문제는이 범위에 무한한 부동 소수점 숫자가 있다는 것입니다. 무한대의 숫자를 저장하는 방법? 불가능하다. 한정된 수의 숫자 만 저장할 수 있습니다. 이것이 0.1과 같은 일부 숫자가 실제로 다른 이유입니다. 0.1의 경우 0.100000000000000006입니다. 부동 소수점 숫자를 사용하는 조건에서는 == 또는! =를 사용하지 않는 것이 좋습니다.


1
어떻게 작동합니까?
Mhmd

5
반올림 오류. 바이너리의 0.1은 10의 1/3과 같기 때문에 0.1은 실제로 0.100000000000000006입니다. 바이너리 확장은 무한대입니다.
오리온

3
실제로 반올림 오류는 아닙니다. 부동 소수점 값은 숫자의 대략적인 표현입니다. 대략적인 값을 정확하게 비교하는 것은 효과가 없습니다.
AKHolland

4
이것이 플로트 / 더블을 평등에 대해 비교하지 않아야하는 이유입니다.
Emanuel Landeholm 5

1
나는 이것을보기 위해 기다리고 있었다. 좋은.
David Conrad

33

HTML / 자바 스크립트

페이지에 입력 상자가 있다고 상상해보십시오.

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

그리고 지금 당신은 그것에 무언가를 입력하고 싶습니다 ... Chrome에서 시도하십시오 : http://jsfiddle.net/jZp4X/ .

alertfunction으로 호출 된 표준 브라우저 대화 상자 는 모달이므로 표시되면 텍스트 상자에서 포커스를 가져 오지만 닫으면 텍스트 상자가 포커스를 다시받습니다.


5
파이어 폭스에서 입력은 경고 닫기에 자동 초점을 갖지 않으며 두 번째부터 더 이상 경고를 표시하지 않으면 텍스트 상자에 정상적으로 쓸 수 있습니다.
Einacio

6
좋은데 루프 나 재귀가 없으면 +1입니다.
ApproachingDarknessFish

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 >=0size_t가 부호가 없으므로 조건 은 항상 참입니다.


2
좋은 점이지만 컴파일러는 일반적으로 이것에 대한 경고를 출력합니다.)
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]}

문자열 'yes'를 foo [2]에 할당하는 대신 시스템 명령을 호출하여 yesfoo [2]를 끝없는 "yes \ n"으로 채 웁니다.


결국 bash메모리가 부족하여 충돌이 발생합니다
Digital Trauma

4
그렇습니다. 그러나 충돌은 다음과 같은 질문에 의해 허용되었습니다 :)
GreenAsJade

네, 단지 관찰 :). 공감.
Digital Trauma

실제로, 나는 당신의 기계 나 다른 서비스 거부에 실제로
영향을 미치는

수정 : yes핵심 유틸리티 프로그램입니다. syscall이 아닙니다.
mniip

28

파일에서 문자 "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 ()에 의해 int와 50으로 확장됩니다. 그런 다음 다시 char로 변환하고 여전히 50을 갖습니다. -1 또는 fgetc ()에서 나오는 다른 출력에서도 마찬가지입니다.
그러나 서명되지 않은 문자를 사용하면 어떻게되는지보십시오. fgetc ()에서 char로 시작하여 int로 확장 한 다음 서명되지 않은 char을 원합니다. 유일한 문제는 부호없는 char에서 -1을 유지할 수 없다는 것입니다. 프로그램이 더 이상 EOF와 같지 않은 255로 저장합니다.

경고
ANSI C 문서의 사본 에서 3.1.2.5 유형을 살펴보면 char이 서명되었는지 여부는 전적으로 구현에 달려 있다는 것을 알 수 있습니다. 따라서 코드에 숨어있는 매우 까다로운 버그를 발견했을 때 아마도 그 사람은 약탈해서는 안됩니다. 컴파일러를 변경하거나 다른 아키텍처로 이동할 때 나올 수 있습니다. 그런 경우에 버그가 나면 누가 해고 될지 궁금합니다.)

추신. 프로그램은 Paul A. Carter가 PC Assembly Language에서 언급 한 버그를 중심으로 구축되었습니다.


7
나는 해결책에 대한 이야기가 있다는 것을 좋아합니다.
jpmc26

하하! 나는 그것이 유일한 것 같아요. 읽어 주셔서 감사합니다!
Legat

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
나는 정규식 엔진을 역 추적하는 것을 싫어한다.
David Conrad

2
나는 이것을 Perl로 먼저 시도했지만 Perl은 여기서 루프를 알 수 있습니다. 정규 표현식이 AWK에서 이러한 동작을 유발할 수 없기 때문에 AWK를 시도하지 않았습니다. PHP는 자동으로 정규 표현식을 작성하여 실패와 일치하는 데 너무 오래 걸립니다 (어리석지 만 PHP는 자동으로 프로그램에 버그를 삽입합니다). 그러나 실제로는 파이썬에서 작동합니다.
Konrad Borowski

1
@ xfix : Perl 역 추적을 피할 수 있었던 이유에 대해서는 이 기사에서 설명합니다. 그러나 여기에 표시된 것처럼 경우 에 비해 충분하지 않습니다 (성능 섹션으로 스크롤). PHP (실제로 PCRE 라이브러리)에는 역 추적 한계가 있으며 적절한 프로그램은 항상 함수의 반환 값을 확인하여 실행이 중지되었는지 또는 완료되었는지를 결정해야합니다.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
너무 매끄 럽습니다.
alvonellos

20

자바 스크립트

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

050은 Javascript에서 8 진 상수이며 10 진수 값은 40입니다.


73
나는 이것이 명백한 것을 안다. :-)
저스틴

6
나는 자바 스크립트가 이것을하는 것을 몰랐다. 그러나 코드를 읽은 후 : "050은 40을 표현할 수있는 방법이되어야합니다. 아마도 8을베이스로하거나 무언가를 정의해야합니다"
Cruncher

더 잘 숨겨져 야합니다.
Paŭlo Ebermann

명백하다 ..
Oliver Ni

18

하스켈

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

생각 해봐! 그것과 같을 것이다 head $ "Hello" ++ (repeat '!'), 즉 그냥 돌아 가야한다 'H'.

하스켈 목록에는 재귀 구조가 있으며 첫 번째 요소가 최상위 요소입니다. 목록에 추가하려면 해당 요소를 모두 풀고 부록을 놓고 들어 올린 요소를 다시 넣어야합니다. 그것은 무한한 목록에서 작동하지 않을 것입니다. 마찬가지로, 무한 목록을 "Hello"되돌 리더라도 마술처럼 등을 돌려 주지 않습니다 . 영원히 걸려요.


1
너무 나쁘게 이것은 실제로 작동하지 않습니다 :-/
John Dvorak

1
어떻게 작동하지 않습니까?
danmcardle

Fedora에서 이것을 테스트했을 때 @crazedgremlin은 결국 프로세스를 죽였습니다. (<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"이 무슨 뜻인지 모르겠습니다.
asteri

4
스트림이 프로그램 블록을 비우지 않으면 두통이 발생하여 이미 사용했습니다. 긴 디렉토리는 버퍼가 완전히 실행되도록 보장합니다
masterX244

아. 좋은! +1
asteri

15

사과와 오렌지를 비교하려면 ...

내가 여기를 사용하여 코드의 어떤 부분이 없음을 감동 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

부두가 사용한 random ()은 무엇입니까?
masterX244

1
ahh, "2"! = 2; 도착
masterX244

2
"2"는 2가 될 수는 없지만 더 큰 숫자 (및 4 이상의 배수)를 사용하면 발생할 수 있습니다.)
orion

1
@ orion : 네, 그렇습니다. 그리고 goto는 여전히 악하지만 나쁜 유형의 캐스팅은 더 악합니다!
최대 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

11

C ++

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

이상한 주석 스타일이 트릭입니다. 힌트 : 3 부작.


이것은 무한 루프의 너무 기본적인 예입니다.
Ismael Miguel

64
그 Trigraphs는 여기
너무

75
나는 더 이상 재미 있지 않은 표준 허점에 trigraphs를 넣어야한다고 생각합니다.
undergroundmonorail

6
@TheDoctor : ?? /는 백 슬래시 문자에 대한 삼중 그래프이므로 백 슬래시는 x가 주석의 끝에 0이 할당 된 행을 스 플라이 싱하여 주석의 일부로 만듭니다.
CasaDeRobison

4
@undergroundmonorail 게시
Justin

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한 가지를 제외하고, 여기의 다음 i != maxfor루프는 비교 참조 의 (정체성) Integer개체를하지 가치 (평등). 그럼에도 불구하고 최대 100까지의 값은 JVM의 최적화로 인해 놀랍게도 "작동"합니다. Java Integer는 "가장 일반적인 값"에 대한 객체를 사전 할당 하고 오토 박싱시 재사용합니다. 따라서 최대 100까지의 값은 동일성 <==> 항등입니다.


5
일부 Java 사용자는 여전히 C ++ 연산자 오버로드를 하다고 생각합니다 .
Daniel

= new Integer(0)나중에 값을 초기화하므로 초기화가 필요하지 않습니다 . (이는 그 이유를 덜 분명하게 만들 수 있습니다.)
Paŭlo Ebermann

@ 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에서 실행될 때 종료되지 않습니다.

Ruby에서는 0이 잘못된 값이 아닙니다.


한 번에 언어를 수행하십시오 ... 인상적입니다.
Paul Draper

7

자바 스크립트

// 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
아, 그렇습니다. 자바 스크립트입니다. 나는 구문 강조를 활성화하는 것을 기억했지만 제목에 넣어야한다는 것을 잊어야했다.)
Aleksi Torhamo

1
나는 이것이 명백한 것을 안다. :-)
rafaelcastrocouto

@rafaelcastrocouto 예, 일종의 기능이지만 루프를 하나의 함수에서 다른 함수로 이동하거나 코드를 살펴볼 때처럼 놓치기 쉽습니다. 또한 변수 섀도 잉으로 인해 C를 포함한 일부 언어에서는 실제로 올바르게 작동합니다. :)
Aleksi Torhamo

7

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);루프에서 (코드 테이블의 경우) 와 같은 것을 사용 하십시오.
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()파이썬 인터프리터를 종료하는 명령입니다. 이 경우 호출은 함수가 아닌 함수의 표현입니다. exit-discussion을 참조하십시오 . 또는 break더 나은 선택이 될 것입니다.


exit실제로 무엇인지 설명해 주 시겠습니까? 클래스 인 것 같지만 무엇을 위해 사용됩니까? 당신은 또한 변경 될 수 있습니다 print mprint(m)이 또한 파이썬 (3)와 함께 작동하도록
마틴 토마스

1
일의 그 종류는 ...처럼 내 경우 ELSEIF는 이 때문에 작동하지 않았다 ELIF .
Anonymous Pi

감사합니다 @moose업데이트 된 인쇄물 진술과 스포일러 메시지
Willem

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 Haha는 그런 전화를 한 적이 없습니다. 아침 웃음 감사합니다.
CompuChip

@RyanEdwardDougherty : 물론 == true(또는 Yoda 스타일 true ==)은 중복되며 조건은 단순히을 읽어야 while (keepGoing)합니다.
celtschk

6

자바 스크립트

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

첫 번째 및 세 번째 줄에 사용 된 변수는 두 번째 및 세 번째 줄에 사용 된 변수와 다릅니다.
하나는 사용 (U + 0061)을, 다른 하나는 사용하는 반면 а을 (+ 0430 U)


여기서 문제가 보이지 않습니다. 나는 그것을 실행했고 잘 작동했다. 내가 무엇을 놓치고 있습니까?
앤드류 셰퍼드

유니 코드가 아마도 변환 될 것이므로 이것은 아마도 모든 곳에서 작동 할 것입니다. 당신이 얻을 수있는 가장 보이지 않기 때문에 +1있어!
rafaelcastrocouto

완전히 숨기려면 (á + U로 대체하십시오.)이 코드라면 문제를 찾는 행운을 빕니다 : 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

자바:

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

하스켈

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-haskell 대신 lang-hs로 표시하면 더 잘 작동하는 것 같습니다 ( 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!");
     }
}

내가 뭘 잘못 했니? 왜 내 프로그램이 끝나지 않습니까? 도와주세요!

여기 링크가 있습니다 .

이것은 치명적인 역 추적 의 어리석은 예입니다 . 복잡도는 O (2 n / 2 )입니다. 이 프로그램은 무기한으로 실행되지 않을 수 있지만, 주변에 있거나 살아 있지 않은 개체 와 주변에 존재 하지 않는 개체 보다 오래 지속될 수 있습니다 .


5

두 개의 루프 중 하나만 필요하지만 필요한 것은 컴파일러에 따라 다릅니다.

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

씨#

다음은 백그라운드 스레드를 사용하여 큰 입력 배열에서 산술 연산 (합계)을 수행하는 간단한 클래스입니다. 샘플 프로그램이 포함되어 있습니다.

그러나 매우 간단하지만 종료되지 않습니다. 손이 얇지 않습니다 (캐릭터 모양, 세미콜론 / 숨겨진 세미콜론, ;-) 등).

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 구현에 따라 다르므로 영향을 줄 수 있습니다. 그러나 일반적으로 x64 프로세서에서 릴리스 빌드를 실행하면 문제가 표시되는 것 같습니다. ( “csc.exe / o + / debug- infinite.cs”사용 하여 시도했습니다 .)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.