Programing

C ++ for 루프 전에는 본 적이 없다

lottogame 2020. 5. 31. 09:54
반응형

C ++ for 루프 전에는 본 적이 없다


C ++ 알고리즘을 C #으로 변환하고있었습니다. 이 for 루프를 발견했습니다.

for (u = b.size(), v = b.back(); u--; v = p[v]) 
b[u] = v;

C ++에서는 오류가 없지만 C #에서는 수행합니다 (int를 bool로 변환 할 수 없음). 나는 이것이 for 루프를 알아낼 수 없다. 조건은 어디에 있습니까?

누군가 설명해 주시겠습니까?

추신. 확인하기 위해 VECTOR를 LIST에 적용하려면 b.back ()이 b [b.Count-1]에 해당합니까?


for루프 상태 는 두 세미콜론 사이의 중간에 ;있습니다.

C ++에서는 거의 모든 표현식을 조건으로 두는 것이 좋습니다. 0으로 평가되는 것은 의미입니다 false. 0이 아닌 의미 true.

귀하의 경우 조건은 u--: C #으로 변환 할 때 간단히 추가하십시오 != 0.

for (u = b.size(), v = b.back(); u-- != 0; v = p[v]) 
    b[u] = v; //                     ^^^^ HERE

많은 정확한 답변이 있지만 동등한 while 루프를 작성하는 것이 좋습니다.

for (u = b.size(), v = b.back(); u--; v = p[v]) 
   b[u] = v;

다음과 같습니다.

u = b.size();
v = b.back();
while(u--) {
   b[u] = v;
   v = p[v];
}

C #으로 변환 할 때 while () 형식으로 리팩토링을 고려할 수 있습니다. 내 생각에 그것은 새 프로그래머에게는 더 명확하고 덜 함정이며 똑같이 효율적입니다.

다른 사람들이 지적했지만 (내 대답을 완성시키기 위해) C #에서 작동하게하려면로 변경 while(u--)해야 while(u-- != 0)합니다.

... 또는 while(u-- >0)u가 음수로 시작하는 경우. (좋아, b.size()절대 부정적인 것은 아니지만 아마도 다른 것이 u를 초기화 한 일반적인 경우를 고려하십시오).

또는 더 명확하게하기 위해 :

u = b.size();
v = b.back();
while(u>0) {
   u--;
   b[u] = v;
   v = p[v];
}

간결한 것보다 명확하게하는 것이 좋습니다.


조건은 for 명령 u--;의 두 번째 위치에 있기 때문에입니다 .

의 값이 u--;0과 다른 true경우이 값 (즉, boolean value로 암시 적으로 캐스트 됨) 으로 해석됩니다 true. 대신 값이 0이면로 캐스팅됩니다 false.

이것은 매우 나쁜 코드 입니다.

업데이트 :블로그 게시물 에서 "for"루프 작성에 대해 논의 했습니다 . 권장 사항은 다음 단락에 요약되어 있습니다.

for 루프는 실용적이고 읽기 쉽고 (한 번 익숙해지면) 간결한 구성이지만 잘 사용해야합니다. 흔하지 않은 구문으로 인해 너무 상상적인 방식으로 사용하는 것은 좋은 생각이 아닙니다.

for 루프의 모든 부분은 짧고 읽을 수 있어야합니다. 이해하기 쉽도록 변수 이름을 선택해야합니다.

이 예는 이러한 권장 사항을 분명히 위반합니다.


이것이 루프의 C # 형식입니다.

// back fetches the last element of vector in c++.
for (u = b.size(), v = b.back(); (u--) != 0; v = p[v]) 
{      
  b[u] = v;      
}

size () 및 back ()에 해당하는 것을 대체하십시오.

그것이하는 일은 목록을 뒤집고 배열에 저장하는 것입니다. 그러나 C #에서는이를 위해 시스템 정의 함수를 직접 가지고 있습니다. 따라서이 루프도 작성할 필요가 없습니다.

b = b.Reverse().ToArray();

u = b.size(), v = b.back()

초기화입니다.

u--

조건입니다.

