2011-02-14 6 views
6

주어진 코드 :FOR 루프 내부의 인덱스 변수를 수정하는 것이 좋습니다.

for (int i = 1; i <= 5; i++) 
     { 
      // Do work 
     } 

루프 내에서 i의 값을 변경할 수 있습니까? 예 :

for (int i = 1; i <= 5; i++) 
     { 
      if(i == 2) 
      { 
       i = 4; 
      } 
      // Do work 
     } 
+7

좋은 사용 사례를 제시 할 수 없다면, 어떨까요? 좋은 유스 케이스가 있다면 이야기하겠습니다.) – delnan

+0

일반적으로 나쁜 습관으로 간주됩니다.하지만 때로는 ... –

+0

나는 그 "적"이라고 생각하지 않지만 때로는 "좋은"것이 우선 순위가 아닙니다. –

답변

9

내 의견으로는, 너무 혼란 스럽다. 이 경우에는 while 루프를 사용하는 것이 더 좋습니다.

+7

동의 함, 의도적 인 것입니다. for 루프의 의도는 선언에 있고, 0에서 시작하여 42에서 끝나고 2 씩 증가합니다. 중간에 완전히 다른 것을 기대하지는 않습니다. – rene

+0

이 질문에 대한 엄격한 "올바른"대답이 있는지 나는 모른다. 어떤 이는 그것이 스타일의 문제라고 주장 할 수 있습니다. 그러나 그것이 혼란을 가중 시킨다는 것에 동의합니다. – DaveB

1

나는 그렇다고 말할 것입니다. 그러나 특정한 경우에만 말입니다.

다소 혼란 스럽습니다. i=4을 다음 반복 이전에 증가시킬 것입니까?

코드 냄새가있을 수 있습니다. 이전에 LINQ 쿼리를 수행하고 관련 요소 만 처리해야합니까?

조심해서 사용하십시오!

+0

이 질문은 기존 코드를 유지할 때 나타났습니다. 내 경우 LINQ는 옵션이 아닙니다. - 좋은 점 – DaveB

4

그러나 나는 이것을 개인적으로 피해야한다고 생각합니다. 대부분의 개발자가 예상치 못한 코드를 작성하고 있기 때문에 유지 관리가 어려운 부분이 있습니다. 이 작업을 수행해야하는 경우

개인적으로, 나는 while 루프로 전환하는 것이 좋습니다 :

int i=1; 
while (i <= 5) 
{ 
    if (i == 2) 
     i = 4; 

    ++i; 
} 

이, 적어도, 당신은 표준이 아닌 논리를 사용하는 사람들을 경고합니다. 그냥 요소를 생략하려는 경우

또는, continue를 사용

for (int i = 1; i <= 5; i++) 
{ 
    if (i == 2 || i == 3) 
     continue; 
} 

을이 기술적으로,하지만, 몇 가지 더 많은 작업을 바로 바로 i를 설정하는 것보다, 다른 개발자들에게 더 의미가됩니다 ...

+0

나는 동의한다. 나는 그것을 읽는 것을 어렵게한다고 생각하기 때문에 이것을 나의 코드에서 피한다. for 루프를 볼 때 루프 내부의 코드가 반복 될 때마다 한 번 실행될 것으로 예상됩니다. – DaveB

1

예일 수 있습니다. 가능한 엄청난 양의 상황이 있기 때문에 좋은 연습으로 간주 될 수있는 한 가지 예외가 있습니다.

그러나 이론적 인 것들을 멈추고, 나는 말할 것이다 : 아니. 하지 마.
매우 복잡하고 읽기가 쉽지 않습니다. 나는 그 중 하나도 큰 팬이 아니지만 오히려 continue 진술 같은 것을 볼 것입니다.

+0

+1 자연스럽게 for 루프의 목적을 벗어나는 것은 내게있어 그 안에있는 코드는 정해진 횟수만큼 실행되어야합니다. – DaveB

1

YES 당신은 자주 응용 프로그램에서 데이터를 구문 분석하는 것을 볼

. 예를 들어, 바이너리 파일을 스캔한다고 가정하면 기본적으로 특정 데이터 구조를 찾고 있습니다.

