8
votes

Quelle est la variable de boucle après une boucle à Delphi?

dans Delphi, envisagez

var
  i: integer;

begin

  for i := 0 to N do
  begin
    { Code }
  end;


4 commentaires

Êtes-vous même certain que N est dans la portée après le pour boucle? Je vérifierais cela en premier - parce que je soupçonne que ce n'est peut-être pas.


@Lbushkin: Cela dépend de la déclaration de N. Mais dans l'exemple de code ci-dessus, j'utilise N comme un "espace réservé" pour tout ce qui pourrait être la dernière valeur de la variable de boucle.


@Lbushkin, vous pouvez être absolument certain que n sera dans la portée de la boucle car il était évidemment dans la portée avant la boucle (sinon que le code n'aurait pas compilé). La portée dans Delphes ne change pas la fonction moyenne; Il commence au début d'une fonction et se termine à la fin.


> Mais pouvez-vous compter sur cela? - NON


6 Réponses :


6
votes

Je suggérerais que l'utilisation d'un tandis que est plus claire si vous devez utiliser l'index de boucle après la boucle: xxx

après cette boucle se termine, vous < em> savoir que i sera n + 1 (ou supérieur si n aurait pu être inférieur à zéro). < / p>


2 commentaires

Oui, c'est une très bonne méthode. Après tout, chaque boucle peut être écrite comme une boucle de cette façon, mais sans aucune "magie de compilateur".


Vous pouvez utiliser inc (i) au lieu de i: = i + 1 , mais IIRC le compilateur les traitera de toute façon.



7
votes

Le compilateur émet un avertissement si vous utilisez la variable de boucle après la boucle, vous devez donc le considérer non défini.


0 commentaires

25
votes

Non, Delphi ne garantit pas de valeur. En dehors de la boucle, la variable est indéfinie - et IIRC Le Guide de la langue énoncipliquement indique donc - cela signifie que les nouvelles implémentations de compilateur sont libres de modifier la valeur que la variable peut avoir à l'extérieur de la boucle en raison de la mise en œuvre réelle.


10 commentaires

C'est correct. La variable est spécifiquement documentée pour être non définie après la fin de la boucle. Si vous avez besoin d'une variable définie après la boucle, utilisez ou répétez


En fonction de la manière dont la variable de boucle est utilisée dans la boucle, le compilateur peut même l'éliminer complètement et simplement utiliser un pointeur pour itération à travers les éléments d'un tableau, par exemple.


... est indéfini ... Sauf si vous terminez la boucle avec la déclaration «Break». Dans ce cas, la valeur est définie (la dernière valeur que le compteur de boucle avait avant que la «pause» a été exécutée).


GABR a raison. Si vous quittez la boucle avec break , la valeur de la variable de contrôle sera valide. De même si vous laissez la boucle avec sortie . La documentation le dit. Sans-documents, mais toujours généralement accepté comme vrai, c'est laisser la boucle via lever ou goto préservera également la valeur de la variable.


Si la variable n'est pas utilisée à l'intérieur de la boucle, le compilateur peut générer du code qui compte de n à 0, même si la source indique compter de 0 à N, car c'est légèrement plus efficace. Je n'ai aucune idée de quelle valeur la variable aurait après la boucle dans ce cas.


@Chris: Nick était cependant légèrement faux. La variable compteur est définie si la boucle est terminée par une pause ou une sortie (bien qu'avec une sortie, la validité de la variable de compteur est discutée car le code suivant ne fonctionnera pas comme le flux de contrôle quittera la procédure contenant la simple variable locale que A pour les compteurs de boucle).


Que se passe-t-il si le compilateur élimine la variable alors que Bauer dit et une pause est rencontrée?


@Deltics: pas nécessairement de théâtre, car la boucle (et donc la sortie EXIT ) peut être placée à l'intérieur d'un essayer ... enfin bloc, etc. lors de l'exécution Quitter Vous avez toujours l'occasion de (essayer de) lire la valeur du compteur avant de quitter la procédure. Néanmoins, pas un scénario très courant, probablement.


@Andriy m: Oui, selon la documentation actuelle, il impliquerait que d'utiliser des actes de rupture ou de sortie pour garantir la valeur de la variable de comptoir: "Une fois la déclaration à la fin (à condition que cela n'ait été forcé par une pause ou une procédure de sortie) , la valeur du compteur n'est indéfinie ».


@ldsandon: Cela m'a déjà expliqué que si la variable de comptoir est référencée dans la boucle, elle ne sera pas éliminée et qui correspond certainement à mon expérience. Ils ne pouvaient pas changer ce comportement (peu importe ce que la documentation peut avoir ou non jamais dit) sans risquer de casser beaucoup de code existant.




1
votes

Autant de personnes indiquées, la variable I est censée être indéfinie après la boucle. Dans l'usage réel du monde, il sera défini à la dernière valeur qu'il avait précédée de "casser" ou à N + 1 si la boucle fonctionne à terme. Ce comportement ne peut pas être invoqué cependant, car il est clairement spécifié, il n'est pas censé fonctionner.

aussi, parfois, i ne sera même pas attribué. J'ai rencontré ce comportement principalement avec l'optimisation allumée.

pour code comme celui-ci xxx

donc ... si vous voulez connaître la valeur de i après La boucle, il est préférable de la pratique d'assigner à une autre variable avant de sortir de la boucle.


0 commentaires

1
votes

Ne comptez jamais sur la valeur de la variable de la variable, après la boucle.

Vérifiez votre sortie du compilateur. Delphi Compiler vous avertit de cela. Faites confiance à votre compilateur.

  1. Ne cachez jamais les astuces et avertissements de votre compilateur avec {$ avertissements off}!
  2. Apprenez à traiter les informations comme avertissements et avertissements comme erreurs!
  3. Optimisez votre code jusqu'à ce que vous ayez zéro des astuces et des avertissements (sans violer la règle 1).

6 commentaires

Eh bien, c'est peut-être un peu aussi "strict". Par exemple, dans de nombreux cas, l'avertissement "Valeur de retour de la fonction ... peut être indéfini" n'est pas pertinent.


Il est très rare que le compilateur indique que quelque chose peut être indéfini quand ce n'est pas possible. Les seuls cas que j'ai constatés impliquent deux conditionnels qui attribuent des résultats et de manière intrinsèquement l'un d'entre eux doivent être exécutés. Je considère que cela vaut un peu de code supplémentaire pour supprimer tous les avertissements même lorsque je sais qu'ils sont inoffensifs.


Cela se produit souvent si vous ROUGEZ une exception à l'intérieur de la fonction ou si vous mélangez la méthode EXIT (VOTRE> EXIT (RETOURNUELLE) avec l'ancienne école résultat: = Méthode.


"Par exemple, dans de nombreux cas, l'avertissement" Valeur de retour de la fonction ... peut être non défini "est hors de propos" - apprendre à initialiser cette variable. Quoi qu'il en soit, ces cas ne sont pas tellement nombreux.


"Je considère que cela valait un peu de code supplémentaire pour supprimer tous les avertissements même lorsque je sais qu'ils sont inoffensifs." - Nice n'est-il pas agréable d'avoir une sortie de compilateur propre? :)


@Altar: Oui, c'est en fait un gain seul. Il facilite également les problèmes les plus graves à repérer dans le journal.