2009-06-02 4 views
7

그래서 BFS 알고리즘에서 노드를 추적하는 C++ 코드가 있습니다. 그것은 조금 다음과 같습니다 그러나무한 루프가 무한 루프입니까?

typedef std::map<int> MapType; 
bool IsValuePresent(const MapType& myMap, int beginVal, int searchVal) 
{ 
    int current_val = beginVal; 
    while (true) 
    { 
     if (current_val == searchVal) 
      return true; 

     MapType::iterator it = myMap.find(current_val); 
     assert(current_val != myMap.end()); 
     if (current_val == it->second) // end of the line 
      return false; 
     current_val = it->second; 
    } 
} 

while (true) 나에게 의심 ... 보인다. 나는이 코드가 작동한다는 것을 알고 있으며 논리적으로 그것이 작동해야한다는 것을 알고있다. 그러나 while에 몇 가지 조건이 있어야한다는 느낌을 떨칠 수는 없지만 실제로 가능한 유일한 방법은 bool 변수를 사용하여 완료했는지 여부입니다. 걱정하지 말아야할까요? 아니면 정말 나쁜 형태입니다.

편집 :이 문제를 해결할 수있는 방법이 있다는 것을 알아 주셔서 감사합니다. 그러나, 나는 아직도 다른 유효한 경우가 있는지 알고 싶다.

+0

이 또한 여기에 약간 논의되었다. http://stackoverflow.com/questions/885908/ – Copas

+0

잘 모르겠습니다. 무한 루프가 나쁜 형태입니까? –

답변

22

나는 겉으로보기에는 무한 루프가 존재하는 것이 괜찮은 경우가 있다고 생각합니다. 그러나 이것은 그들 중 하나 인 것처럼 보이지 않습니다. 다음과 같이 그냥 간단하게 코드를 작성할 수처럼 보인다

이 루프의 진정한 의도를 표현하는 것
while (current_val != searchVal) { 
    MapType::iterator it = myMap.find(current_val); 
    assert(current_val != myMap.end()); 
    if (current_val == it->second) // end of the line 
     return false; 
    current_val = it->second 
} 
return true; 

더 나은

+5

+1 명확한 의도와 기능을 표현하기 위해서. –

+0

당신은 여전히 ​​current_val을 map.begin()으로 초기화하고 while 조건에 추가하여 (... && current_val! = it-> second) 어쩌면 do-while으로 변환 할 수도 있습니다. – stefanB

+0

동의. 이것은 읽기가 쉽고 결과적으로 실수가 덜 발생합니다. 무한 루프에 대한 또 다른 생각 - 진정으로 "무한한"행동을하는 경향이 있다면 코드에서 어떤 종류의 탈출구를 설계하는 것이 좋지 않을 때가 있습니다. 그것은 사용자 입력 (사용자 히트 탈출)을 검사하는 형태이거나 사전 정의 된 시간 초과 후에 중지하는 다른 상황 일 수 있습니다. –

0

음, 무한 루프 도움이 될 정말 아니라고 말하는 코멘트 :

while (true) // Not really an infinite loop! Guaranteed to return. 

나는이 조건을 가져야한다고 동의하지만,이 어떤 상황에서 괜찮습니다 (그리고 항상 가능하지 또는 조건을 만들기 쉽다).

+0

참조가 어떻게 든 체인의 시작 부분 근처에있는 어떤 곳으로의 참조를 얻으면, 그것은 영원히 반복 될 것입니다. 이것은 '무한 루프'버전과 JaredPar가 만든 버전 모두에 해당됩니다. 그러나, 그의 버전은 실제로 당신이하지 않는 조건부에 루프 의도를 보여줍니다. – DevinB

+0

예! 의견은 항상 그 문제를 해결합니다. –

+0

그건 꽤 쓸모없는 의견입니다. 그것은 그것이 어떤 조건으로 반환되는지 아무 것도 말해주지 않습니다. 좋은 설명은이 복잡한 괄호 안의 집합에 너무 복잡하게 맞추기에는 너무 복잡한 특정 조건 집합에서 반환 한 다음 조건을 나열하는 것일 수 있습니다. 물론, 당신이 분명히 논평한다면, 첫 번째 경우에서 명확하게 CODE를 나타낼 수도 있습니다 (일반적으로 그렇습니다). –

6

는 무한 루프에 대한 시간과 장소가있다 -이는 확신하지 않다 그들 중 하나. 다른 한편으로, 여기에 심각한 문제가되는 것은 아닙니다. 프로세스가 진정으로 무기한 때 사용할 수있는

while (currentVal != searchVal) 
{ 
    ... 
} 
return true; 

한 장소입니다 - 종료되지 않습니다 모니터 루프와 데몬 프로세스.

+0

데몬을 종료하려면 어떻게합니까? –

+0

다양하게 선택할 수 있습니다 - 그렇지 않으면 무한 루프에서 벗어나거나 돌아 오지 않는 이탈과 같은 함수를 호출하십시오. 둘 다 효과적입니다. –

+0

내가 말하길 '어느 쪽이든 (또는 돌아 오는) 말을해야한다고 생각한다.' –

5

이 같은 구조를 의미한다 상황이있다 : 브레이크 조건이 루프 내 계산

  1. 더 파괴 조건이 있습니다 그리고 그들은 모든
  2. 당신이 정말 원하는 똑같이 중요 무한 루프;) ..
0

걱정하지 마세요. 코드의 논리를 간소화하고 유지 보수성과 가독성을 향상시키는 데 도움이된다면 이는 나쁜 형식이 아닙니다. 예상되는 종료 조건에 대한 설명과 알고리즘이 무한 루프로 빠지지 않는 이유에 대해 설명하는 것이 좋습니다.

