saubere Programmierung:Parameterübergabe an Funktionen

  • von C++ und VB.Net kenne ich eine Paramerterübergabe so in der Art:

    .
    .
    .
    function_bla(par_x, par_y)
    .
    .

    Func function_bla(par_a, par_b)
    rechne dies
    tue das
    usw
    return(par_a,par_b)
    endfunc


    man kann also die Parameter als par_x an par_a usw. übergeben, nur die Reihenfolge innerhalb der Klammer ist entscheidend. Gilt auch für die Rückgabewerte. Nun kann man in C++ auch direkt par_x an par_x übergeben, ist aber nicht ganz koscher. Möglich ist das, aber nicht gerne gesehen, da sich diese variablen bzw. Parameter bei unaufmerksam programmiertem Code überschreiben können. ich habe dies auch in AutoIt versucht und es geht auch beides, aber wie ist es "autoit-konform" programmiert? Wie macht Ihr das in der Regel?

    • Offizieller Beitrag

    In AutoIt ist es so, dass eine Variable, die im Funktionskopf als Übernahmevariable angegeben ist, eine lokale Variable darstellt, auch wenn es eine gleichnamige globale Variable gibt.

    Beispiel:

    [autoit]


    Global $a = 5
    Test($a)
    MsgBox(0,'Global', '$a = ' & $a)

    [/autoit][autoit][/autoit][autoit]

    Func Test($a)
    $a += 5
    MsgBox(0,'Innerhalb der Funktion', '$a = ' & $a)
    EndFunc

    [/autoit]

    Insofern kannst Du die Übernahmevariablen auch genauso nennen wie die Übergabevariablen im Hauptprogramm.
    Meistens mache ich das auch so. Kommt aber immer drauf an, ob die Funktion nur eine bestimmte Aufgabe hat oder ob sie universell ausgelegt ist.

  • aha...das mit der lokalen Variable ist interessant, da ich innerhalb der Funktion eben diese Variable nicht mehr deklarieren konnte und jetzt weiss ich dass das im Funktionskopf erledigt wird, gut. Sowas in der Art dachte ich mir aber schon.
    Bei mir ist die Funktion eher universell und wird vielen anderen Funktionen mit verschiedenen Parametern aufgerufen. Dann könnte ich es also so machen, dass die Parameter immer andere Namen haben um diese besser zu unterscheiden. Aber bei einfacheren Funktionen nehme ich gleiche Namen und es treten auch keine Probleme auf, wie evtl. in C++ ?

  • Kleine Ergänzung vielleicht noch:
    Willst du direkt mit der übergebenen Variable arbeiten so kannst du das über das KeyWord ByRef machen.
    Ist manchmal doch recht wichtig - vor allem bei sehr großen Datenstrukturen wie z.B. Arrays.
    Da wäre es meistens einfach unsinnig dieses 2x im Speicher zu haben.

    Beispiel:

    [autoit]

    Global $Variable = 5

    [/autoit][autoit][/autoit][autoit]

    Beispiel($Variable)

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0,"", "Variable nach Funktion: " & $Variable)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func Beispiel(ByRef $VarX)
    $VarX += 5
    Return 1
    EndFunc

    [/autoit]
  • ja so könnte es auch gehen, aber ich habe mich in AutoIt mit Pointern noch nicht beschäftigt (hoffe es ist einfacher als in C++). Musst du die $Variable global deklarieren? Arbeite sehr ungerne mit globalen Variablen

    • Offizieller Beitrag

    Ein "Problem" bei AutoIt ist, dass alle Variablen, die außerhalb einer Funktion deklariert werden, globale Variablen sind (ich halte das immer noch für einen Bug), auch wenn man sie explizit als Lokal deklariert.

    Beispiel:

    [autoit]


    Local $a = 5
    Test()
    MsgBox(0,'Global', '$a = ' & $a)

    [/autoit][autoit][/autoit][autoit]

    Func Test()
    $a += 5
    MsgBox(0,'Innerhalb der Funktion', '$a = ' & $a)
    EndFunc

    [/autoit]
  • also das ist ne lösung um Außerhalb der Funktion und inerhalb von Funktionen Verschiedene sachen zu speichern. eig ganz leicht

    [autoit]

    Global $a = 5
    MsgBox(0,"Wert", "$a =" & $a)
    Test()

    [/autoit][autoit][/autoit][autoit]

    Func Test()
    Local $a = 7
    MsgBox(0,"Wert", "$a =" & $a)
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0,"Wert", "$a =" & $a)

    [/autoit]
    • Offizieller Beitrag

    Hab mal ein bischen gegoogled . Sinngemäß wiedergegeben wäre das :Ich deklariere eine Variable z.B. Local $Test="Hallo" im Hauptprogramm. In einer Funktion dek. ich Local $Test="Hallo2" dann gilt die Var nur so lange bis die Funktion beendet wird. Nach Ende der FUNC ist $Test ="Hallo".Also die beiden Var. haben den selben Namen aber eigentlich nix miteinander zu tun bzw sie beeinflussen sich nicht gegenseitig. Wenn ich in der FUNC die Variable $Test nicht deklariere dann habe ich auch keinen Zugriff auf den Inhalt(Wert) der Variable. Also wenn man dann $Test abfragt inerhalb der Func dann wäre der Wert = 0.

    Edit: Oscar du hast recht mit dem Bug . Habe mal ein Testscript geschrieben .

    Spoiler anzeigen
    [autoit]

    Local $Test = "Hallo"
    Test1()
    Test2()
    MsgBox(0,"Test3",$Test)

    [/autoit] [autoit][/autoit] [autoit]

    Func Test1()
    Local $Test = "Hallo2"
    MsgBox(0,"Test1",$Test)
    EndFunc
    Func Test2()
    MsgBox(0,"Test2",$Test)
    EndFunc

    [/autoit]

    Die 1. MsgBox gibt "Hallo2" aus des ist richtig.
    Die 2. MsgBox gibt "Hallo" aus , das ist falsch es dürfte gar nichts ausgegeben werden.
    Dei 3. MsgBox gibt "Hallo" aus, das ist richtig .

    Quelle zum nachlesen :http://books.google.de/books?id=tnzjEFRrNYkC&pg=PA179&lpg=PA179&dq=lokale+variablen+im+hauptprogramm&source=web&ots=Qsg6x-aDgt&sig=VAwLRchAvjdQOupWCBRbYF9Y6j0&hl=de&sa=X&oi=book_result&resnum=4&ct=result#PPA178,M1
    Ist ein QBasic-Beispiel.

  • Wie du richtig erkannt hast ist die Reihenfolge innerhalb der Klammern entscheidend, aber bei dem Rückgabewert ist das egal weil Funktionen eh immer nur einen Rückgabewert haben. Parameter sind in der Funktion wie ganz normale lokale Variablen zu benutzen.


    Parameter mit gleichen Namen sind doch kein Problem und werden oft benutzt um die Verständlichkeit des Codes zu erhöhen.
    Den this Zeiger gibt es bei C++, C# Java usw. und My ist es in VB.NET.
    Ob es sowas in AutoIT gibt, um die Globalen Variablen anzusprechen, weiß ich jetzt nicht.

    MFG. RAPTOR-ONE

  • ok...das hätte ich nun gelöst...funktioniert alles prima....aber ich bekomme nun kein Tray Menu hin, weil ein Tray Menu, ebenso wie die GUI in einer While Schleife durchläuft....irgendwie finde ich das jetzt doch schlehct gelöst, denn wie soll ich denn beide whiles ineinander verschachteln, ohne dass die sich beissen? Geht irgendwie nicht. Und die GUI wie bei VB üblich als OnEvent ummodeln möchte ich jetzt auch nicht mehr

    • Offizieller Beitrag

    Das TrayGetMsg kannst Du doch in die GUIGetMsg-Schleife mit einbauen:

    [autoit]


    [...]
    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    MsgBox(0, "", "Dialog was closed")
    Exit
    Case $button_1
    MsgBox(0, "Default button clicked", "Radio " & $radioval1)
    EndSwitch
    Switch TrayGetMsg()
    Case $aboutitem
    MsgBox(64, "About:", "AutoIt3-Tray-sample")
    Case $exititem
    ExitLoop
    EndSwitch
    WEnd
    [...]

    [/autoit]