Pourquoi le code suivant me donne une erreur?
int n = 30000; // Some number
for (int i = 0;
0 <= n ? (i < n) : (i > n);
0 <= n ? (i++) : (i--)) { // ## Error "not a statement" ##
f(i,n);
}
Pourquoi le code suivant me donne une erreur?
int n = 30000; // Some number
for (int i = 0;
0 <= n ? (i < n) : (i > n);
0 <= n ? (i++) : (i--)) { // ## Error "not a statement" ##
f(i,n);
}
C'est parce que l' for
boucle a été défini ainsi dans le Langage Java Spécification.
14.14.1 La base d'une déclaration
BasicForStatement:
for ( ForInit ; Expression ; ForUpdate ) Statement
ForStatementNoShortIf:
for ( ForInit ; Expression ; ForUpdate ) StatementNoShortIf
ForInit:
StatementExpressionList
LocalVariableDeclaration
ForUpdate:
StatementExpressionList
StatementExpressionList:
StatementExpression
StatementExpressionList , StatementExpression
Il se doit donc d'être un StatementExpression
ou multiple, StatementExpression
s et StatementExpression
est défini comme:
14.8 Expression des déclarations
StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
0 <= n ? (i++) : (i--)
est aucun de ceux-ci, de sorte qu'il n'est pas acceptée. i += ((0 <= n) ? 1 : -1)
est une affectation, de sorte qu'il fonctionne.
Tout d'abord, je vous recommande d'écrire le code de cette façon. Le but du code est de "compter à partir de zéro à n si n est positif, le compte à rebours de 0 à n, si n est négatif", mais j'ai tendance à plutôt écrire:
for (int i = 0; i < abs(n); i += 1)
{
int argument = n < 0 ? -i : i;
f(argument, n);
}
Mais cela ne veut pas répondre à votre question, qui est:
Pourquoi ne puis-je pas utiliser
?:
opérateurs dans le 3ème argument de boucles for en Java?
Un for
boucle a la structure en for ( initialization ; condition ; action )
.
Le but d'une expression est de calculer une valeur.
Le but de l' instruction est de prendre une action.
Il y a certaines expressions qui de par leur design à la fois de calculer une valeur et prendre des mesures. i++
, i += j
, new foo()
, method()
et ainsi de suite.
Il est mauvais style à toute autre expression qui calcule à la fois une valeur et prend une action. De telles expressions sont difficiles à comprendre.
Par conséquent, l'action de l' for
boucle est limité à seulement ceux expressions qui de par leur design à la fois de calculer une valeur et prendre des mesures.
Fondamentalement, en interdisant à ce code, le compilateur est vous dire que vous avez fait un mauvais choix stylistiques. b?i++:i--
est une expression juridique, mais il est vraiment mauvais style, parce qu'il rend ce qui est censé être le calcul d'une valeur en produisant un effet secondaire et en ignorant la valeur.
Votre code vous donne une erreur surtout parce que vous essayez de résoudre votre problème avec des non valide algorithme. Le fait que JLS ne permet pas ternaire comme condition dans la boucle for n'aide pas non plus - mais le principal problème est que vous manquez de la validité de la solution de la tâche à portée de main.
Commençons par une déclaration commune, "l'optimisation prématurée == sqrt(sum(mal))" - d'abord, vous devez considérer ce que vous voulez faire, pas comment le faire, ou pourquoi le code ne fonctionne pas.
je l'étape devrait être de 1 si n >= 0, sinon -1
(note: si n est invariante (et c'est ici) en utilisant par exemple abs(n) ou n < 0 dans l'état est une mauvaise pratique; bien que la plupart compilateur va essayer de facteur de l'invariant de la boucle, vous devez simplement utiliser un temporaire var pour stocker le résultat et utiliser le résultat de la comparaison à la place)
Donc, le code devrait être:
void doSomething( int n ) {
if ( n >= 0 )
for( int i = 0; i < n; i++ )
f( i, n );
else
for( int i = 0; i > n; i-- )
f( i, n );
}
L'affacturage des invariants et la séparation distincte de branches de code sont les techniques de base utilisées pour augmenter l'efficacité des algorithmes de (pas une optimisation prématurée, l'esprit me); il n'y a pas plus rapide ni plus propre façon de le faire. Certains prétendent que c'est un cas de boucle de déroulement - il très bien serait, si ce n'est pour le fait que ces deux boucles ne devrait pas être enroulés ensemble en premier lieu...
Une autre chose: le tiers de l'op dans de boucle a toujours été un régulier de la déclaration; nous allons essayer de deviner pourquoi ne pas le code suivant compile?
0 <= n ? (i++) : (i--); // error: not a statement
... peut-être parce que code suivant ne compile pas non plus?
0 <= n ? i : i; // error: not a statement
... et c'est pour la même raison, le code ci-dessous ne fonctionne pas en Java soit?
i; // error: not a statement
Votre réponse est: ternaire n'est pas un énoncé - ternaire renvoie simplement la valeur, et la valeur n'est pas une déclaration (au moins en Java); ++i et i - sont autorisés dans ternaire juste parce qu'ils renvoient une valeur, mais ils produisent également des effets secondaires ici.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.