Czy można używać zmiennych w tablicy jako numer indeksu?

0

Witam,
próbuję użyć tablicy w pętli (for), ale cały czas pokazuje mi błąd na zmiennej I i nie wiem czy po prostu ja robię coś źle czy nie można tak w delphi?

var  I : Integer;

  for I := 1 to 10 do
     tablica[I]:=I;
    
 

Bardzo proszę o pomoc.

0

JAKI BŁĄD???

0

Jak najbardziej można tak wykorzystać pętlę for, żeby zmienna sterująca była jednocześnie indeksem tablicy.
Natomiast odnośnie Twojego problemu - podaj odpowiedź na trzy poniższe pytania, bo na razie ciężko coś więcej powiedzieć:

  1. pokaz, w jaki sposób została zadeklarowana tablica
  2. napisz, jaki błąd się pojawia. Myślę, że mając go będziemy mogli coś więcej powiedzieć. Może on wynikać z wielu rzeczy - może tablica nie jest typu integer, a może ma inny rozmiar i w pętli odwołujesz się do elementów poza jej zakresem
    oraz
  3. czy ten błąd pojawia się podczas kompilacji, czy dopiero po uruchomieniu?
0

Dodałem w załączniku

2

po pierwsze - tablicę masz zadeklarowaną jako array[0..9] of string. Oznacza to, że składa się z 10 elementów, ale są one typu string czyli tekstowego. Poza tym numeracja zaczyna się od zera, a kończy na 9.
Ty natomiast starasz się po pierwsze pisać do indeksów od 1 do 10, co oznacza, że ostatni indeks do którego się odwołujesz zwyczajnie nie istnieje, a po drugie - chcesz do tablicy tekstowej zapisać wartości liczbowe.

Najpierw - uporządkuj te indeksy i zrób tak, żeby deklaracja tablicy pokrywała się z pętlą - obecnie w jednym miejscu masz 0-9, a w drugim 1-10.
A po drugie - albo zmień typ tablicy na integer, albo skorzystaj z funkcji, która przerobi liczbę na łańcuch (np. inttostr) i dopiero po takiej konwersji zapisz ją do tablicy.

Tak w ogóle to widzę, że pętla for w pierwszym poście oraz na załączonych zrzutach ekranu to są inne pętle, w związku z czym ciężko mi teraz dać konkretną poradę, bo pierwszy post oraz ostatni zawierają różne treści i nie wiem, do której mam się odnosić i poprawiać. Napisz może co chcesz osiągnąć i co ten program ma robić, to będzie łatwiej Ci pomóc. Zwłaszcza, że widzę parę innych błędów/problemów w Twoim kodzie, ale o tym będzie trochę późnej ;)

I ostatnia prośba - jakbyś mógł kod zamieszczać w treści posta a nie jako obrazki - będzie czytelniej.

0

Program ma podliczać punktacje formuły 1. Czyli za 1 miejsce 20 punktów i tak dalej. Zrobiłem 10 editów, które odpowiadają drużyną (jest ich 10), użyłem fora dlatego, że z założenia maja być tylko 5 okrążeń i na końcu if który ma sprawdzać czy zmienna przypisana do edita jest równa jeden, dwa itd. do 10ciu. I stoję na etapie takim:
P.S Skrypt sie zmienił bo w między czasie go modyfikowałem

unit unit6;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit10: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    Edit9: TEdit;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
var
  Tablica : array[0..9] of string;
var a, b, c, d, e, f, g, h, i, j :String;

implementation

{$R *.lfm}


procedure TForm1.Button1Click(Sender: TObject);
           var n,o,s,r,p,w,u,x,y,z:real;
           var m : integer;
begin

     Tablica[0] := a;
     Tablica[1] := b;
     Tablica[2] := c;
     Tablica[3] := d;
     Tablica[4] := e;
     Tablica[5] := f;
     Tablica[6] := g;
     Tablica[7] := h;
     Tablica[8] := i;
     Tablica[9] := j;
     n:=StrToint(Edit1.text);
     o:=StrToint(Edit2.text);
     s:=StrToint(Edit3.text);
     r:=StrToint(Edit4.text);
     p:=StrToint(Edit5.text);
     w:=StrToint(Edit6.text);
     u:=StrToint(Edit7.text);
     x:=StrToint(Edit8.text);
     y:=StrToint(Edit9.text);
     z:=StrToint(Edit10.text);
     for m:= 1 to 5 do
       if n == 1 Tablica[0]:=20+a;
       if n == 2 Tablica[0]:=18+a;

