【问题标题】:What can go in the parentheses of a Java for loop?Java for 循环的括号中可以包含什么?
【发布时间】:2010-11-04 02:53:30
【问题描述】:

我的问题是关于 Java for 语句,例如

for (int i = 0; i < 10; ++i) {/* stuff */}

我不明白的是我可以在括号中放入多少代码/什么样的代码(即在我的示例中我有int i = 0; i &lt; 10; ++i)-我不太了解用来描述它的语言这里:

http://java.sun.com/docs/books/jls/third_edition/html/statements.html#24588

基本上我的问题归结为要求翻译规范中看起来像这样的位:

初始化: 语句表达式列表 本地变量声明

编辑:哇。我想真正的答案是“学习阅读和理解 JLS 中使用的符号——它的使用是有原因的”。谢谢大家的回答。

【问题讨论】:

  • “括号”是什么意思:() 或 {}?
  • 我的意思是()。我不知道该怎么称呼他们。我将编辑问题。
  • 称它们为“括号”,因为那是它们的名字 =) 括号是 {},和/或可能是 []。
  • () = 括号,{} = 大括号,[] = 括号
  • 另外,对于一般信息,括号是单数,复数是括号。

标签: java syntax for-loop


【解决方案1】:

StatementExpressionListLocalVariableDeclaration 都在页面的其他位置定义。我将它们复制在这里:

StatementExpressionList:
        StatementExpression
        StatementExpressionList , StatementExpression

StatementExpression:
        Assignment
        PreIncrementExpression
        PreDecrementExpression
        PostIncrementExpression
        PostDecrementExpression
        MethodInvocation
        ClassInstanceCreationExpression

LocalVariableDeclaration:
        VariableModifiers Type VariableDeclarators

VariableDeclarators:
        VariableDeclarator
        VariableDeclarators , VariableDeclarator

VariableDeclarator:
        VariableDeclaratorId
        VariableDeclaratorId = VariableInitializer

VariableDeclaratorId:
        Identifier
        VariableDeclaratorId [ ]

VariableInitializer:
        Expression
        ArrayInitializer

进一步遵循语法没有多大意义;我希望它很容易阅读。

这意味着您可以在ForInit 部分中或者拥有以逗号分隔的任意数量的StatementExpressionsLocalVariableDeclarationLocalVariableDeclaration 可以由任意数量的“variable = value”对组成,以逗号分隔,前面是它们的类型。

所以这是合法的:

for (int i = 0, j = 0, k = 0;;) { }

因为“int i = 0, j = 0, k = 0”是有效的LocalVariableDeclaration。这是合法的:

int i = 0;
String str = "Hello";
for (str = "hi", i++, ++i, sayHello(), new MyClass();;) { }

因为初始化器中的所有这些随机事物都符合StatementExpressions

由于StatementExpressionList 在 for 循环的更新部分是允许的,所以这也是有效的:

int i = 0;
String str = "Hello";
for (;;str = "hi", i++, ++i, sayHello(), new MyClass()) { }

你开始看照片了吗?

【讨论】:

  • 啊哈。好的,但你不能拥有 (String s = "hello", int i =0;;)?
  • 没错。 LocalVariableDeclaration 中只允许使用一种类型,但您可以拥有任意数量的该类型。
  • 有趣。这已被投票,未投票,然后再次投票。
【解决方案2】:

请注意:我们希望在括号中看到非常简单、非常熟悉的内容。超越

for (int i = 0; i < n; i++)

可能会使您代码的未来读者感到困惑。有时您需要以相反的顺序进行迭代——甚至开始和结束条件都会给许多程序员带来麻烦(是 n、n-1、n+1 吗?是 >0、>=0、...?)

种情况需要详细说明。我只是说 - 在你去那里之前要小心,考虑更简单的表示。

