-         

Ergebnis 1 bis 5 von 5

Thema: Das Funktionen-Byref/Byval-Variablenchaos - Verständnisfragen

  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638

    Das Funktionen-Byref/Byval-Variablenchaos - Verständnisfragen

    Anzeige

    Hallo!


    Nach langer Zeit habe ich mich gestern das erste Mal über Subroutinen und Funktionen getraut. Bisher schrieb ich teilweise sehr umfangreiche Programme lediglich mit jede Menge Routinen, die per Gosub angesprochen wurden. Es funktionierte zwar, war aber manchmal zu langsam und zu unübersichtlich.

    Nach genauem Studium der Literatur (Internet, Bücher und Bascom-Hilfe) über Prozeduren und Funktionen hat mich teilweise über deren Wirkungsweise aufgeklärt, aber dennoch tauchen einige unbeantwortete Fragen auf. Auch möchte ich wissen, ob ich es denn richtig verstanden habe.

    Mein Wissensstand:
    • Eine Prozedur (Declare Sub) kann mit übergebenen Variablen arbeiten
    • Eine Funktion (Declare Function) kann mit übergebenen Variablen arbeiten und liefert einen Wert zurück
    • Innerhalb einer Prozedur oder Funktion kann ich mittels LOCAL Prozedur-/Funktionseigene Variablen definieren, die außerhalb der Prozedur nicht sichtbar sind
    • Übergebe ich eine Variable mit Byref wird lediglich die Adresse der zu übergebenen Variable weitergegeben
    • Übergebe ich eine Variable mit Byval wird die Variable kopiert


    Ein Beispielcode:
    Code:
    'GLOBAL
    Dim a as Byte
    Dim b as Byte
    Dim c as Byte
    
    Declare Function myfunction (a as Byte, b as Byte) as Byte
    
    Do
         c = myfunction(a,b)
    Loop
    
    Function myfunction (a as Byte, b as Byte)
         myfunction = a + b
    End Function
    
    End
    Ich habe jetzt drei globale Variablen definiert (a, b und c). Anschließend deklariere ich die Funktion myfunction mit zwei Übergabevariablen, die pfiffigerweise ebenfalls wie die globalen Variablen a und b heißen. Diese werden allerdings nicht kopiert, sondern nur die Adresse wird an die Funktion weitergegeben.
    In der Hauptschleife rufe ich die Funktion auf, in dem ich ein Ergebnis für die globale Variable c verlange. Dabei werden die globalen Variablen a und b an die Übergabevariablen a und b (ich find das extrem gemein) übergeben. Anschließend wird in der Funktion das Zeug zusammengerechnet und das Ergebnis wieder in die Hauptschleife in die globale Variable c kopiert. Fertig!

    Laut Simulator läuft die Sache so.

    So, nun zu den Fragen, die mich interessieren:
    Ist es wirklich kein Problem, globale Variablen gleich zu bennen wie Übergabevariablen (außer Verwirrung)?
    Welche Nachteile ergeben sich durch die Verwendung von byref, beziehungsweise wann kann die Variable fälschlicherweise geändert werden?
    Hat jemand Beispiele von richtig eingebundenen Funktionen/Prozeduren aus der Praxis oder in einem bestehendem Projekt?

    Warscheinlich sind die Antworten eh ganz einfach und logisch aber ich scheine gerade voll auf dem Schlauch zu stehen.

    Danke für eure Hilfe.
    Grüße
    Thomas

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Die Verwendung von Byval/Byref habe ich gerade durch Ausprobieren verstanden:
    Code:
    Dim X as Byte
    Dim Ergebnis as Byte
    
    Declare Function abc (a as Byte) as Byte
    
    Do
    
         Ergebnis = abc(x)
    
    Loop
    
    Function abc (a as Byte)
    
         Shift a , left , 2
         abc = a
    
    End Function
    
    End
    Diese Variante verändert beim zweimaligen Schieben der übergebenen Variable a ebenfalls die globale (Ursprungs-) Variable x, da ja die Variable gar nicht "real" an die Funktion übergeben wurde, sondern nur die Adresse der Variable x. Das ist warscheinlich schnell und speichersparend, aber in diesem Fall doof und unerwünscht.

    Mit der Verwendung von byval wird x einfach kopiert und dieser Klon wird dann in der Funktion geschoben und wieder zurückkopiert.

    Dazu noch eine Frage: Wird der Speicher nach verlassen der Funktion wieder freigegeben?

    Schön langsam wirds ja...
    Grüße
    Thomas

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo Thomas,
    dein Wissensstand ist vollkommen in Ordnung.
    Eine Sache hierzu: Es funktionierte zwar, war aber manchmal zu langsam und zu unübersichtlich.
    Durch die Verwendung von Subs oder Funktionen wird es nicht schneller, im Gegenteil, du bekommst etwas Overhead.
    Übersichtlicher wird es auf jeden Fall und daher ist die Verwendung sicherlich richtig.

    Ich würde grundsätzlich vermeiden, für eine lokale Variable den gleichen Namen zu verwenden, wie für eine globale.
    Ein Fehler von MCS beim Programmieren des Compilers und schon wird der falsche Wert verwendet. Ich meine mich sogar zu erinnern, dass es das auch schon einmal gegeben hat im Zusammenhang mit gleichen Namen.


    Den "Nachteil" von ByRef hast du ja schon gesehen. Wenn man darum weiß, ist es allerdings eher ein Vorteil.
    Arrays kannst du übrigens gar nicht anders übergeben, da bei ihnen nur die Startadresse übergeben und nichts kopiert wird.
    Strings werden mit ByVal kopiert, aber du kannst dir vorstellen, dass dabei einiges an Zeit draufgeht -> Overhead.
    Es wird übrigens nichts "zurückkopiert".

    Hast du dir die Beispiele in den Samples schon angesehen, dort ist einiges erklärt.

    Der Speicher wird beim Verlassen der Funktion wieder freigegeben.
    Zu beachten ist noch, dass die lokalen Variablen nicht mit 0 oder "" vorbelegt werden. Sie enthalten einfach das, was beim letzten Verwenden der Speicherzelle dort stand.

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Zitat Zitat von for_ro Beitrag anzeigen
    Hallo Thomas,
    dein Wissensstand ist vollkommen in Ordnung.
    Eine Sache hierzu: Es funktionierte zwar, war aber manchmal zu langsam und zu unübersichtlich.
    Durch die Verwendung von Subs oder Funktionen wird es nicht schneller, im Gegenteil, du bekommst etwas Overhead.
    Übersichtlicher wird es auf jeden Fall und daher ist die Verwendung sicherlich richtig.
    Mit langsam habe ich mich etwas unglücklich ausgedrückt: Ich meinte das Schreiben des Programms an sich, nicht die Ausführgeschwindigkeit. Sry.

    Zitat Zitat von for_ro Beitrag anzeigen
    Ich würde grundsätzlich vermeiden, für eine lokale Variable den gleichen Namen zu verwenden, wie für eine globale.
    Ein Fehler von MCS beim Programmieren des Compilers und schon wird der falsche Wert verwendet. Ich meine mich sogar zu erinnern, dass es das auch schon einmal gegeben hat im Zusammenhang mit gleichen Namen.
    Also geht es, ist aber furchtbar böse und unübersichtlich - das habe ich mir fast schon gedacht.
    Wie verhält es sich mit zwei einzelnen Funktionen, die beide als Übergabevariablen A und B haben? Da sie lokal sind, wäre das denkbar?

    Zitat Zitat von for_ro Beitrag anzeigen
    Den "Nachteil" von ByRef hast du ja schon gesehen. Wenn man darum weiß, ist es allerdings eher ein Vorteil.
    Arrays kannst du übrigens gar nicht anders übergeben, da bei ihnen nur die Startadresse übergeben und nichts kopiert wird.
    Strings werden mit ByVal kopiert, aber du kannst dir vorstellen, dass dabei einiges an Zeit draufgeht -> Overhead.
    Es wird übrigens nichts "zurückkopiert".
    Achso: Die lokale Variable wird dann ja sowieso entfernt da die Prozedur/Funktion verlassen wird.

    Zitat Zitat von for_ro Beitrag anzeigen
    Der Speicher wird beim Verlassen der Funktion wieder freigegeben.
    Zu beachten ist noch, dass die lokalen Variablen nicht mit 0 oder "" vorbelegt werden. Sie enthalten einfach das, was beim letzten Verwenden der Speicherzelle dort stand.
    Auch beim definieren einer lokalen Variable mit LOCAL?

    Danke nochmals für die Hilfe!
    Grüße
    Thomas

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Thomas E. Beitrag anzeigen
    Ist es wirklich kein Problem, globale Variablen gleich zu bennen wie Übergabevariablen (außer Verwirrung)?
    Kommt auf die Bascom-Version an, siehe history.txt:
    2.0.5.0
    - local variables may now have the same name as global variables.
    Auch beim definieren einer lokalen Variable mit LOCAL?
    Eigentlich nur da, denn die einzig andere/n lokale/n Variable/n, also übergebene Funktionsparameter, haben einen Wert. Nämlich den sie beim Aufruf der Funktion übergeben bekamen.

    Zitat Zitat von for_ro Beitrag anzeigen
    Ein Fehler von MCS beim Programmieren des Compilers und schon wird der falsche Wert verwendet.
    So'ne Aussage ist ja recht sinnfrei, denn wenn bei MCS ein Fehler im Compiler entsteht, dann geht u.U. gar nix mehr.
    Von einem Fehler grundsätzlich und speziell bei die Namensgebung von Variablen auszugehen, stellt im Prinzip jegliche Programmierung in Frage und macht auch so keinen Sinn.
    Abgesehen davon würde ich zustimmen, gleiche Namen für lokale und globale Variablen kann man locker vermeiden.

Ähnliche Themen

  1. RS485 Verständnisfragen
    Von Snakey im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 5
    Letzter Beitrag: 26.01.2012, 18:33
  2. Schrittmotor ESB, Verständnisfragen
    Von axel88 im Forum Motoren
    Antworten: 8
    Letzter Beitrag: 07.07.2011, 11:41
  3. Parameter von Funktionen in Funktionen
    Von hosti im Forum C - Programmierung (GCC u.a.)
    Antworten: 22
    Letzter Beitrag: 29.10.2009, 10:37
  4. Übergabe von Werten an eine SUB per Byval
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 23.11.2008, 12:52
  5. Gleichstrommotor Verständnisfragen
    Von Moresko im Forum Motoren
    Antworten: 12
    Letzter Beitrag: 12.01.2008, 19:16

Berechtigungen

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