end;

end.
2
Tablica[0] := a;
Tablica[1] := b;
Tablica[2] := c;
Tablica[3] := d;
Tablica[4] := e;
Tablica[5] := f;
Tablica[6] := g;
Tablica[7] := h;
Tablica[8] := i;
Tablica[9] := j;

Przypisujesz do tablicy wartości tych zmiennych, a nawet nie nadałeś im początkowej wartości. Jako że zmienne od a do j są globalne, to ich wartości są inicjalizowane pustymi ciągami znaków. Więc do każdej komórki tablicy i tak podajesz puste wartości.

n:=StrToint(Edit1.text);
o:=StrToint(Edit2.text);
s:=StrToint(Edit3.text);
r:=StrToint(Edit4.text);
p:=StrToint(Edit5.text);
w:=StrToint(Edit6.text);
u:=StrToint(Edit7.text);
x:=StrToint(Edit8.text);
y:=StrToint(Edit9.text);
z:=StrToint(Edit10.text);

Zmienne od n do z są typu Real, czyli zmiennoprzecinkowego, a Ty próbujesz do nich wpisać liczby całkowite. Zamiast StrToInt użyj StrToFloat.

damianmajor987 napisał(a):

P.S Skrypt sie zmienił bo w między czasie go modyfikowałem

To nie jest skrypt – te pisze się w językach skryptowych, do których Delphi się nie zalicza.

0

Dziękuję bardzo za wszelkiej maści wskazówki mój błąd odnośnie skryptu wziął się stąd, że przygodę z programowaniem zacząłem z językami skryptowymi i dlatego ciężko mi jest się przestawić zwłaszcza na deklarowanie typu zmiennej. Jesteście mi w stanie powiedzieć jeszcze jak zrobić w if'ie, że jeżeli coś = coś to zrób tamto, bo dwa równa się nie działają ?

1

Bo w przeciwieństwie do innych języków, dialekty Pascala wykorzystują operator = jak pan bug przykazał do porównania operandów, a nie do przypisania.

if cos = cos then
  zrob_cos;

Zacznij może od jakiegoś kursu, bo masz poważne braki z zakresu absolutnych podstaw. W razie czego tutaj jest dokumentacja, w której znajdziesz wszystko czego potrzebujesz.

0

No i pytanie - czy teraz już wiesz, jak osiągnąć to, co chciałeś, czy jeszcze nadal masz problem?
Wczoraj poszedłem spać, ale widzę, że temat ładnie pociągnął dalej @furious programming. Jakby co to śmiało pisz :)

1

Takich rzeczy jak w tym programie się nie robi – czyli deklarowania mnóstwa zmiennych pomocniczych, w dodatku globalnych i o nic nie mówiących, jednoliterowych identyfikatorach. Po to są tablice, listy, kolejki i inne indeksowane kontenery, aby mieć jedną zmienną grupującą dla dowolnej liczby elementów.

Takich rzeczy jak to niżej też się nie robi:

n:=StrToint(Edit1.text);
o:=StrToint(Edit2.text);
s:=StrToint(Edit3.text);
r:=StrToint(Edit4.text);
p:=StrToint(Edit5.text);
w:=StrToint(Edit6.text);
u:=StrToint(Edit7.text);
x:=StrToint(Edit8.text);
y:=StrToint(Edit9.text);
z:=StrToint(Edit10.text);

Tutaj powinno się zastosować metodę FindChildControl i na podstawie nazwy wyłapywać kontrolki w pętli, rzutować na określony typ końcowy (czyli TEdit) i na koniec konwertować tekst na liczbę (za pomocą ogólnych funkcji lub tych z helperów – dla zwiększenia czytelności).

0

Dziękuje za wszysrtkie rady @furious programming.
Nie dział mi w moim programie jeszcze jedna rzecz, ponieważ doedukowałem się troszkę i dowiedziałem się, że ta funkcja Inc() zwiększa o jeden ale u mnie nie działa. Dodaje jeszcze łańcuch bo widzę, że tam też sypie błędem.

var m : integer; 
for m:= 1 to 5 do 
    begin

     [reszta programu]

     Inc(m);
   
    end;

  ShowMessage('Team1 '+a+'| Team 2 '+b+'| Team 3 '+c+'| Team 4 '+d+'| Team 5 'e'| Team 6 '+f+'| Team 7 '+g+'| Team 8 '+h+'| Team 9 '+i+'| Team 10 '+j);    
 
end.

Błąd w załączniku.

2
damianmajor987 napisał(a):

