Pourquoi éviter les opérateurs d'incrémentation ("++") et de décrémentation ("-") en JavaScript?

357

L'un des conseils de l'outil jslint est le suivant:

++ et -
Les opérateurs ++ (incrémenter) et - (décrémenter) sont connus pour contribuer au mauvais code en encourageant une ruse excessive. Ils viennent juste après une architecture défectueuse pour permettre aux virus et autres menaces de sécurité. Il existe une option plusplus qui interdit l'utilisation de ces opérateurs.

Je sais que les constructions PHP comme $foo[$bar++]has peuvent facilement entraîner des erreurs hors-un, mais je n'ai pas pu trouver un meilleur moyen de contrôler la boucle qu'un while( a < 10 ) do { /* foo */ a++; }ou for (var i=0; i<10; i++) { /* foo */ }.

Est-ce que jslint les met en surbrillance parce qu'il y a des langages similaires qui n'ont pas la syntaxe " ++" et " --" ou la gèrent différemment, ou y a-t-il d'autres raisons d'éviter " ++" et " --" que je pourrais manquer?

artlung
la source
59
Il faut donc faire un tableau [index = index + 1] au lieu d'un tableau [++ index] (si le premier est même autorisé!). Quelle charge de hooey.
Lawrence Dol
34
Je n'ai pas vu Crockford index = index + 1. Je l'ai vu indexer + = 1. Je pense que c'est une alternative raisonnable. Et c'est bien quand vous voulez changer la foulée à autre chose que 1.
Nosredna
124
Personnellement, je ne suis pas un grand fan de Crockford. Il semble considérer que tout ce qui a causé un bug dans son code est mauvais.
Paolo Bergantino
38
En JavaScript, vous devriez considérer chaque bogue comme quelque chose de mal, car il n'y a pas de documentation officielle ni de fournisseur de certificats et vous n'apprenez pas correctement JS à l'Université. Crockford et Firebug ont comblé ces lacunes dans l'éducation JavaScript.
stevek
40
++ne cause pas de bugs. L'utilisation ++de manière "délicate" peut conduire à des bugs, surtout si plus d'une personne gère la base de code, mais ce n'est pas un problème avec l'opérateur, c'est un problème avec le programmeur. Je n'ai pas appris le JS à l'université (car il n'existait pas encore), mais alors quoi? J'ai fait C, qui bien sûr a été le ++premier, mais qui obtient également un "alors quoi?" Je ne suis pas allé à l'université pour apprendre une langue spécifique, je suis allé apprendre de bonnes pratiques de programmation que je peux appliquer à n'importe quelle langue.
nnnnnn

Réponses:

408

Mon point de vue est de toujours utiliser ++ et - par eux-mêmes sur une seule ligne, comme dans:

i++;
array[i] = foo;

au lieu de

array[++i] = foo;

Au-delà de cela, cela peut être déroutant pour certains programmeurs et ne vaut tout simplement pas la peine à mon avis. Les boucles For sont une exception, car l'utilisation de l'opérateur d'incrémentation est idiomatique et donc toujours claire.

cdmckay
la source
3
Ouais, c'est ce que je fais aussi. Difficile de se tromper et plus facile pour les autres de comprendre ce que vous faites.
Nosredna
65
Cela semble être au cœur du problème et de ma confusion. Utilisé seul, i ++; est limpide. La minute où vous ajoutez un autre code autour de cette expression de base, la lisibilité et la clarté commencent à souffrir.
artlung
2
D'accord, mais ce n'est pas seulement lié à JavaScript
Tobias
5
Vous ne dites pas si vous écrivez du C ou du C ++. On peut dire que vous devriez utiliser l'opérateur d'incrémentation de préfixe en C ++, au cas où la ivariable deviendrait plus tard une classe composite, auquel cas vous créeriez inutilement un objet temporaire. Je trouve que l'opérateur postfix est plus esthétique.
mc0e
2
Je préfère la version 1 ligne. Cela rappelle une opération de pile. push est un tableau [++ i] = foo, pop est un bar = array [i--]. (Mais avec les tableaux basés sur 0, array [i ++] = foo et bar = array [- i] sont encore meilleurs). Une autre chose, je détesterais que quelqu'un ajoute du code supplémentaire entre i ++; et tableau [i] = foo ;.
Florian F
257