+0

JaredPar가 보여 주었 듯이 실제로 논리를 단순화하지는 않습니다. 제가 말했듯이, 그것을 문서화하는 것은 확실히 좋은 생각입니다. – Zifre

0

음, ,하지만 당신은 당신이 당신의 메인 루프가 while(true) 같은 없도록하려면 작성해야 할 코드의 두 페이지도 악화 형태이다.

1

전에도 해 보았지만, 일반적으로 while 루프에서 유효한 표현식을 포함하는 읽기 쉬운 것을 사용하여 더 명확한 해결책을 찾으려고 노력했습니다. 그렇지 않으면 코드를 검색하고 있습니다. 휴식을 찾으십시오.

나는 그 (것)들에 관하여 진짜로 두려워하지 않는다, 그러나 나는 어떤 사람들이다는 것을 알고있다.

13

내 두 센트는 다음과 같습니다. 코드는 self-documenting이어야합니다. 즉, 코드 조각이 주어지면 필자는 프로그래머의 의도를보고 둘러보고 주석을 읽거나 주변 코드를 거쳐야한다고 말할 수 있습니다. 내가 읽을 때 :

while(true) 

그것은 프로그래머가 무한 루프를 원한다는 것을 말해 준다. 최종 조건을 지정할 수 없음을 나타냅니다. 이것은 일부 상황에서 프로그래머의 의도입니다. 예를 들어 서버 루프, 그리고이를 사용해야 할 때입니다. 위의 코드에서

은, 루프가 영원히하는 것은 아닙니다, 그것은 분명한 끝 조건을 가지고 있으며, 다른 사람들이 지적으로 순서에 의미 명확하기 :

while (currentVal != searchVal) 

작품 때문에, while (true)은 분명히 열등하므로이 경우에는 피해야합니다.

4

while(true) 게임은 메인 게임 루프를 위해 게임에서 사용됩니다. 게임은 플레이어 입력을 계속 읽고, 개체 간의 상호 작용을 처리하고 화면을 페인트 한 다음 반복합니다. 이 루프는 다른 루프가 빠져 나갈 때까지 무한히 계속됩니다 (게임을 종료하고 레벨 완료).

퀘이크 1 소스 코드에서이 메인 루프를 신속하게 찾으려고했지만 적어도 'while(1)'이 50 번이나 'for(;;)'으로 기록되어 있었지만 즉시 확신 할 수 없었습니다. 어느 것이 게임의 주요 루프였습니다.

+0

이것이 정말 좋은 예가 아닌가하는 의문이 생깁니다. (사실) ... 내 말은, 돌아 오지 않는 경우에만 사용하면 게임 루프인지 알 수 있습니다. 더 나은 아직, 그 중 하나가 말한 (실행) 동안, 당신은 진짜 루프를 알고 있고 당신이 프로그래머에게 정확하게 당신이 멈추길 기대하고있다 (그렇지 않으면 브레이크? return? exit입니까? 어느 쪽이 올바른 셧다운 절차를 실행 시킬까?) –

+0

내가 본 또는 쓰는 대부분의 게임 루프는'while (! Exiting) {...}' – Zifre

+0

'while (running)'과 같이 보였을 것이다. CPU주기 낭비 - '실행 중'변수를 확인하면 1 ~ 2 사이클이 낭비되며, RAM에서 읽는 것을 기다리는 데 더 많은 시간이 낭비됩니다. –

5

이 경우 무한 루프가 필요 없다는 다른 답변에 동의합니다.

그러나 다른 점은 일 때에 무한 반복이있는 경우 for(;;)이 더 좋은 표현 일 수 있습니다. 일부 컴파일러에서는 while(true)에 대한 경고를 생성하며 (조건은 항상 false로 평가 됨) 다른 루프처럼 보이기 때문에 의도가 명확하지 않습니다. 아마도 while (x == true)이라고 말하고 true 대신 x을 실수로 삭제했을 수 있습니다. for(;;)은 이것이 무한 루프로 의도되어 있음을 분명히 말합니다. 또는 while(t)과 같은 것을 쓰려고했지만 IDE의 Intellisense가 실행되어서 true으로 자동 완성되기로 결정했습니다. 다른 한편으로는 실수로 입력 한 것이 아닙니다.

for(;;)

어느 버전 잘못된 (그리고 그것은 동안 (사실)도 (1) ​​동안과 같이 쓸 수 있습니다. 검색하기 쉽게)하지만 없는 루프 조건이 있기 때문에 for(;;) 더 직관적 수 있습니다.

+0

+1 for for (;;) and while (true) – pierrotlefou

0

그것은 임베디드 시스템 코드에서 무한 루프를 찾을 드문 일이 아니다 - 자주, 유한 상태 기계를 주변 등 주변 칩과 장치를 확인

0

나는 유한 상태 기계의 외부 제어 구조로 무한 루프를 사랑 해요. 그것은 효과적으로 구조화 고토의 :

for (;;) { 
    int c = ReadInput(); 
    if (c == EOF) 
     return kEOF; 

    switch (state) { 
    case inNumber: state = HandleNumber(c); break; 
    case inToken: state = HandleToken(c); break; 
    case inWhiteSpace: state = HandleWhiteSpace(c); 
    default: 
     state = inError; 
     break; 
    } 
    if (state == inError) ThrowError(); 

}

+0

이것은 여전히 ​​while ((int c = ReadInput())! = EOF) {..}' – Erbureth

+0

과 같이되어야합니다. c가 루프 범위를 벗어나거나 EOF와 오류를 구분할 수 없습니다. 튼튼한 루프 구조는 항상 당신의 친구가 아닙니다. – plinth

관련 문제