Nie dział mi w moim programie jeszcze jedna rzecz, ponieważ doedukowałem się troszkę i dowiedziałem się, że ta funkcja Inc() zwiększa o jeden ale u mnie nie działa.

Iterator pętli – w Twoim kodzie zmienna m – jest inkrementowany w pętli for automatycznie, więc nie musisz sam tego robić. Poza tym iteratora pętli for w ogóle nie można modyfikować, bo jest nietykalny – tego właśnie dotyczy błąd kompilacji.

3

W Twoim przykładzie zmienna m jest zmienną sterującą pętli for. NIE WOLNO zmieniać jej wartości podczas pracy pętli, czyli to, co zrobiłeś w bloku begin .... end uruchamianym w ramach pętli for. Sama pętla już wie, że ma za każdym przebiegiem zwiększyć wartość zmiennej.

0

bez wnikania w szczegóły, ale taki kod to już na pierwszy rzut oka jakiś koszmarek

n:=StrToint(Edit1.text);
o:=StrToint(Edit2.text);
s:=StrToint(Edit3.text);
r:=StrToint(Edit4.text);
p:=StrToint(Edit5.text);
w:=StrToint(Edit6.text);
u:=StrToint(Edit7.text);
x:=StrToint(Edit8.text);
y:=StrToint(Edit9.text);
z:=StrToint(Edit10.text);
0

Tylko i tak wywala błąd odnośnie ShowMessage()

ShowMessage('Team1 '+a+'| Team 2 '+b+'| Team 3 '+c+'| Team 4 '+d+'| Team 5 'e'| Team 6 '+f+'| Team 7 '+g+'| Team 8 '+h+'| Team 9 '+i+'| Team 10 '+j);    
1
damianmajor987 napisał(a):

Tylko i tak wywala błąd odnośnie ShowMessage()

ShowMessage('Team1 '+a+'| Team 2 '+b+'| Team 3 '+c+'| Team 4 '+d+'| Team 5 'e'| Team 6 '+f+'| Team 7 '+g+'| Team 8 '+h+'| Team 9 '+i+'| Team 10 '+j);    

któraś ze zmiennych od "a" do "j" nie jest stringiem

2

błąd masz we fragmencie Team 5 'e'| Team 6 - przed oraz po e nie dałeś znaku "dodać" ;)

0

Teraz doszedłem do wniosku, że wszystkie te zmienne są typu integer i nie wiem jak jak to przekonwertować w senie wiem, że IntToStr, ale do tego trzeba stworzyć nowe zmienne i przypisać do tego zmienne których typ chcemy zmienić. Czy idzie to ominąć jakoś ?
Próbowałem, też funkcją tylko nie wiem jak ją zaimplementować do kodu.

  function IntToStr(Value: Integer): string; overload;  
1

Nie musisz tworzyć żadnych dodatkowych zmiennych, możesz wykonać konwersję w locie - coś na kształt

showmessage ('Twoj wynik to ' + inttostr(wynik));

chyba, że chodziło Ci o coś innego - ale w takim razie napisz jaśniej, w czym jest problem.

0

Teraz mam taki problem, że nie che chyba wyjść z if'a ponieważ nie pokazuje się nic czyli tak jak by nie było ShowMessage()

   for m:= 1 to 5 do
       begin   
          
        treść

      end;
    ShowMessage('Team1 '+inttostr(a)+'| Team 2 '+inttostr(b)+'| Team 3 '+inttostr(c)+'| Team 4 '+inttostr(d)+'| Team 5 '+inttostr(e)+'| Team 6 '+inttostr(f)+'| Team 7 '+inttostr(g)+'| Team 8 '+inttostr(h)+'| Team 9 '+inttostr(i)+'| Team 10 '+inttostr(j)); 
end.
1

nie za bardzo wiem, o jakiego if'a Ci chodzi, bo w pokazanym fragmencie jest pętla for. Poza tym za bardzo nie ma opcji, żeby pętla for się nie zakończyła, a co za tym idzie - za bardzo nie wiem, dlaczego showmessage się nie wykonuje. Nawet, jakby zmienne w niej użyte były puste, to i tak powinna się pokazać niezmienna treść.
Prawdopodobnie coś, czego nam nie pokazujesz i co się zawiera we fragmencie begin treść end; dokonuje jakiejś czarnej magii, ale ponieważ tego nie wkleiłeś, ciężko się do tematu ustosunkować. Poza tym rozumiem, że obecnie wszystko się kompiluje i uruchamia, nie ma żadnych błędów, a jedyny niepożądanym efektem jest brak tego showmessage - mam rację?