v = p[v]

반복입니다


조건은의 결과이며 u--, u감소하기 전의 값입니다 .

C 및 C ++에서은 int 이다 암시 적으로 수행하여 부울로 변환 != 0비교 (0 false, 다른 모든 것들입니다 true).

b.back()인 용기 내의 마지막 요소 인 b[b.size() - 1]경우는 size() != 0.


In C everything non-zero is true in "boolean" contexts, such as the loop end condition or a conditional statement. In C# you have to make that check explicit: u-- != 0.


As stated by others, the fact that C++ has implicit casting to boolean means the conditional is u--, which will be true if the value is non-zero.

It's worth adding, that you've a false assumption in asking "where's the conditional". In both C++ and C# (and other similarly syntaxed languages) you can have an empty conditional. In this case it always evaluates to true, so the loop continues forever, or until some other condition exits it (via return, break, or throw).

for(int i = 0; ; ++i)
  doThisForever(i);

Indeed, any part of the for statement can be left out, in which case it's just not performed.

In general, for(A; B; C){D} or for(A; B; C)D; becomes:

{A}
loopBack:
if(!(B))
  goto escapeLoop;
{D}
{C}
goto loopBack;
escapeLoop:

Any one or more of A, B, C or D can be left out.

As a result of this, some favour for(;;) for infinite loops. I do because while while(true) is more popular, I read that as "until truth ends being true", which sounds somewhat apocalyptic compared to my reading for(;;) as "forever".

It's a matter of taste, but since I'm not the only person in the world to like for(;;) it's worth knowing what it means.


all the answers are correct :-

for loop can be used in a variety of ways as follows :

Single Statement inside For Loop
Multiple Statements inside For Loop
No Statement inside For Loop
Semicolon at the end of For Loop
Multiple Initialization Statement inside For
Missing Initialization in For Loop
Missing Increment/Decrement Statement
Infinite For Loop
Condition with no Conditional Operator.

for (u = b.size(), v = b.back(); u--; v = p[v]) 
   b[u] = v;

In above code, u and v are initialized with b.size() and b.back().

Every time the condition is checked, it executes decrement statement too i.e. u--.

The for loop will exit when u will become 0.


The error encountered in C# itself clears the doubt. The for-loop searches for a

FALSE

condition to terminate. And as we know,

(BOOL) FALSE = (int) 0

but C# cannot process this on its own unlike as C++. So the condition you are searching for is

u--

but you have to explicitly give the condition in C# as

u-- != 0

or

u-- > 0

But still try to avoid this kind of coding practice. The

while loop

stated above in answer is one of the most simplified version of your

for-loop.


If you're used to C / C++ this code isn't so hard to read, though it's pretty terse and not that great of code. So let me explain the parts that are more Cism than anything else. First off the general syntax of a C for loop looks like this:

for (<initialization> ; <condition>; <increment>)
{
    <code...>
}

The initialization code gets run once. Then the condition gets tested before every loop and lastly the increment gets called after every loop. So in your example you'll find the condition is u--

Why does u-- work as a condition in C and not C#? Because C implicitly converts a lot of things too bools and it can cause trouble. For a number anything that is non-zero is true and zero is false. So it will count down from b.size()-1 to 0. Having the side-effect in the condition is a bit annoying and it would be preferable to put it in the increment part of the for loop, though a lot of C code does this. If I were writing it I would do it more like this:

for (u = b.size() - 1, v = b.back(); u>=0; --u) 
{
    b[u] = v;
    v = p[v]
}

The reason for this is, to me at least, it's clearer. Each part of the for loop does it's job and nothing else. In the original code the condition was modifying the variable. The increment part was doing something that should be in the code block etc.

The comma operator may be throwing you for a loop also. In C something like x=1,y=2 looks like one statement as far as the compiler is concerned and fits into the initialization code. It just evaluates each of the parts and returns the value of the last one. So for example:

std::cout << "(1,2)=" << (1,2) << std::endl;

would print out 2.

참고URL : https://stackoverflow.com/questions/11738939/never-seen-before-c-for-loop

반응형