8
votes

Precedence de ~ et ++ en Java

Considérez cet extrait de code xxx

impression xxx

ce que je m'attends à voir xxx

D'abord, je pensais que cela pourrait être la priorité de ~ et ++

si le ~ est évalué avant ++ La réponse sera xxx

sinon si le ++ est évalué avant ~ xxx

j'ai cherché Tutoriels Oracle Mais je n'ai pas pu trouver la réponse. Quelqu'un peut-il expliquer ce comportement?


6 commentaires

Personne ne devrait écrire du code de cette façon.


Avez-vous essayé j = ~ (++ j) et comparé?


Hm ... est ce comportement défini à Java? Vous modifiez J des deux côtés de la mission. Je pense que même si vous avez essayé j = j ++ , vous pourriez obtenir des résultats inattendus. Donc, ce n'est pas vraiment une question de priorité.


@Axel C'est un comportement parfaitement bien défini en Java. Un peu inutile et généralement déroutant, mais certainement bien défini. Java n'est pas vraiment dans les affaires de comportement non défini .


@Axel, @dukeling: Je l'ai regardé pour être certain et Dukeling est correct. Cette ambiguïté est résolue par la spécification, qui fournit un ordre d'évaluation spécifique des opérations d'affectation. Le lien suivant affiche l'ordre des opérations pour l'opération externe, j = ... Assignment: Section de la spécification Java 15.26.1 Ce que je n'ai pas vu de spécification claire de ce serait le comportement de quelque chose comme: < Code> J = ++ J + J -; Dans ce cas, est-ce que l'évaluation ++ a été évaluée avant ou après le j ++? Et est-ce la même chose dans chaque machine virtuelle?


Ah, voici: Spec Java Section 15.7 La commande est strictement laissée à droite et aucune partie de la droite ne commence à évaluer avant la fin de la gauche. Je suppose que cela met un peu d'amortisseur sur quelles sortes d'optimisations seraient possibles :-p


5 Réponses :


0
votes

Tout d'abord, ne faites pas ça. Il n'y a aucune raison de créer des opérateurs tels que celui-ci dans une déclaration, mais je me rends compte que vous ne prévoyez pas vraiment de mettre cela en code en direct et n'ayez que expérimenter. Essayez cette page pour la précédente de l'opérateur Java: http://bmanolov.free.fr/javaopérators.php


3 commentaires

Comme mentionné dans le lien, l'incrément postfix est évalué avant ~ alors la réponse doit être incrémentée en premier: 00 ..... 01000 puis complément: 11 ..... 10111


Cela aurait dû être un commentaire, à moins que vous n'ayez réellement extraire les informations requises du lien et postez-la dans la réponse avec une explication.


Veuillez expliquer s'il y a quelque chose que je n'ai pas remarqué dans le lien que je pourrais extraire le ++ (incrément avant ou postfix) a une priorité plus élevée que ~ et les deux ont la bonne associativité



1
votes

Le code semble très fragile. Je pense que ce qui se passe est que lorsque l'expression "~ i ++" est évaluée, la valeur "~ i" est extraite, "i ++" est effectuée, puis finalement l'affectation (remplacer la valeur précédente de "i ++").


4 commentaires

~ 8 est 1111111111111111111111111111111111111111111111111111111111111111111111000. Editer: Je vois votre édition :-) Cependant, vous avez toujours la commande en arrière. Le ++ arrive en premier, mais le résultat du ++ est 7 non 8.


Facilement confondu avec -8. J'ai été confus pendant un moment et j'ai pensé que cette réponse était correcte.


Oui, a été confondu initialement confondu. Devrait mettre un peu plus de pensée avant de répondre.


Cette réponse peut être un peu précise, mais si c'est le cas, il est peu probable que cela soit compris correctement. Veuillez lire La réponse de Jonathan pour plus d'informations.



7
votes

N'oubliez pas que l'opérateur post-augmentation «++» renvoie la valeur de J avant l'incrément est arrivé. C'est-à-dire que si 'J' est 7, alors "J ++" définit J à 8, mais retourne 7 . ~ 7 est alors la sortie que vous avez vue, le nombre se terminant par trois bits.

L'opérateur post-augmentation '++' Post-Ingrement ne peut fonctionner que sur des "valeurs L". Une valeur L est une valeur qui existe quelque part que le code peut logiquement référence - une variable ou un élément de tableau, un paramètre ou un champ de classe. Dès que vous prenez la valeur d'une valeur L et que vous appliquez une opération numérique, vous obtenez une valeur R. Les valeurs R sont juste la valeur et ils ne font référence à aucun stockage persistant où un résultat pourrait être mis. Vous pouvez attribuer aux valeurs L mais pas à des valeurs R - et donc si vous avez essayé de «++» une valeur R, vous obtiendrez une erreur de compilation.

Si l'opérateur '~' est allé en premier, vous seriez ++ - une valeur R, comme dans (~ J) ++. Cela ne compilerait pas. Le fait que le code compile du tout signifie que la priorité est l'autre solution: ~ (J ++).

Parenthèses comme ceci est la manière la plus simple que je sache que vous pouvez régler la priorité chaque fois qu'il y a une confusion: écrivez simplement trois cas de test:

  1. la manière originale que vous êtes incertain.
  2. avec des parenthèses forçant une ordonnance d'opérations.
  3. avec des parenthèses forçant l'autre ordre des opérations.

    exécutez-le et voyez si n ° 2 ou n ° 3 produit le même résultat que n ° 1. : -)


2 commentaires

Comme vous avez mentionné j = (~ j) ++ donne une erreur de compilation ~ (J ++) équivaut à ~ J ++ puisque le ++ a une priorité plus élevée


+1 Très belle réponse, en particulier la valeur R-Value / L-Valeur L.



1
votes

Les deux opérateurs sont des opérateurs de second degré associatif droit, mais un test simple révèle qu'il s'agit du ++ code> exécuté en premier et le bitwise ne fonctionne pas ce dernier.

int j = 7, z = 7, k = 7;
z = z++;
z = ~z;
k = ~k++;
j = ~j;
j++;
System.out.println(Integer.toBinaryString(z));
// 11111111111111111111111111111000
System.out.println(Integer.toBinaryString(j));
// 11111111111111111111111111111001
System.out.println(Integer.toBinaryString(k));
// 11111111111111111111111111111000


0 commentaires

1
votes

opérateurs unaires ( ++ 1 , - , + , - , ~ < / code>, ! ) est évalué de droite à gauche. Par conséquent, ++ est évalué avant ~ .


0 commentaires