Je suis franchement confus par ce conseil. Une partie de moi se demande si cela a plus à voir avec un manque d'expérience (perçue ou réelle) avec les codeurs javascript.

Je peux voir comment quelqu'un simplement "pirater" un exemple de code pourrait faire une erreur innocente avec ++ et -, mais je ne vois pas pourquoi un professionnel expérimenté les éviterait.

Jon B
la source
7
Bon point Jon B. C'est pourquoi ça me dérange tellement. Crockford est un programmeur de carrière (valant des décennies), parlant plusieurs langues sur plusieurs décennies et travaillant avec JavaScript essentiellement depuis sa création. Je ne pense pas que ses conseils viennent de "Je suis un pirate inexpérimenté paresseux et inattentif" - c'est pourquoi j'essaie de comprendre d'où il vient.
artlung
14
@artlung Peut-être que son plus à voir avec "Un pirate inexpérimenté paresseux et inattentif" va probablement jouer avec ce code, et je ne veux pas le confondre.
Chris Cudmore
9
Je suis totalement en désaccord avec votre réponse. À mon avis, il ne s'agit pas de "suis-je assez expérimenté pour l'utiliser?" - mais 'Est-ce plus clair ou pas?' Si à l'intérieur d'une boucle for, ou seul, c'est limpide - tout le monde comprendra cela sans mal. Le problème survient lorsqu'il est mis ++dans une expression plus compliquée dans laquelle ++ x est différent de x ++, résultant ainsi en quelque chose de pas facile à lire. L'idée de Crockford n'est pas «je peux le faire? il s'agit de "comment éviter les erreurs?"
ArtoAle
1
C'est la préférence personnelle à quel point la clarté est plus importante pour vous que la compacité. Cela va au-delà d'être suffisamment expérimenté pour comprendre le code. Voir d'autres réponses pour des exemples où cela pose plus de problèmes que sa valeur.
Frug
1
Je suis entièrement d'accord. Pourquoi vous handicaper en n'utilisant pas une partie de la langue? Je trouve de bonnes raisons d'utiliser à la fois les post-incréments et les pré-incréments. Pour moi, une ligne comme celle-ci est claire et concise ... if (--imagesLoading === 0) start (); Si vous pensez que votre code n'est pas clair, utilisez les commentaires!
xtempore
69

Il y a une histoire en C de faire des choses comme:

while (*a++ = *b++);

pour copier une chaîne, c'est peut-être la source de la supercherie excessive dont il parle.

Et il y a toujours la question de

++i = i++;

ou

i = i++ + ++i;

en fait. Il est défini dans certaines langues, et dans d'autres il n'y a aucune garantie de ce qui se passera.

Ces exemples mis à part, je ne pense pas qu'il y ait quelque chose de plus idiomatique qu'une boucle for qui utilise ++pour incrémenter. Dans certains cas, vous pourriez vous en sortir avec une boucle foreach ou une boucle while qui vérifiait une condition différente. Mais déformer votre code pour essayer d'éviter d'utiliser l'incrémentation est ridicule.

Éclipse
la source
104
i = i ++ + ++ i; m'a fait un peu mal aux yeux - :)
Hugoware
3
Le mien aussi. Même si elles n'étaient pas toutes de la même variable, disons que j'avais x = a ++ + ++ b; - cette combinaison rend instantanément x, a et b plus difficiles à retenir dans ma tête. maintenant, si chacun était des instructions séparées sur des lignes distinctes, comme dans - a ++; ++ b; x = a + b; il serait plus facile à comprendre à première vue.
artlung
10
Hélas, (a ++; b ++; x = a = b) n'est pas la même valeur que (a ++ + ++ b).
Thomas L Holaday
8
@Marius: x = a+++b-> x = (a++)+b-> x = a + b; a++. Le tokeniser est gourmand.
Callum Rogers
14
Pour plus de sécurité au travail, supprimez les espaces dans votre dernier exemple.
mc0e
48

Si vous lisez JavaScript The Good Parts, vous verrez que le remplacement de Crockford pour i ++ dans une boucle for est i + = 1 (pas i = i + 1). C'est assez propre et lisible, et est moins susceptible de se transformer en quelque chose de "délicat".

