简体   繁体   中英

(Java) While-Loop condition

I'm just starting to learn Java in school and now I'm stuck.

public static void main(String[] args) {
    int count = 0;
    int point = 5;
    while(point != count++){
        System.out.println(count);
    }

Console : 1 2 3 4 5

Why is number "5" still printed ? Isn't this while loop supposed to run only if point != count + 1 ? Then it should stop when 5 = 5, isn't it (and "5" wouldn't be printed) ?

Thank a lot.

point != count++

This means compare point and current value of count for inequality and then increment count . So when count is 4 :

  1. it will be compared to point (unequal)
  2. count will become 5
  3. the while loop will run for one iteration
  4. it will be compared to point again (equal)
  5. the loop is terminated

the prefix increment operator ++count would increment before using the value in a comparison.

因为你是在 increment ++之前做比较== ,如果你想修复它,改成++count

I agree with the prior answers on the details of your problem assuming the current structure. However, it would be better to follow the advice in the Java Language Specification, 15.7. Evaluation Order , which says

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.

The count++ has a side effect and is not the outermost operation in its statement. That is ultimately the cause of your difficulty reasoning about your code. It would be clearer if you did the increment inside the loop, either before or after the println call.

The key to reasoning about programs is to have simple, clear invariants. Here is an alternative version of your program, over-commented for exposition.

public class Test {
  public static void main(String[] args) {
    /*
     * Initialize count to the first value that will be used in the loop
     * payload.
     */
    int count = 1;
    int point = 5;
    while (count < point) {
      /*
       * Loop payload - executed with the same value of count as the test above
       */
      System.out.println(count);
      /*
       * Increment count for the next test and, if the test passes, payload
       * execution.
       */
      count++;
    }
  }
}

I am using "payload" to mean the code for which the loop exists, in this case just the println call.

My invariants are:

  • The value of count on arrival at the test is both the value that will be tested and, if it passes the test, the value that will be used in the payload.
  • After execution of the loop body, the value of count has been incremented by one.

The loop contains two operations with side effects, the call to println and the count increment. Each of them is the outermost operation in its statement.

This is the difference between prefix ( ++i ) and postfix ( i++ ) operators in java.

What you used is postfix, which means it first returns the value of count, and after that increases it. if you'd use point != ++count you wouldn't get 5 printed

The count isn't incremented until after the the while has been evaluated. You'll need to make it this way instead:

public static void main(String[] args) {
    int count = 0;
    int point = 5;
    while(point != ++count){
        System.out.println(count);
    }

In this case the ++ causes count to change first, before it is checked against point .

It's easy to remember: if the ++ comes before, it gets incremented first. If after then after the evaluation. The same applies to assignments.

With that said, I agree with Patricia´s answer, that the incrementing should be done within the while block like so:

  public static void main(String[] args) {
        int count = 0;
        int point = 5;
        while(point != count){
            System.out.println(count);
            count++;
        }

This is more clear and easier to reason about.

The problem is that you are comparing count before incrementing it.

What you mean is: while(point != count +1)

What you want : while(point != ++count)

Hope that helps!

This is what I understand: if you use prefix or post in a for loop it does not change the behaviour of the programme at all. so the question is when does it matter?

it matters when we use prefix or postfix alongside other comparison operators FOR EXAMPLE

prefix i = 1; result = 5 + ++i //answer for this one will be 7 Explanation : this is what I think - because it has ++ before "i" then first we will increment the i and then add it to 5.

postfix

i=1; result = 5 + i++; //answer for this will be 6 Explanation: because this one has ++ after i then first we will add the i value and then increment so first 1 will be added to 5 and then it the new value of i will be 2

In short i++ first provide the value to comparison operator and then it is incremented. This explain your case 5!= 4 , then i is incremented to 5 and printed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM