我正在将C++算法转换为C#.我遇到了这个for循环:
for (u = b.size(), v = b.back(); u--; v = p[v])
b[u] = v;
Run Code Online (Sandbox Code Playgroud)
它在C++中没有错误,但在C#中没有错误(不能将int转换为bool).我真的无法弄清楚这个循环,条件在哪里?
有人可以解释一下吗?
PS.只是为了检查,使VECTOR适应LIST b.back()对应b [b.Count-1]?
das*_*ght 319
for循环的条件位于中间 - 两个分号之间;.
在C++中,几乎可以将任何表达式作为条件:任何评估为零的意思false; 非零意味着true.
在您的情况下,条件是u--:当您转换为C#时,只需添加!= 0:
for (u = b.size(), v = b.back(); u-- != 0; v = p[v])
b[u] = v; // ^^^^ HERE
Run Code Online (Sandbox Code Playgroud)
sli*_*lim 165
很多准确的答案,但我认为值得写出等效的while循环.
for (u = b.size(), v = b.back(); u--; v = p[v])
b[u] = v;
Run Code Online (Sandbox Code Playgroud)
相当于:
u = b.size();
v = b.back();
while(u--) {
b[u] = v;
v = p[v];
}
Run Code Online (Sandbox Code Playgroud)
在转换为C#时,您可以考虑重构为while()格式.在我看来,它更清晰,更少是新程序员的陷阱,同样有效.
正如其他人已经指出的那样 - 但为了使我的答案完整 - 要使它在C#中工作,你需要while(u--)改为while(u-- != 0).
......或者while(u-- >0)万一你开始消极.(好吧,b.size()永远不会消极 - 但考虑一个普遍的情况,或许其他东西初始化你).
或者,使其更清晰:
u = b.size();
v = b.back();
while(u>0) {
u--;
b[u] = v;
v = p[v];
}
Run Code Online (Sandbox Code Playgroud)
最好是要清楚而不是简洁.
Dan*_*nas 66
条件是u--;,因为它位于for指令的第二个位置.
如果值u--;不为0,则将其解释为true(即隐式转换为布尔值true).相反,如果它的值为0,则它将被转换为false.
这是非常糟糕的代码.
更新:我在这篇博文中讨论了"for"循环的写作.其建议可归纳为以下段落:
for循环是一个实用的,可读的(一旦你习惯了)和简洁的构造,但你需要很好地使用它.由于其不常见的语法,以过于富有想象力的方式使用它并不是一个好主意.
for循环的所有部分都应该简短易读.应选择变量名称以使其易于理解.
这个例子显然违反了这些建议.
Nar*_*dra 23
这将是循环的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;
}
Run Code Online (Sandbox Code Playgroud)
只需替换size()和back()的等效项.
它的作用是反转列表并存储在数组中.但是在C#中我们直接为此设置了系统定义的函数.所以你也不需要编写这个循环.
b = b.Reverse().ToArray();
Run Code Online (Sandbox Code Playgroud)
hus*_*sik 15
u = b.size(), v = b.back()
Run Code Online (Sandbox Code Playgroud)
是初始化.
u--
Run Code Online (Sandbox Code Playgroud)
是条件.
v = p[v]
Run Code Online (Sandbox Code Playgroud)
是迭代
Bo *_*son 14
条件是结果u--,u它是递减之前的值.
在C和C++中,通过隐式地进行比较,int 可以将a转换为bool != 0(0是false,其他一切都是true).
b.back()是容器中的最后一个元素,即b[b.size() - 1]何时size() != 0.
正如其他人所说,C++隐式转换为布尔值的事实意味着条件是u--,如果值非零,则为真.
值得补充的是,你在问"有条件的地方"时有一个错误的假设.在C++和C#(以及其他类似的语法语言)中,您可以使用空条件.在这种情况下,结果始终为true,因此该循环永续,或者直到一些其他条件,即可退出它(通过return,break或throw).
for(int i = 0; ; ++i)
doThisForever(i);
Run Code Online (Sandbox Code Playgroud)
实际上,for语句的任何部分都可以省略,在这种情况下它只是没有执行.
一般来说,for(A; B; C){D}或for(A; B; C)D;成为:
{A}
loopBack:
if(!(B))
goto escapeLoop;
{D}
{C}
goto loopBack;
escapeLoop:
Run Code Online (Sandbox Code Playgroud)
可以省略A,B,C或D中的任何一个或多个.
因此,有些人喜欢for(;;) 无限循环.我这样做是因为虽然while(true)它更受欢迎,但我读到"直到真相结束才真实",与我的阅读for(;;) "永远" 相比,这听起来有点世界末日.
这是一个品味问题,但因为我不是世界上唯一一个喜欢for(;;)它的人,值得知道这意味着什么.