Crockford a fait interdire l'auto-incrémentation et l'auto-décrémentation une option dans jsLint. Vous choisissez de suivre ou non les conseils.

Ma règle personnelle est de ne rien faire combiné avec l'auto-incrémentation ou l'auto-décrémentation.

J'ai appris des années d'expérience en C que je n'obtiens pas de dépassements de tampon (ou d'index de tableau hors limites) si je continue à l'utiliser simplement. Mais j'ai découvert que j'obtiens des dépassements de tampon si je tombe dans la pratique "excessivement délicate" de faire d'autres choses dans la même déclaration.

Donc, pour mes propres règles, l'utilisation d'i ++ comme incrément dans une boucle for est correcte.

Nosredna
la source
Excellent point sur l'option "plusplus" qui n'est que cela, une option. Sur la base des vôtres et d'autres réponses, je pense que j'ai l'impression que ++ en soi ou une boucle for ne sont pas en soi déroutants. La seconde où vous combinez ce ++ dans une autre instruction, votre instruction devient plus difficile à lire et à comprendre dans son contexte.
artlung
6
tout le monde obtient des débordements de tampon. Même OpenSSH avec leur open source et leurs multiples comités de révision
Eric
11
@Eric Revisitant votre commentaire de cinq ans: oh, comme vous aviez raison!
wchargin
27

Dans une boucle, c'est inoffensif, mais dans une déclaration d'affectation, cela peut conduire à des résultats inattendus:

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

L'espace entre la variable et l'opérateur peut également conduire à des résultats inattendus:

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

Dans une fermeture, des résultats inattendus peuvent également être un problème:

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

Et il déclenche l'insertion automatique de points-virgules après une nouvelle ligne:

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

la confusion pré-incrément / post-incrément peut produire des erreurs ponctuelles qui sont extrêmement difficiles à diagnostiquer. Heureusement, ils sont également inutiles. Il existe de meilleures façons d'ajouter 1 à une variable.

Références

Paul Sweatte
la source
13
Mais ils ne sont pas "inattendus" si vous comprenez l'opérateur. C'est comme ne jamais utiliser ==parce que vous ne comprenez pas la différence entre ==et ===.
greg84
1
Exactement. Il y a une question C # qui démystifie les fausses hypothèses.
Paul Sweatte
Je pense que le point de Crockford est que la plupart des programmeurs ne «comprennent pas complètement l'opérateur» même lorsqu'ils pensent qu'ils le font; par conséquent, il y a danger à les utiliser car le risque de malentendu est élevé. Voir le commentaire de @ Paul sur les fausses hypothèses qui renforce l'argument selon lequel les gens comprennent généralement mal comment les opérateurs préfixes et postfixes fonctionnent réellement. Cela dit, j'avoue que j'aime les utiliser, mais pour le bien des autres, j'essaie de limiter leur utilisation aux cas idiomatiques (voir la réponse de cdmckay ).
gfullam
Votre lien Espace blanc semble être rompu.
Ruslan
Qu'est-ce qui est délicat dans votre exemple "d'espaces blancs"? J'obtiens une sortie simple de a: 2 b: 0 c: 1. Je ne vois rien d'étrange ou d'inattendu dans le premier exemple ("déclaration d'affectation") non plus.
Ken Williams
17

Considérez le code suivant

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[i++] = i++;
    a[i++] = i++;
    a[i++] = i++;

puisque i ++ est évalué deux fois, la sortie est (du débogueur vs2005)

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Considérez maintenant le code suivant:

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = ++i;
    a[++i] = ++i;
    a[++i] = ++i;

Notez que la sortie est la même. Maintenant, vous pourriez penser que ++ i et i ++ sont identiques. Ils ne sont pas

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Enfin, considérez ce code

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = i++;
    a[++i] = i++;
    a[++i] = i++;

La sortie est maintenant:

    [0] 0   int
    [1] 1   int
    [2] 0   int
    [3] 3   int
    [4] 0   int
    [5] 5   int

Donc ce ne sont pas les mêmes, mélanger les deux résulte en un comportement pas si intuitif. Je pense que les boucles for sont correctes avec ++, mais attention quand vous avez plusieurs symboles ++ sur la même ligne ou la même instruction