int SizeOfInterestingSpot = 4; 
int InterestingSpotCount = 0; 
for (int currentSpot = 0; currentSpot < endOfFile; currentSpot++) 
{ 
    if (IsInterestingPart(file[currentSpot]) 
    { 
     InterestingSpotCount++; 
     //I know that I have one of what I need ,and further, that this structure in the file takes 20 bytes, so... 
     currentSpot += SizeOfInterestingSpot-1; //Skip the rest of that structure. 

    } 
} 
+1

개인적으로, 나는 이것을 while 루프라고 이해할 수있을 것이다. –

+1

그것은 매우 좋을지도 모른다; 하지만 나는 FOR 루프로 잘못되었거나 잘못 생각하지 않습니다. – GWLlosa

+0

작성된대로, 이것은 off-by-one 오류를 일으킬 것입니다 ("흥미로운 지점"을 건너 뛰고 나서 다음 반복을 너무 멀리 시작합니다). 아이러니 컬하게도, 당신은 왜 이런 식으로 for를 사용하는 것이 위험한 것인지 설명해주었습니다. – zinglon

0

페 타르 Minchev을 인용 : 나는 다음을 수행하는 코드있을 수 있습니다 제 생각에는

을, 너무 혼란 스럽다. 그런 경우에는 while 루프를 사용하는 것이 더 좋습니다.

그리고 그들은 색인을 기준으로했을 때, 당신은 무한 루프, 조기-취소 루프, 이상한 변수 값 또는 수학으로 일어날 수있는 몇 가지, 알고 있어야합니다 그 작업을 수행하여 말할 것입니다, 주로 (다른 것들을 제외하지 않음) 실행 루프 문제는 인덱스 및 장애 루프에 의해 수정 된 다른 변수에 기반합니다.

하지만 그런 경우가 있으면 가져 가십시오.

3

예는 어떤 기준과 일치하는 항목 삭제 될 것이다 : 그러나 더 나은 아이디어가 사용 반복자

for (int i = 0; i < array.size(); /*nothing*/) 
{ 
    if (pred(array[i])) 
     i++; 
    else 
     array.erase(array.begin() + i); 
} 

이 될 것입니다 :

for (auto it = array.begin(); it != array.end(); /*nothing*/) 
{ 
    if (pred(*it)) 
     ++it; 
    else 
     it = array.erase(it); 
} 

편집
죄송 오, 코드는 C++이고 질문은 C#에 관한 것입니다. 그러나 그럼에도 불구하고 생각은 동일합니다

for (int i = 0; i < list.Length; /*nothing*/) 
{ 
    if (pred(list[i])) 
     i++; 
    else 
     list.RemoveAt(i); 
} 

그리고 더 나은 아이디어는 여기에 단지

list.RemoveAll(x => !pred(x)); 

또는 약간 더 현대적인 스타일

,

list = list.Where(pred); 

(list가해야 물론 수 있습니다 be IEnumerable<...>)

1

예는 for 특정 조건에서 현재 반복을 반복하거나 이전 반복으로 돌아가거나 (continue의 숫자가 아닌) 반복 반복을 건너 뛰기를 원할 때 반복하십시오.

하지만 이러한 경우는 거의 없습니다. 이러한 경우에도 for 루프는 while, do 및 기타 사용할 수있는 도구 중 하나 일뿐입니다. 이것을 나쁜 습관이라고 생각하고 피하기 위해 노력하십시오. 당신의 코드는 그렇게 쉽게 읽을 수 없을 것입니다.

결론에 대한 그래서

: 그것은 (A foreach에없는) 달성이다하지만 대신 whiledo 등을 사용하여이을 피하기 위해 노력하고 있습니다.

1

개인적으로 알고리즘의 논리가 정상적으로 선형으로 반복되는 동작을 요구하지만 특정 반복을 건너 뛰거나 반복하는 경우 개인적으로 생각해 보겠습니다. 그러나 나는 또한 대부분의 사람들이 이것이 일상적이지 않은 루프 사용에 동의한다. 그래서 나는 신발에 있었고, 나는 이것이 일어나는 이유를 설명하는 한 줄 또는 두 줄의 주석을 던지도록했다.

이런 경우에 완벽하게 유효한 유스 케이스는 로마 숫자 문자열을 구문 분석하는 것일 수 있습니다. 문자열의 각 문자 인덱스에 대해 해당 문자와 ​​그 다음 문자를 살펴보십시오. 다음 문자의 숫자 값이 현재 문자보다 큰 경우 현재 문자의 값을 다음 문자에서 뺀 다음 결과를 합계에 더하고 현재 색인을 증가시켜 다음 문자를 건너 뜁니다. 그렇지 않으면, 현재 문자의 값을 누적 합계에 더하고 계속 진행하면됩니다.

관련 문제