Never seen before C++ for loop

后端 未结 12 2113
独厮守ぢ
独厮守ぢ 2020-12-07 10:58

I was converting a C++ algorithm to C#. I came across this for loop:

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

It gives no

12条回答
  •  心在旅途
    2020-12-07 11:41

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

    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.

提交回复
热议问题