0

@cerrato wiesz co w pętli mam same if'y

  implementation

{$R *.lfm}


procedure TForm1.Button1Click(Sender: TObject);
           var n,o,s,r,p,w,u,x,y,z:real;
           var m : integer;
begin
     a:=0;b:=0;c:=0;d:=0;e:=0;f:=0;g:=0;h:=0;i:=0;j:=0;
     Tablica[0] := a;
     ...
     Tablica[9] := j;
     n:=StrToFloat(Edit1.text);
     ...
     z:=StrToFloat(Edit10.text);

     for m:= 1 to 5 do
       begin

       if n = 1 then a:=a+25;
       ...
       
       if z = 10 then j:=j+1;

       end;
    ShowMessage('Team1 '+inttostr(a)+'| Team 2 '+inttostr(b)+'| Team 3 '+inttostr(c)+'| Team 4 '+inttostr(d)+'| Team 5 '+inttostr(e)+'| Team 6 '+inttostr(f)+'| Team 7 '+inttostr(g)+'| Team 8 '+inttostr(h)+'| Team 9 '+inttostr(i)+'| Team 10 '+inttostr(j));

end;

end.                       

tak wygląda cały praktycznie kod

1

jeżeli cała procedura wygląda w stylu tego, co pokazałeś i nie ma w niej żadnych dziwnych instrukcji w stylu break czy exit to za bardzo nie mam pojęcia, czemu ten showmessage się nie wywołuje. Najprościej będzie skorzystać z najbardziej uniwersalnej metody pra-programistów, czyli tzw. dupa debugging :D

Upewnij się najpierw, czy procedura przypisana do zdarzenia onclick w ogóle się uruchamia. W tym celu zaraz po begin rozpoczynającym procedurę wstaw coś na kształt showmessage ('start');. Jeśli się odpali, to znaczy że procedura zostaje poprawnie wywołana, w takim razie usuń tą wiadomość, a umieść po beginie w pętli for m:= 1 to 5 polecenie shomessage ('przebieg numer ' + inttostr(m)); i sprawdź, czy zostanie wywołane 5 razy z kolejnymi numerami.

Jak to zrobisz to daj znać, co wyszło z w/w testów.

0

Nie wykonuje się w ogóle dałem go od razu po beginie i nic. Dodam, że Procedura odnosząca się do pierwszego buttona ustawiła się sama po dwukrotnym kliknięciu w buttona.

  unit unit6;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit10: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    Edit9: TEdit;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;
var
  Tablica : array[0..9] of integer;
var a, b, c, d, e, f, g, h, i, j :integer;   

Teraz to jest już w pełni mój kod 1 do 1 (no oczywiście bez skróceń kodu w postaci 3 kropek)

2

A czy w object inspector w zakładce events masz wskazaną odpowiednią procedurę przy odpowiednim zdarzeniu dla tego przycisku, który ma reagować na wciśnięcie?

screenshot-20181204224118.png

0

Tak nie było przypisane, wszystko działa tylko z tym, że wartość m (czyli zmienna z for'a) po jednokrotnym naciśnięciu przycisku button od razu przyjmuje wartość 5.
A powinna dopiero po piątym naduszeniu przycisku button.

0

pokaż gdzie wstawiłeś tego kontrolnego ShowMessage'a. Podejrzewam, że po end zamykającym blok wykonywany w ramach pętli for.

0
cerrato napisał(a):

pokaż gdzie wstawiłeś tego kontrolnego ShowMessage'a. Podejrzewam, że po end zamykającym blok wykonywany w ramach pętli for.

Odpowiedz brzmi nie dałem go od razu po begin od procedury, ale kiedy wstawiłem ShowMessage ('przebieg numer ' + inttostr(m)); od razu po begin w pętli for to wyskakuje mi okienko przebieg numer 1 i na dole okienka jest przycisk ok i po kliknięciu od razu pojawia się kolejne tylko, że z dwójką i tak leci do piątki.

1

Czyli wszystko jest tak, jak być powinno - pętla wykonuje się 5 razy z wartościami od 1 do 5.
Podejrzewam, że opisany wcześniej błąd - czyli brak showmessage z "długim" komunikatem, który powinien się pojawić po zakończeniu wykonania pętli for też się pojawia, ponieważ problemem było przypisanie procedury do obsługi zdarzenia.
Czy w takim razie w tej chwili wszystko działa, czy masz jeszcze jakiś problem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1