Je commence juste à apprendre Java à l'école et maintenant je suis coincé.

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

Persist est un nom déroutant car il ne persiste pas au-delà de la durée de vie de votre contexte.

Pourquoi le numéro «5» est-il toujours imprimé? Cette boucle while n'est-elle pas censée s'exécuter uniquement si point! = Count + 1? Ensuite, il devrait s'arrêter lorsque 5 = 5, n'est-ce pas (et "5" ne serait pas imprimé)?

Merci beaucoup.

6
FaY 23 déc. 2015 à 18:17

6 réponses

Meilleure réponse
point != count++

Cela signifie comparer point et la valeur actuelle de count pour l'inégalité, puis incrémenter count. Ainsi, lorsque count vaut 4:

  1. il sera comparé à point (inégal)
  2. count deviendra 5
  3. la boucle while s'exécutera pendant une itération
  4. il sera à nouveau comparé à point (égal)
  5. la boucle est terminée

L'opérateur d'incrémentation du préfixe ++count s'incrémenterait avant d'utiliser la valeur dans une comparaison.

12
Nir Levy 23 déc. 2015 à 15:43

Parce que vous faites la comparaison == avant l'incrémentation ++, si vous voulez le corriger, passez à ++count

10
OPK 23 déc. 2015 à 15:19

Je suis d'accord avec les réponses précédentes sur les détails de votre problème en supposant la structure actuelle. Cependant, il serait préférable de suivre les conseils de la spécification du langage Java, 15.7. Ordre d'évaluation, qui dit

Le langage de programmation Java garantit que les opérandes des opérateurs semblent être évalués dans un ordre d'évaluation spécifique, à savoir de gauche à droite.

Il est recommandé que le code ne repose pas de manière cruciale sur cette spécification. Le code est généralement plus clair lorsque chaque expression contient au plus un côté effet, comme son opération la plus externe, et lorsque le code ne dépend pas de exactement quelle exception survient en raison de la gauche à droite évaluation des expressions.

Le count++ a un effet secondaire et n'est pas l'opération la plus externe dans son instruction. C'est finalement la cause de votre difficulté à raisonner sur votre code. Ce serait plus clair si vous faisiez l'incrémentation à l'intérieur de la boucle, avant ou après l'appel println.

La clé du raisonnement sur les programmes est d'avoir des invariants simples et clairs. Voici une version alternative de votre programme, sur-commentée pour l'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++;
    }
  }
}

J'utilise "payload" pour désigner le code pour lequel la boucle existe, dans ce cas juste l'appel println.

Mes invariants sont:

  • La valeur de count à l'arrivée au test est à la fois la valeur qui sera testée et, si elle réussit le test, la valeur qui sera utilisée dans la charge utile.
  • Après l'exécution du corps de la boucle, la valeur de count a été incrémentée de un.

La boucle contient deux opérations avec des effets secondaires, l'appel à println et l'incrément count. Chacun d'eux est l'opération la plus externe dans son énoncé.

6
Patricia Shanahan 23 déc. 2015 à 16:23

C'est la différence entre les opérateurs prefix (++i) et postfix (i++) en java.

Ce que vous avez utilisé est postfix, ce qui signifie qu'il renvoie d'abord la valeur de count, puis l'augmente. si vous utilisiez point != ++count, vous n'obtiendrez pas 5 imprimés

5
Nir Levy 23 déc. 2015 à 15:21

Le nombre n'est pas incrémenté tant que le while n'a pas été évalué. Vous devrez plutôt procéder de cette façon:

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

Dans ce cas, ++ entraîne le changement de nombre en premier, avant qu'il ne soit vérifié par rapport au point .

C'est facile à retenir: si le ++ vient avant, il est incrémenté en premier. Si après puis après l'évaluation. La même chose s'applique aux affectations.

Cela dit, je suis d'accord avec la réponse de Patricia, selon laquelle l'incrémentation doit être effectuée dans le bloc while comme suit:

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

C'est plus clair et plus facile à raisonner.

4
Gabriel Kunkel 23 déc. 2015 à 15:41

Le problème est que vous comparez le nombre avant de l'incrémenter.

Ce que vous voulez dire, c'est: while(point != count +1)

Ce que vous voulez: while(point != ++count)

J'espère que cela pourra aider!

2
Felix Gerber 23 déc. 2015 à 15:23