【讨论】:

    【解决方案3】:

    基本上,对于一个简单的 FOR 循环:

    for (startCondition; endCondition; increment)
    

    在 startCondition 中,设置用于运行循环的变量的起始值;在许多情况下,您会将其视为 i

    int i = 0
    

    在 endCondition 中,您指定循环继续进行的比较。所以,如果你想在 i = 15 时停止循环,你会放

    i <= 15
    

    i != 15
    

    你也可以做一些事情,比如与布尔值进行比较,比如

    i == true
    

    在增量中,您指定计数器变量在每次循环后应增加多少。如果你想简单地增加 1,你会放

    i++
    

    在 startCondition 和 endCondition 中使用更多表达式以及多个计数器会变得更加复杂,但这是一个简单的 FOR 循环。

    【讨论】:

    • 但是 什么 究竟是允许三个中的每一个?
    • 我不认为 endCondition 需要进行比较。也可能我没有计数器变量。
    • endCondition 必须是布尔测试。当它变为假时,循环结束。 startCondition 和 increment 可以是您喜欢的任何语句,但通常您应该使用有意义的语句作为循环初始化和增量。如果您正在做一些不太适合该模式的事情,请改用 while。
    • 是的 endCondition 可能是 1 并且你有一个无限循环:-)...下面是严肃的答案
    • 您可以使用的另一个循环示例是 for(Iterator i = l.iterator(); i.hasNext();;) (假设您有一个名为 l 的 List 变量)。此示例主要针对 Java 1.4,如果使用 Java 5,则几乎总是首选 foreach 循环。例如,for(String s : l),假设您有一个 String 对象列表。
    【解决方案4】:

    StatementExpressionList

    表示你可以做到:

    int x = 0; 
    int y = 0;
    int z = 0;
    
    
    for ( x++, y++; x+ y < z; z++) {
    // whatever
    }
    

    其中 x++, y++ 是表达式列表的列表。基本上是您希望在循环开始时执行的语句。

    LocalVariableDeclaration 看起来像

    int j = 0, i = 0, k = 0;
    

    所以

    for ( int j = 0, i = 0, k = 0; i+j+k < 10; i++, j++, k++ ){
    // whatever
    }
    

    【讨论】:

      【解决方案5】:

      for 循环中的第二条语句(条件语句)可以是任何计算结果为布尔值或布尔值的语句。通常,这类似于i &lt; max,但也可能是hasMore()(x &gt; y) == boolmyclient.getMapOfIntsToBools().get(i)。只要表达式的结果是布尔值,它有多长并不重要。

      其他两个部分基本上可以是任何单个语句:无论它的最终返回类型是什么,它都会被忽略(就像它在一个空行上一样)。第一条语句总是在第一个循环开始时精确执行一次,而另一个语句在每个循环结束时执行。

      另一种思考方式是:

      if (A; B; C){
        ...
      }
      

      变成这样:

      A
      while (B){
        ...
        C
      }
      

      A 和 C 可以是您希望它们成为的任何单个语句(不包括任何内容)。 B 必须是一个布尔值。

      【讨论】:

        【解决方案6】:

        BasicFor 语句: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) 声明

        for 语句由 ForInit、Expression 和 ForUpdate 组成,它们都是可选的

        初始化: 语句表达式列表 局部变量声明 forInit 是用逗号分隔的语句和表达式列表(见下文)或局部变量的声明

        更新: 语句表达式列表

        forUpdate 是用逗号分隔的语句和表达式的列表...基本上,您可以输入: 作业
        前增量表达式 预减量表达式 后增量表达式 PostDecrement 表达式 方法调用 ClassInstanceCreationExpression

        语句表达式列表: 语句表达式 语句表达式列表,语句表达式

        什么是语句:

        程序的执行顺序由语句控制, 为了它们的效果而被执行 并且没有值。

        有些语句包含其他语句 陈述作为其结构的一部分; 此类其他陈述是 语句的子语句。我们说 该语句 S 立即包含 如果没有语句 T,则语句 U 不同于 S 和 U 使得 S 包含 T 并且 T 包含 U。在 同样的方式,一些语句包含 表达作为他们的一部分 结构。

        一个表达式是

        程序中的大部分工作都是通过评估表达式来完成的,要么是为了它们的副作用,例如对变量的赋值,要么是它们的值,它可以用作更大表达式中的参数或操作数,或者影响执行语句中的顺序,或两者兼而有之。

        所以基本上你可以在中间有任何有效的java表达式(你不需要比较)但是这个表达式仍然必须返回一个布尔值......

        【讨论】:

          【解决方案7】:

          你可以放

          for(stmt a,stmt b, stmt,c.... ; stmt 1; alpha, beta, omega,...){}

          其中 stmt : 语句;

          a、b、c等都可以

          局部变量或其他语句的定义

          for(int a=0,b=0;;){}
          

          将 a 和 b 声明并初始化为 0;

          for(a=i,b=a+1;;){}
          

          将 a 和 b 分配给这些值

          你可以使用迭代器

           for(Iterator it= my_list.iterator();;){}
          

          1、2、3等必须返回布尔值,

          所以你不能放类似的东西

           for (;a++;)
          

          但你可以

          for (;a<b;)
          

          for(;it.hasNext();)
          

          这基本上是一个while循环。

          或者什么都没有:)

           for(int a=0;;a++)
          

          至于alpha、omega..部分,应该使用赋值运算符

          for(;;a){} 
          

          不会编译,但是

          for(;;a++){}
          for(;;a=b;a++){}
          

          会的。

          然后你就有了 foreach 构造,它更简单

          for (A a:getAList())
          

          并遍历整个列表, a 具有当前元素。不需要控制变量。

          【讨论】:

          • 您可以在单个语句中声明的变量之间使用逗号。但是,语句或表达式之间不能有逗号。在 C 中,a, b 是一个表达式,其中 a 被评估,然后 b 返回 b 的值。 Java 不这样做。
          【解决方案8】:
          for(startCondition(s); endCondition(s); Action) {}
          

          只要 startCondition(s) 和 endCondition(s) 被评估为布尔值(真或假,1 或 0 取决于语言),您就可以根据需要拥有“长”的条件列表。

          【讨论】:

            【解决方案9】:

            使用循环翻译规范

            for (initFor; endCondition; update)
            

            startCondition 是其值被丢弃的语句列表(包括无语句)。他们指定LocalVariableDeclaration 来说明如果局部变量声明在语句中(例如 int x = 0),那么局部变量将“作用域”到 for 语句的块中(即该值在块或 for 语句)。

            endCondition 是一个布尔表达式。再次它是可选的(如果没有循环永远继续)

            update 是一个语句列表,通常处理每个循环后所需的更新。

            【讨论】:

              【解决方案10】:

              for 循环的所有三个子句都是可选的,但分号必须在那里。

              在 for 循环的第一个子句中,可以放置任意数量的语句,用逗号分隔。或者,在替代方案中(但不能混合使用),您可以声明可用于 for 循环的单一类型的新变量(例如 int i = 1, j= 2)。此处声明的任何变量都可用于 for 循环之后的语句(或使用花括号的语句)。

              for 循环的第二个子句是一条返回布尔值的语句。这将被评估以考虑 for 循环是否应该继续。

              for 循环的第三个子句可以包含任意数量的以逗号分隔的语句,但不能声明任何变量。

              【讨论】:

                【解决方案11】:

                您收到的很多回复并未真正回答您的问题。正确的答案是你可以放任何你想要的东西。如果您的 for 循环中有 break 语句,您甚至不需要有效的结束条件。在使用迭代器循环的情况下,您也不需要三个语句。

                编辑:好的,不太对。您不能在第一个分号之后初始化新变量。

                【讨论】:

                  【解决方案12】:

                  您可能会发现 for each 表示法通常更简单、更清晰。我建议在适当的时候使用 for each 循环。 例如

                  for(Element element: arrayOfElement) { /* stuff */ }
                  // or
                  for(Element element: iterableOfElement) { /* stuff */ }
                  

                  Collection、Set 和 List 是可迭代的,但您可以自己制作。

                  【讨论】:

                    【解决方案13】:

                    你可以有多个语句;然后是在每个循环中评估的单个条件,最后是另一组语句

                    【讨论】:

                    • 在最后一部分中,您可以使用 ,(逗号)分隔多个语句,例如 for(int i=0,j=0;i
                    猜你喜欢
                    • 1970-01-01
                    • 2019-03-09
                    • 2020-10-03
                    • 1970-01-01
                    • 2017-10-28
                    • 1970-01-01
                    • 2014-05-07
                    • 1970-01-01
                    相关资源
                    最近更新 更多