Eric
la source
3
Merci d'avoir fait cette expérience. Code particulièrement "simple", mais qui devient difficile à retenir pour mon cerveau très rapidement. Fait définitivement partie de la catégorie «délicate».
artlung
28
Je me suis arrêté après le premier exemple. Vous avez dit "Considérez le code suivant". Non, personne n'écrit ce code. C'est l'idiot qui écrit ce qui est défectueux, pas une construction de langage.
Sam Harwell
4
Vous avez montré que deux morceaux de code différents produisent des sorties différentes et cela prouve que c'est mauvais?
nickf
7
la conclusion est "attention quand vous avez plusieurs symboles ++ sur la même ligne ou la même instruction". Je ne pense pas que vous l'ayez lu
Eric
1
"puisque i ++ est évalué deux fois" - faux! Modifier une variable deux fois entre des points de séquence et également l'utiliser n'est pas valide en C ++ et conduit à un comportement indéfini. Le compilateur peut donc faire ce qu'il veut. Les résultats présentés ici sont accidentels de l'implémentation du compilateur.
tbleher
16

La nature "pré" et "post" des opérateurs d'incrémentation et de décrémentation peut avoir tendance à prêter à confusion pour ceux qui ne les connaissent pas; c'est une façon dont ils peuvent être délicats.

