Ergebnis 1 bis 11 von 11

Thema: Variablentypen in Delphi

  1. #1

    Variablentypen in Delphi

    Ich beschäftige mich zurzeit mit Delphi, habe auch einige Tutorials durchgearbeitet (u. a. von Delphi-Treff). Ich habe folgenden Code aus einem Tutorial abgetippt:
    ----------------------------------------------------------------------
    var n, i : longint; //Drei Variablen werden deklariert
    summe : real;
    begin

    n := strtoint(edit1.text); //edit1.text ist ein String, durch StrToInt wird die manuelle Eingabe in einen Integer umgewandelt und als Variable n definiert
    summe := 0; //real-Werte sind von Anfang an rein zufällig, deshalb wird summe auf 0 gesetzt

    for i := 1 to n do //i ist gleich 1, n hat den manuell eingegebenen Wert ausm Edit-Feld, von i bis n wird hochgezählt
    begin
    summe := summe+i; //Solange die Schleife läuft, ist die Summe gleich Summe + Wert von i, beim ersten Mal also 0 = 0 + 1
    end;

    label1.caption := 'S = ' + floattostr(summe); //Wenn Schleife durchbrochen -> auf der Labelcaption (Labeloberfläche) wird S, ein Leerzeichen sowie der Wert der Summe angezeigt.

    end;
    -----------------------------------------------------------------------

    Dazu habe ich folgende Fragen:

    1) Hab das ganze in Delphi eingegeben und bekomme die Fehlermeldung "Edit1 ist kein gültiger Integerwert". Woran kann das liegen? =0

    2) Warum weist man den Variablen n, i, & Summe Typen wie jetzt longint oder real zu, wenn sie doch nach begin sowieso wieder umgewandelt werden?

    3) Und wieso wird bei der Deklaration n von einem String in einen Integer umgewandelt (strtoint), obwohl es doch von Beginn an als Integer gekennzeichnet wurde (n; i : longint) und nicht als String?

    4) Die Variable n hat hier keinen Anfangswert, wie kann man also mit der for-Schleife von i (hat ja den Wert 1 bekommen) bis nach n (hat keinen Wert) hochzählen?

    Nachtrag: Hab den obigen Code durch die Antworten hier im Thread mal durchkommentiert, hoffe mal dass es so richtig ist ^^'

    Geändert von Davy Jones (11.05.2008 um 00:54 Uhr)

  2. #2
    Lustigerweise lassen sich wohl alle Fragen mit einer Antwort abhandeln.
    Vorne weg: Ich kann kein Delphi, ich versuche das jetzt nur mit allgemeinem Programmiersprachenverständnis zu lösen. ^^'

    edit1 kommt überhaupt nur einmal vor, nämlich in dem strtoint() Aufruf. Nicht vorher, nicht danach. Foglich kann der Fehler wohl nur da auftreten, und dass es ein Integer sein soll, liegt vermutlich daran, dass nur die dieses ".text" hintendran verstehen... oder so.

    Mit Delphis Datentypen kenne ich mich nicht aus, aber wo werden die Variablen danach umgewandelt? Erst werden sie deklariert und dann definiert, ganz einfach. Sollte z.B. strtoint kein longint zurückliefern, wirds vermutlich automatisch konvertiert.

    Und n hat durchaus einen Wert - nämlich den Integer Wert des zum Text konvertierten Integers edit1

    So verstehe ich das. Also liegt der einzige Fehler wohl darin, dass edit1 nicht existiert *shrug*

    Vermutlich hab ich mich grad voll in die Nesseln gesetzt...

  3. #3
    Ich vermute jetzt einfach mal, dass "edit1" ein Textbox-Steuerelement ist. Und "text" ist dann entsprechend die Eigenschaft, der eben den eingegebenen Text enthält.
    Hast du auf deinem Formular denn auch ein Textboxsteuerelement, das genau diesen Namen hat? Da würde ich nämlich das Problem sehen.

  4. #4
    1) Ich würd ma tippen, dass man "edit1" so nicht benutzen kann.
    Es wird wohl für eine Art Variable dienen, die man per Eingabe bei Programmstart setzt.

    Soll heißen man tippt in die Eingabeaufforderung oder was auch immer z.B. 25 ein. Das Ding wird natürlich als String gelesen und durch die strtoint dann in den passenden int 25 konvertiert.

    "edit1" ist natürlich keine Zahl an sich, da muss also was geändert werden.

    2) Ich denke auch, dass sie nicht umgewandelt werden...

    3) Wie 1). Ich denke, dass das Teil nur als Synonym für die Eingabe steht. (die natürlich ne Zahl sein sollte)

    4) Auch klar.


    Dazu sei gesagt, dass ich mich mit Delphi auch nicht wirklich auskenne... aber in C/C++ kann man das so machen wie ichs beschrieben hab. Delphi ist einfach zu lang her und wirklich lange hab ich damit nix gemacht...

    edit: Heh, ich tippe zu lang. Scheint dann aber wohl so inner Art zu sein.

  5. #5
    Zitat Zitat von Davias Beitrag anzeigen
    1) Hab das ganze in Delphi eingegeben und bekomme die Fehlermeldung "Edit1 ist kein gültiger Integerwert". Woran kann das liegen? =0
    Das was du im Edit stehen hast ist nicht umwandelbar. Eingaben wie 0 gehen, 0asd nicht. Sollte man eigentlich vorher sowieso verhindern bzw. SpinEdits nehmen fuer Zahleneingaben.

    Zitat Zitat von Davias Beitrag anzeigen
    2) Warum weist man den Variablen n, i, & Summe Typen wie jetzt longint oder real zu, wenn sie doch nach begin sowieso wieder umgewandelt werden?
    Schrottiger Beispielcode halt.

    Zitat Zitat von Davias Beitrag anzeigen
    3) Und wieso wird bei der Deklaration n von einem String in einen Integer umgewandelt (strtoint), obwohl es doch von Beginn an als Integer gekennzeichnet wurde (n; i : longint) und nicht als String?
    n ist ein Integer und Edit.Text ist ein String StrToInt wandelt den String (Edit1.Text) in einen Integer um. longint solltest du aber eigentlich nicht schreiben, Int64 ist die korrekte Delphi-Bezeichnung
    (andere gehen zwar aus Kompatibilitaet auch aehnlich wie Word oder DWord in Delphi, aber die richtigen Typen sind besser).

    Zitat Zitat von Davias Beitrag anzeigen
    4) Die Variable n hat hier keinen Anfangswert, wie kann man also mit der for-Schleife von i (hat ja den Wert 1 bekommen) bis nach n (hat keinen Wert) hochzählen?
    n bekommt den Wert von Edit1.Text. Sollte der kleiner als 1 sein laeft die for Schleife halt nicht an.

    Zitat Zitat von dead_orc Beitrag anzeigen
    Mit Delphis Datentypen kenne ich mich nicht aus, aber wo werden die Variablen danach umgewandelt? Erst werden sie deklariert und dann definiert, ganz einfach. Sollte z.B. strtoint kein longint zurückliefern, wirds vermutlich automatisch konvertiert.
    Jo, Delphi Konvertiert soweit es geht immer. Spontan faellt mir nur String -> PChar ein bei der man PChar() zum Umwandeln angeben muesste.

    Zitat Zitat von The_Best_Isaac Beitrag anzeigen
    Ich vermute jetzt einfach mal, dass "edit1" ein Textbox-Steuerelement ist. Und "text" ist dann entsprechend die Eigenschaft, der eben den eingegebenen Text enthält.
    Hast du auf deinem Formular denn auch ein Textboxsteuerelement, das genau diesen Namen hat? Da würde ich nämlich das Problem sehen.
    "Edit1 ist kein gültiger Integerwert" sagt schon aus, dass er Edit1 duraus findet (sonst wuerde er auch nicht kompilieren koennen), nur ist das String-Property Text nicht in einen Integer umwandelbar.

    edit:
    Mist, stimmt wenn er sagt Edit1 waere kein Wert findet er es wohl in der Tat nicht. Drop einfach mal ein TEdit aus der Komponenten-Liste auf dein Formular und aender das Text-Property in "0" oder so, sollte gehen. Oder gleich ein TSpinEdit (Registerkarte Examples/Beispiele) und dann statt "StrToInt(Edit1.Text)" "SpinEdit1.Value", das ist dann schon im Int-Format.

    Geändert von Crash-Override (10.05.2008 um 18:37 Uhr)

  6. #6
    Okay, der Code ist anscheinend doch korrekt, habe das Ganze zum laufen gebracht:

    http://img383.imageshack.us/img383/2544/snag0123im7.png
    Testplay in der oberen Menüleiste anwählen, ins Edit-Feld eine Zahl eingeben, Button drücken. Anschließend wird im Label-Feld das verrechnete Ergebnis angezeigt.

    Zitat Zitat von The_Best_Isaac
    Hast du auf deinem Formular denn auch ein Textboxsteuerelement, das genau diesen Namen hat? Da würde ich nämlich das Problem sehen.
    Ja, der Code war falsch abgelegt, er musste in die Prozedur vom Button rein. Und den gabs vorher irgendwie nicht xD

    Zitat Zitat von Crash-Override
    SpinEdits
    Mein Wissen erstreckt sich leider nur über die üblichen Sachen wie Label, Edit & Button + for-, while-, & repeat-until-Schleife sowie Variablendeklaration, if-Abfrage mit else... yoah, das wars. Bin blutiger Anfänger, sozusagen

    Zitat Zitat von Crash-Override
    Zitat Zitat von Davias
    2) Warum weist man den Variablen n, i, & Summe Typen wie jetzt longint oder real zu, wenn sie doch nach begin sowieso wieder umgewandelt werden?
    Schrottiger Beispielcode halt.
    Wie meinst du das? Der Code ist ja nun korrekt, aber gibt es denn eine Alternative oder kann man die Variablen gleich von Anfang an mit ihrem tatächlichen Typ definieren?

    Zitat Zitat von Crash-Override
    Zitat Zitat von Davias
    3) Und wieso wird bei der Deklaration n von einem String in einen Integer umgewandelt (strtoint), obwohl es doch von Beginn an als Integer gekennzeichnet wurde (n; i : longint) und nicht als String?
    n ist ein Integer und Edit.Text ist ein String. StrToInt wandelt den String (Edit1.Text) in einen Integer um.
    Wenn ich richtig verstehe bewirkt StrToInt also, dass ich im Edit-Feld nur noch ganze Zahlen eingeben kann.

    Also gilt die Umwandlung nicht für meine Variable n, sondern für Edit1.Text?
    Das würde Sinn machen, denn n ist ein Integer und Edit1-Text wäre es nach der Umwandlung auch. Das Edit-Feld wird n also zugeordnet und alles was ich in dieses Feld nachher reinschreibe wird mit dieser Vari verrechnet.

    HEY, ich verstehe es. Unglaublich =0

    Deine Antwort auf 4) verstehe ich somit auch, n ist gleich Wert des umgewandelten Edit-Feldes (in welches man im Testplay manuell eine Zahl eingibt). Darum kann n auch in der for-schleife verwendet werden, weil diese Variable halt einen Wert hat.

  7. #7
    Zitat Zitat von Davias Beitrag anzeigen
    Wenn ich richtig verstehe bewirkt StrToInt also, dass ich im Edit-Feld nur noch ganze Zahlen eingeben kann.

    Also gilt die Umwandlung nicht für meine Variable n, sondern für Edit1.Text?
    Das würde Sinn machen, denn n ist ein Integer und Edit1-Text wäre es nach der Umwandlung auch. Das Edit-Feld wird n also zugeordnet und alles was ich in dieses Feld nachher reinschreibe wird mit dieser Vari verrechnet.
    Nein, nicht ganz. strtoint ist eine bloße Funktion, die einen Wert berechnet, auf das künftige Verhalten von edit1 hat sie keinerlei Einfluss. Was in Zeile 5 wirklich passiert, ist folgendes (Schritt für Schritt erklärt):
    Code:
    edit1 // Der Identifier spricht das Eingabefeld dieses Namens an
    edit1.text // Liefert die Eigenschaft "text" des Eingabefelds mit
               // der ID "edit1". Diese enthält den eingegebenen Text
               // (als String).
    strtoint(edit1.text) // Die Funktion strtoint nimmt einen String
                         // als Parameter und liefert die durch ihn
                         // repräsentierte ganze Zahl zurück. Ist
                         // edit1.text also z.B. "12", so liefert der
                         // Ausdruck den Wert 12 (als Integer) zurück.
    n := strtoint(edit1.text) // Weist der Variablen "n" den Wert des
                              // rechten Ausdrucks (in obigem Beispiel
                              // also 12) zu.
    Dieser Code wird jedes Mal ausgeführt, wenn man auf den Button klickt und wandelt dann den eingegebenen String in eine Zahl um. Der Text wird dabei aber in keinster Weise verändert, du kannst ja mal probieren, was passiert, wenn du totalen Unsinn (also keine Zahl) eingibst.
    Dein dazuedierter Kommentar zu der Zeile ist demnach auch nicht korrekt, die anderen stimmen aber, denke ich.

  8. #8
    Zitat Zitat von drunken monkey Beitrag anzeigen
    Code:
    edit1 // Der Identifier spricht das Eingabefeld dieses Namens an
    edit1.text // Liefert die Eigenschaft "text" des Eingabefelds mit
               // der ID "edit1". Diese enthält den eingegebenen Text
               // (als String).
    strtoint(edit1.text) // Die Funktion strtoint nimmt einen String
                         // als Parameter und liefert die durch ihn
                         // repräsentierte ganze Zahl zurück. Ist
                         // edit1.text also z.B. "12", so liefert der
                         // Ausdruck den Wert 12 (als Integer) zurück.
    n := strtoint(edit1.text) // Weist der Variablen "n" den Wert des
                              // rechten Ausdrucks (in obigem Beispiel
                              // also 12) zu.
    Genau, wenn Edit1 allerdings nicht umwandelbar ist, dann bekommst du n' Fehler un d die Prozedure schmiert ab, also solltest du solche Umwandlungen vorsichtig anwenden aka pruefen oder durch z.B. Spinedits ausschschliesen.

    Code:
    function IsInt(S: Integer): Boolean;
    var
      Temp: Integer;
    begin
      try
        Temp := StrToInt(S);
        Result := True;
      except
        Result := False;
      end:
    end;
    
    function IsInt(S: Integer): Boolean;
    var
      I: Integer;
    begin
      Result := True;
      for I := 1 to Length(S) do
        if ((S[I] <> '1') AND (S[I] <> '2') AND (S[I] <> '3') AND 
            (S[I] <> '4') AND (S[I] <> '5') AND (S[I] <> '6') AND 
            (S[I] <> '7') AND (S[I] <> '8') AND (S[I] <> '9') AND 
            (S[I] <> '0')) then
          Result := False;
    end;
    Beide gehen (ungetestet, grad kein Delphi). Obere pausiert aber im Debug Modus bei einem Nicht-Integer.

    Anwendung waere dann so:

    Code:
    var
      n, i: Integer;
      summe: Real; 
    begin
      if IsInt(Edit1.Text) then
      begin
        n := StrToInt(Edit1.Text);
        summe := 0;
    
        for i := 1 to n do
        begin
          summe := summe + i;
        end;
     
        Label1.Caption := 'S = ' + FloatToStr(summe);
      end
      else
        ShowMessage('Fehler blub...');
    end;
    Quellcodes einrueken und Gross-Kleinschreibung beachten ist btw. ziemlich sinnvoll wenn es um Leserlichkeit geht.

    Geändert von Crash-Override (10.05.2008 um 23:07 Uhr)

  9. #9
    @drunken monkey: Hab mir die Informationen aus deinem Post noch einmal in einfacher Form zusammengetragen, um zu sehen ob ich das auch wirklich kapiert habe:

    edit1 // Klar, ein Eingabefeld.
    edit1.text // Edit.text gibt also meinen eingegebenen Daten den String-Typus.

    Zitat Zitat von drunken monkey
    strtoint(edit1.text) //Ist edit1.text also z.B. "12", so liefert der Ausdruck den Wert 12 (als Integer) zurück.
    Gut, das verstehe ich.

    Zitat Zitat von drunken monkey
    n := strtoint(edit1.text)
    Also Variable n bekommt den Wert meiner Eingabe, was immer das auch sein mag. Demnach ist es also klüger, lieber eine Zahl als ein Wort einzugeben, da sowas sonst Fehler provoziert (das Wort "Hamster" als Integer zurückzugeben ist wohl für Delphi unmöglich, bei der Zahl "12" ists aber kein Problem).


    Eine Frage hätte ich hierzu noch:

    Code:
    label1.caption := 'S = ' + floattostr(summe);
    Die Variable summe wird von einer Kommazahl (real) in einen String umgewandelt, um auf der Caption vom Labelfeld angezeigt zu werden.
    Gilt sowas auch generell, also kann man Zahlen wie Integer und real nicht auf einer Caption anzeigen lassen und muss man sie deshalb immer in einen String umwandeln?

  10. #10
    Zitat Zitat von Davias Beitrag anzeigen
    Eine Frage hätte ich hierzu noch:

    Code:
    label1.caption := 'S = ' + floattostr(summe);
    Die Variable summe wird von einer Kommazahl (real) in einen String umgewandelt, um auf der Caption vom Labelfeld angezeigt zu werden.
    Gilt sowas auch generell, also kann man Zahlen wie Integer und real nicht auf einer Caption anzeigen lassen und muss man sie deshalb immer in einen String umwandeln?
    Nein, sowas geht nicht. Zahlen zu String immer Umwandeln. FloatToInt(), IntToStr() und FormatFloat() [Letzteres fuer komplexere Formatierungen aka 10.10 statt 10.1]

  11. #11

    Achtung, OT

    Zitat Zitat von Davias Beitrag anzeigen
    Ja, der Code war falsch abgelegt, er musste in die Prozedur vom Button rein. Und den gabs vorher irgendwie nicht xD
    Das klingt nach dem magic pushbutton-anti-pattern. Das ist eine Unsitte, die bei Entwicklungsumgebungen mit eingebautem Formulareditor (wie VB oder Delphi) häufig vorkommt: Man schreibt in eine Callbackmethode eines Bedienelements rein, was das Bedienelement tut.

    Auf den ersten Blick wirkt das harmlos - immerhin soll ja definiert werden, was der Knopf tut! Tatsächlich stimmt das aber nicht. Es soll ein Verhalten definiert werden, das durch den Knopf ausgelöst wird. Das Verhalten könnte aber auch auf einem anderen Weg ausgelöst werden. Man sollte die eigentliche Programmlogik immer in eigene Methoden auslagern, aus mehreren Gründen:

    Zuerst ist da der offensichtliche Grund - vielleicht willst du später mal die gleiche Funktionalität zusätzlich über ein Menü oder sonstwie verfügbar machen. Das geht nur dann sauber, wen der Kram in seiner eigenen Methode liegt. Copy and paste ist nicht dein Freund.

    Dann ist noch das Wartbarkeitsproblem. Wenn du später was an deinem Code ändern willst, mußt du auch wissen, was er macht. Nach einigen Monaten hat man das nicht mehr im Kopf und da kommt es schon vor, daß man rausfinden muß, was eine bestimmte Methode überhaupt tut. Es hilft dabei immens, wenn die Methode exportToCSV() heißt und nicht Button13.onClick().

    Außerdem wird die Trennung von Präsentation (GUI) und Logik (was das Programm tut) generell als gute Idee angesehen. Im Idealfall sollte man das GUI komplett rausreißen und neu machen können, ohne daß das die Logik weiter interessiert.


    Du bist natürlich noch neu*, aber ich empfehle dir, dir Dinge wie Modularisierung und code reuse möglichst früh zu verinnerlichen. So gewöhnst du dir schlechte Gewohnheiten gar nicht erst an - die sind teilweise nämlich wirklich schwer wieder loszuwerden.


    * Beim Programmieren, nicht im Forum. Nur, damit es da keine Mißverständnisse gibt.

    Geändert von Jesus_666 (10.05.2008 um 23:35 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •