首页 文章

在C for循环之前从未见过

提问于
浏览
163

我正在将C算法转换为C# . 我遇到了这个for循环:

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

它在C中没有错误,但在C#中没有错误(不能将int转换为bool) . 我真的无法弄清楚这个循环,条件在哪里?

有人可以解释一下吗?

PS . 只是为了检查,使VECTOR适应LIST b.back()对应b [b.Count-1]?

12 回答

  • 6

    在C中,在"boolean"上下文中,所有非零都是 true ,例如循环结束条件或条件语句 . 在C#中,您必须明确检查: u-- != 0 .

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

    是初始化 .

    u--
    

    是条件 .

    v = p[v]
    

    是迭代

  • 65

    for 循环的条件位于中间 - 两个分号 ; 之间 .

    在C中,几乎可以将任何表达式作为条件:任何计算结果为零的都意味着 false ;非零意味着 true .

    在您的情况下,条件是 u-- :当您转换为C#时,只需添加 != 0

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

    很多准确的答案,但我认为值得写出等效的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) 以防你开始消极 . (好的, b.size() 永远不会是负面的 - 但考虑一个普遍的情况,也许其他东西初始化你) .

    或者,使其更清晰:

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

    最好是要清楚而不是简洁 .

  • 14

    条件是 u--; ,因为它位于 for 指令的第二个位置 .

    如果 u--; 的值与0不同,则它将被解释为 true (即,隐式地转换为布尔值 true ) . 相反,如果它的值为0,则它将被转换为 false .

    这是very bad code .

    Update: 我在blog post讨论了"for"循环的写法 . 其建议可归纳为以下段落:

    for循环是一个实用的,可读的(一旦你习惯了)和简洁的构造,但你需要很好地使用它 . 由于其不常见的语法,以过于富有想象力的方式使用它并不是一个好主意 . for循环的所有部分都应该简短易读 . 应选择变量名称以使其易于理解 .

    这个例子显然违反了这些建议 .

  • 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;      
    }
    

    只需替换size()和back()的等效项 .

    它的作用是反转列表并存储在数组中 . 但是在C#中我们直接为此设置了系统定义的函数 . 所以你也不需要编写这个循环 .

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

    该条件是 u-- 的结果,它是递减前的 u 的值 .

    在C和C中, int 可以通过隐式执行 != 0 比较来转换为bool(0是 false ,其他一切都是 true ) .

    b.back()size() != 0 时容器中的最后一个元素,即 b[b.size() - 1] .

  • 14

    正如其他人所说,C隐式转换为布尔值这一事实意味着条件为 u-- ,如果该值为非零,则为true .

    在询问"where's the conditional"时,它是一个错误的假设 . 在C和C#(以及其他类似的语法语言)中,您可以使用空条件 . 在这种情况下,它总是计算为true,因此循环会一直持续,或者直到某个其他条件退出(通过 returnbreakthrow ) .

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

    实际上,for语句的任何部分都可以省略,在这种情况下它只是没有执行 .

    通常, for(A; B; C){D}for(A; B; C)D; 变为:

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

    可以省略A,B,C或D中的任何一个或多个 .

    由于这个原因,一些人赞成 for(;;) 无限循环 . 我这样做是因为虽然 while(true) 更受欢迎,但我将其视为"until truth ends being true",与我的阅读 for(;;) 相比,这听起来有点世界末日 .

    它不是世界上唯一喜欢 for(;;) 的人,值得知道这意味着什么 .

  • 4

    所有答案都是正确的: -

    for循环可以以多种方式使用,如下所示:

    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.
    
  • 11
    for (u = b.size(), v = b.back(); u--; v = p[v]) 
       b[u] = v;
    

    在上面的代码中, uvb.size()b.back() 初始化 .

    一切检查条件的时间,它也执行递减语句,即 u-- .

    u 变为 0 时, for 循环将退出 .

  • 164

    C#本身遇到的错误清除了疑点 . for循环搜索a

    条件终止 . 而且我们知道,

    (BOOL)FALSE =(int)0

    但C#不能像C一样自行处理 . 所以你要寻找的条件是

    你 -

    但是你必须在C#中明确地给出条件

    你 - != 0

    要么

    u--> 0

    但仍然试图避免这种编码实践 . 该

    while循环

    以上所述的答案是您最简化的版本之一

    for-loop .

  • 3

    如果你已经习惯了C / C,那么这段代码就不那么难读了,虽然它很简洁而且代码也不是很好 . 因此,让我解释一下Cistic比其他任何东西都要多的部分 . 首先,C for循环的一般语法如下所示:

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

    初始化代码运行一次 . 然后在每个循环之前测试条件,最后在每个循环之后调用增量 . 所以在你的例子中你会发现条件是 u--

    为什么 u-- 在C而不是C#中作为一个条件?因为C隐含地转换了很多东西而且会引起麻烦 . 对于数字,任何非零的都是真,零是假 . 所以它会从b.size() - 1倒计数到0.在条件中有副作用有点烦人,最好将它放在for循环的增量部分,尽管很多C代码这样做 . 如果我正在写它,我会更喜欢这样做:

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

    原因是,至少对我来说,它更清楚 . for循环的每个部分都是它的工作,没有别的 . 在原始代码中,条件是修改变量 . 增量部分正在做一些应该在代码块等中的东西 .

    逗号运算符也可能会引发循环 . 在C中,就编译器而言,类似 x=1,y=2 的内容看起来像一个语句,并且适合初始化代码 . 它只是评估每个部分并返回最后一个部分的值 . 例如:

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

    会打印2 .

相关问题