Paul Sonier
la source
29
D'accord; cependant, un professionnel expérimenté ne doit pas être confondu.
Nate
1
Je pense que cela est similaire aux conseils pour éviter de rendre tout statique ou global. Il n'y a rien de mal à cela en tant que construction de programmation, mais une surutilisation ignorante peut conduire à un mauvais code.
Joel Martinez
6
La question n'est pas de savoir si un bon programmeur pourrait "se frayer un chemin" dans la logique - un bon code ne nécessite idéalement aucun travail pour être compris. Je pense que le point de McWafflestix est simplement que vous ne devriez pas écrire de code qui, après une brève inspection, pourrait entraîner l'ajout de bogues dans deux semaines ou deux ans. Je sais que je suis coupable d'avoir ajouté du code à une routine que je n'ai pas bien comprise :)
Mike
1
@Mike: yah, remarquez comment je n'ai pas spécifié si les opérateurs peuvent être délicats pour l'auteur d'origine du code ou pour les responsables ultérieurs. Généralement, nous essayons de supposer que les codeurs originaux n'utilisent pas de constructions avec lesquelles ils ne sont pas familiers / confortables (malheureusement, c'est souvent une hypothèse incorrecte); cependant, cette familiarité ne s'étend certainement pas aux mainteneurs (et, comme indiqué entre parenthèses ci-dessus, peut même ne pas s'étendre à l'auteur d'origine).
Paul Sonier
J'essaie d'écrire mon code pour que d'autres programmeurs le lisent, mais je n'essaie pas de l'écrire pour que les débutants le lisent.
Luke H
16

À mon avis, «explicite vaut toujours mieux qu'implicite». Parce qu'à un moment donné, vous pouvez être confondu avec cette instruction d'incréments y+ = x++ + ++y. Un bon programmeur rend toujours son code plus lisible.

Sriram
la source
1
Il n'y a rien d'implicite dans x ++ ou ++ y.
Florian F
1
Ce code lisible est délicat ... Je pense qu'il y a une base à la simplicité de votre code, et nous, en tant que communauté, devons prospérer un peu et être en mesure de lire ce qui n'est plus lisible, comme les lignes simples. avec des ternaires imbriqués, pour permettre à plus de choses d'
apparaître
14

La justification la plus importante pour éviter ++ ou - est que les opérateurs retournent des valeurs et provoquent des effets secondaires en même temps, ce qui rend plus difficile de raisonner sur le code.

Par souci d'efficacité, je préfère:

  • ++ i lorsque vous n'utilisez pas la valeur de retour (pas temporaire)
  • i ++ lors de l' utilisation de la valeur de retour (pas de blocage de pipeline)

Je suis un fan de M. Crockford, mais dans ce cas, je ne suis pas d'accord. ++iest 25% moins de texte à analyser que i+=1 et sans doute plus clair.

Hans Malherbe
la source
13

J'ai regardé la vidéo de Douglas Crockford à ce sujet et son explication pour ne pas utiliser l'incrémentation et la décrémentation est que

  1. Il a été utilisé dans le passé dans d'autres langues pour briser les limites des tableaux et causer toutes sortes de méchancetés et
  2. Qu'il est plus déroutant et que les développeurs JS inexpérimentés ne savent pas exactement ce qu'il fait.

Tout d'abord, les tableaux en JavaScript sont de taille dynamique et donc, pardonnez-moi si je me trompe, il n'est pas possible de briser les limites d'un tableau et d'accéder aux données qui ne devraient pas être accessibles en utilisant cette méthode en JavaScript.

Deuxièmement, si nous évitons les choses qui sont compliquées, le problème n'est sûrement pas que nous avons cette fonctionnalité mais le problème est qu'il y a des développeurs qui prétendent faire du JavaScript mais ne savent pas comment ces opérateurs fonctionnent ?? C'est assez simple. valeur ++, donnez-moi la valeur actuelle et après l'expression, ajoutez-en une, valeur ++, incrémentez la valeur avant de me la donner.

Les expressions comme a ++ + ++ b, sont simples à comprendre si vous vous souvenez juste de ce qui précède.

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

Je suppose que vous devez juste vous rappeler qui doit lire le code, si vous avez une équipe qui connaît JS ​​à fond, vous n'avez pas à vous inquiéter. Sinon, commentez-le, écrivez-le différemment, etc. Faites ce que vous avez à faire. Je ne pense pas que l'incrémentation et la décrémentation soient intrinsèquement mauvaises ou génèrent des bogues, ou créent des vulnérabilités, peut-être juste moins lisibles en fonction de votre public.

Btw, je pense que Douglas Crockford est une légende de toute façon, mais je pense qu'il a fait beaucoup peur à un opérateur qui ne le méritait pas.

Je vis pourtant pour me tromper ...

Stuart Wakefield
la source
10

Un autre exemple, plus simple que certains autres avec simple retour de valeur incrémentée:

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

Comme vous pouvez le voir, aucun post-incrément / décrément ne doit être utilisé à l'instruction return, si vous voulez que cet opérateur influence le résultat. Mais le retour ne "capture" pas les opérateurs post-incrémentation / décrémentation:

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}
Evgeny Levin
la source
Une seule de vos fonctions reçoit x comme paramètre
Calimero100582
8

Je pense que les programmeurs devraient être compétents dans la langue qu'ils utilisent; l'utiliser clairement; et utilisez-le bien. Je ne pense pas qu'ils devraient paralyser artificiellement la langue qu'ils utilisent. Je parle d'expérience. Une fois, j'ai travaillé littéralement à côté d'un magasin Cobol où ils n'utilisaient pas ELSE «parce que c'était trop compliqué». Reductio ad absurdam.

Marquis de Lorne
la source
@downvoter Fascinant. Vous ne pensez pas que les programmeurs devraient être compétents dans la langue? Vous pensez qu'ils devraient paralyser artificiellement la langue? Lequel est-ce? Pas de troisième choix ici.
Marquis de Lorne
1
et une upvote pour cet exemple COBOL, me rend encore plus heureux que COBOL s'éteigne avant que je ne me mette au codage
Mark K Cowan
1
@MarkCowan Je ne vois pas pourquoi. Mon point concerne la restriction arbitraire, pas la langue. L'anecdote n'indique rien de mal avec Cobol. Ce qui devait disparaître, c'était cette boutique de programmation, et c'est ce qui s'est produit. Visitez les entrailles de n'importe quelle grande banque et vous découvrirez que Cobol est bel et bien vivant.
Marquis de Lorne
2

Comme mentionné dans certaines des réponses existantes (que je ne peux pas commenter), le problème est que x ++ ++ x est évalué en différentes valeurs (avant vs après l'incrément), ce qui n'est pas évident et peut être très déroutant - si cette valeur est utilisée. cdmckay suggère très judicieusement d'autoriser l'utilisation de l'opérateur d'incrémentation, mais uniquement de manière à ce que la valeur renvoyée ne soit pas utilisée, par exemple sur sa propre ligne. Je voudrais également inclure l'utilisation standard dans une boucle for (mais uniquement dans la troisième instruction, dont la valeur de retour n'est pas utilisée). Je ne peux pas penser à un autre exemple. Ayant moi-même été "brûlé", je recommanderais également la même directive pour les autres langues.

Je ne suis pas d'accord avec l'affirmation selon laquelle cette trop grande rigueur est due au fait que beaucoup de programmeurs JS sont inexpérimentés. C'est exactement le genre d'écriture typique des programmeurs "trop ​​intelligents", et je suis sûr que c'est beaucoup plus courant dans les langages plus traditionnels et avec les développeurs JS qui ont une formation dans ces langages.

Près de Privman
la source
1
Merci pour la réponse. Vous aurez besoin d'une valeur de réputation de 50 ou mieux pour commenter. Voir: stackoverflow.com/faq
artlung
1
@artlung: J'en suis conscient et de la justification derrière cela. Je disais juste que c'est ennuyeux :)
Près de Privman le
2

