2017-10-08 9 views
-2

Ce problème apparaît uniquement avec les nombres, plus grand, puis 12 inclus.Pour la boucle continuez après avoir atteint le but. Delphi

Ces deux images capturées en même temps. Comment c'est possible?

For La boucle doit passer de 0 à 12-1 = 11, n'est-ce pas? Néanmoins, quand j'utilise la boucle while à la place, cela fonctionne très bien.

Est-ce ma faute ou celle de Delphi?

P.S. Code ci-dessous. 1 1

unit Unit1; 
interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, Grids; 

type 
    TForm1 = class(TForm) 
    StringGrid1: TStringGrid; 
    Button1: TButton; 
    Edit1: TEdit; 
    Button2: TButton; 
    Label1: TLabel; 
    Button3: TButton; 
    Label2: TLabel; 
    Label3: TLabel; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure StringGrid1KeyPress(Sender: TObject; var Key: Char); 
    procedure Button3Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 
    n:Integer; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); //Button, that sets array length 
var 
    i, index:Integer; 
begin 
    val(Edit1.Text, n, index);     
    if(index<>0) then 
    begin 
     ShowMessage('Wrong number'); 
     Edit1.Clear(); 
     exit; 
    end; 
    StringGrid1.ColCount:=n; 
    for i:=0 to n-1 do       
     StringGrid1.Cells[i,0]:=IntToStr(i+1); 
    StringGrid1.SetFocus(); 
end; 

procedure TForm1.Button2Click(Sender: TObject);  //Main button 
var 
    i, index:Integer; 
    a:array[0..10] of Real; 
    denom, sum:Real; 
begin 
    i:=0; 
    sum:=0; 
    denom:=-1; 

//that for loop from screenshot is here 

    for i:=0 to n-1 do 
    //while i<=(n-1) do 
    begin 
    Val(StringGrid1.cells[i,1], a[i], index);  
    if(index<>0) then 
    begin 
     ShowMessage('Wrong number with ' + IntToStr(i+1) + ' Id'); 
     StringGrid1.Col:=i; 
     StringGrid1.Row:=1; 
     StringGrid1.SetFocus(); 
     exit; 
    end; 
    a[i]:=a[i]/denom;        
    sum:=sum+a[i]; 
    StringGrid1.Cells[i,2]:=FloatToStrF(a[i],ffFixed,5,3);  
    denom:=-denom*(i+2); 
    //Inc(i); 
    end; 
    Label2.Caption:=FloatToStrF(sum,ffFixed,5,3); 
end; 

//code down bellow just allow to go to another cell by pressing Enter 


procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char); 
begin 
    if (Key=#13) and (StringGrid1.Col=(n-1)) then 
     Button2.SetFocus() 
    else if (Key=#13) and (StringGrid1.Col<>(n-1)) then 
     StringGrid1.Col:=StringGrid1.Col+1; 
end; 

procedure TForm1.Button3Click(Sender: TObject); 
begin 
    Close(); 
end; 

end. 
+3

[Regardez ici] (https://stackoverflow.com/a/35478474/2292722) pour une explication de la façon dont la variable * de contrôle de boucle * est utilisée dans diverses situations. –

+0

Une boucle avec une instruction de sortie? Je n'ai même pas besoin de lire votre code pour connaître leur logique défectueuse ici. Si vous devez arrêter une boucle sur une condition, utilisez une boucle conditionnelle (repeat until ou while do) et non une boucle uncondition. De même, tout le code après votre boucle n'est pas exécuté lorsque l'exit est déclenché. C'est un code très illisible – GuidoG

Répondre

-2

Tableau a taille est plus petite, puis la quantité de cellules.

+1

Bien que vous ayez raison, vous n'expliquez pas pourquoi cela pourrait être important. – Dsm

+0

Vous devriez soit ajouter une explication à votre réponse comme @Dsm dit, ou le supprimer, imo. – MartynA

-1

Comme pour répondre à votre question de « comment est-ce possible » ...

Dans votre écran, n est 12. Comme l'a souligné Kermation, indice le plus élevé d'un est de 10, alors quand i est 11, sauf si vous avez activé la vérification de gamme, lorsque vous écrivez à [11] (i = 11), vous écrasez autre chose. C'est dans la zone de variable locale donc il peut s'agir de i, par exemple, ou même de variables internes que vous ne pouvez pas voir comme la limite utilisée pour la boucle for, qui est calculée au début de la boucle. Une fois que vous autorisez cela, presque tout est possible.

Bien sûr, la manifestation exacte du problème sera très d'une version du compilateur à l'autre. Dans une version, vous pourriez vous en sortir. dans un autre tu ne le feras pas.