D'après mon expérience, ++ i ou i ++ n'a jamais causé de confusion autre que lors de la première découverte du fonctionnement de l'opérateur. Il est essentiel pour les boucles les plus élémentaires et les boucles qui sont enseignées par n'importe quel cours de lycée ou de collège enseigné dans des langues où vous pouvez utiliser l'opérateur. Personnellement, je trouve que faire quelque chose comme ce qui est ci-dessous pour mieux regarder et lire que quelque chose avec un ++ sur une ligne distincte.

while ( a < 10 ){
    array[a++] = val
}

En fin de compte, c'est une préférence de style et rien de plus, ce qui est plus important, c'est que lorsque vous faites cela dans votre code, vous restez cohérent afin que les autres travaillant sur le même code puissent suivre et ne pas avoir à traiter la même fonctionnalité de différentes manières .

De plus, Crockford semble utiliser i- = 1, que je trouve plus difficile à lire que --i ou i--

burdz
la source
2

Mon 2cents est qu'ils doivent être évités dans deux cas:

1) Lorsque vous avez une variable qui est utilisée dans de nombreuses lignes et que vous l'augmentez / la diminuez sur la première instruction qui l'utilise (ou la dernière, ou pire encore, au milieu):

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

Dans des exemples comme celui-ci, vous pouvez facilement manquer que la variable soit auto-incrémentée / décrémentée ou même supprimer la première instruction. En d'autres termes, utilisez-le uniquement dans des blocs très courts ou lorsque la variable apparaît dans le bloc sur quelques instructions fermées.

2) En cas de plusieurs ++ et - environ la même variable dans la même instruction. Il est très difficile de se rappeler ce qui se passe dans des cas comme celui-ci:

result = ( ++x - --x ) * x++;

Les examens et les tests professionnels demandent des exemples comme ci-dessus et, en effet, je suis tombé sur cette question en recherchant de la documentation sur l'un d'eux, mais dans la vraie vie, il ne faudrait pas être obligé de penser autant à une seule ligne de code.

zakmck
la source
1

Fortran est-il un langage de type C? Il n'a ni ++ ni -. Voici comment vous écrivez une boucle :

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

L'élément d'index i est incrémenté par les règles de langage à chaque fois dans la boucle. Si vous voulez incrémenter par autre chose que 1, compter en arrière par deux par exemple, la syntaxe est ...

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

Python C-like? Il utilise des compréhensions de plage et de liste et d'autres syntaxes pour contourner la nécessité d'incrémenter un index:

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

Ainsi, sur la base de cette exploration rudimentaire d'exactement deux alternatives, les concepteurs de langage peuvent éviter ++ et - en anticipant les cas d'utilisation et en fournissant une syntaxe alternative.

Fortran et Python sont-ils notablement moins un aimant de bogue que les langages procéduraux qui ont ++ et -? Je n'ai aucune preuve.

Je prétends que Fortran et Python sont semblables à C parce que je n'ai jamais rencontré quelqu'un qui parle couramment C et qui ne pouvait pas avec une précision de 90% deviner correctement l'intention de Fortran ou Python non obscurci.

Thomas L Holaday
la source
1
Ouais, IFortran est des années 1950, tandis que C est des années 1970, donc peut-être que Fortran ne ressemble pas à C. L'exemple de Python dépourvu de quelque chose comme l'opérateur plusplus est intéressant. L'itération sur les structures de données est plus clairement gérée en Python, Python étant JavaScript "différemment" orienté objet. Le conseil de Crockford est peut-être d'utiliser plus de syntaxe de type OO pour l'itération.
artlung