VisualBasic Unterschied zwischen ByRef und ByVal

NitroTurboRatte

Lieutenant
Registriert
Juli 2007
Beiträge
577
Hallo Forum,
ich habe Probleme zu verstehen, was der Unterschied zwischen ByRef und ByVal sein soll (Parameter einer Methode)

Könnte mir das jemand erklären?

Danke jeder Hilfe.
 
um was geht es? visual basic? da kann ich leider nicht wirklich helfen, aber was referenzen sind, sollte denke ich mal jeder programmierer wissen. referenzen sind übergabeparameter, welche mit den originalwerten arbeiten und keine kopie dessen verwenden. byval ist das "gegenstück", es wird also nicht mit den originalwerten gearbeitet, sondern eine kopie erstellt und diese wird benutzt,

vorstellen kannst du dir das so (in c++ verdeutlicht):

Code:
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

void kopie( string foo )
{
  foo = "test";
}

void referenz( string &foo )
{
  foo = "test";
}

int main( int argc, char **argv, char **env )
{
  string test = "tolles wetter";
  cout << "original: " << test.c_str() << endl; // ausgabe: tolles wetter
  
  kopie( test );
  cout << "kopie(): " << test.c_str() << endl; // ausgabe: tolles wetter
  
  referenz( test );
  cout << "referenz(): " << test.c_str() << endl; // ausgabe: test
  
  return 0;
}

du änderst also die originalwerte in der funktion referenz(). bei kopien änderst du die originaldaten nicht, sondern nur mit der kopie.
 
Für den Fall, dass dir der Quellcode oben nicht geholfen hat:

Wenn du eine Variable irgendwo in deinem Programm hast, und diese ByVal (Werteparameter) einer anderen Funktion etc. übergibst, dann kann die Funktion den Wert verändern, ohne das diese Änderungen auch die ursprüngliche Variable betreffen (da im Grunde intern eine neue Variable gleichen Namens, aber anderer Adresse geschaffen wird).
Übergibst du sie stattdessen ByRef (Referenzparameter), dann nutzt die Funktion genau die Variable. Änderungen der Variable sind also auch nach aussen hin sichtbar, da keine neue Variable geschaffen wird sondern direkt der Speicherbereich übergeben wird, der zu der ursprünglichen Variable gehörte.

Und wenn dir das auch nicht geholfen hat:

http://de.wikipedia.org/wiki/Wertparameter
http://de.wikipedia.org/wiki/Referenzparameter
 
byRef:
der wert wird nicht als wert übergeben oder ermittelt sondern ein zeiger auf die speicheradresse wo der wert steht

byVal:
der wert wird als wert übergeben

unterschied:
byRef benötigt weniger speicher bei großen werten

hoffe das ist verständlich
 
@RAMMSTEiN0815

es gibt noch einen unterschied, sonst würde ja jeder nur byref verwenden. :)

@Topic

wenn die funktion den mit byref übergebenen wert verändert, ist er global (also auch dort wo die funktion gecalled wurde) verändert. mit byval passiert das nicht. damit können mit einer funktion mehrere "return-werte" (in klammern weils ja eigentlich keine return-werte sind) bearbeitet und an die caller-funktion zurückgegeben werden. siehe auch system-calls bei denen der returnwert z.b. ein boolean ist (hats funktioniert, ja oder nein) und die eigentlichen parameter per byref übergeben werden.

VB-Beispiel:
++++++++

public sub Caller()

dim s1 as String
dim s2 as String

s1 = "tröt"
s2 = "tröt"

ValueTest(s1, s2)

debug.print s1
debug.print s2

end sub
'---------------
public sub ValueTest(byref sRefString as String, byval sValString as String)

sRefString = "gabbagandalf"
sValString = "gabbagandalf"

end sub
'End of Code #############

wenn nun caller aufgerufen wird, dann wird debug.print für s1 "gabbagandalf" ausgeben und für s2 "tröt".
 
1.) ByRef bzw. ByVal trifft nur auf natürliche Datentypen z.B. Integer, String, Double etc. Alles, was ein Feld oder ein Objekt ist, wird sowieso nur ByRef übergeben.

2.) Im Normalfall wird man nur ByVal benötigen. Damit wird eine Kopie übergeben. In einem sauber geschriebenen Programm wirst du keine ByRef Argumente finden außer bei externen Funktionen aus einer dll.

3.) Es ist ein Irrglaube, dass ByRef immer schneller ist. Eine Referenz auf einen Integer, Double etc. ist nicht kleiner als der Wert selbst und bei Strings ist das Kopieren der Daten auch relativ schnell (ca. 10GB/s bei langen Ketten, im L1 Cache noch schneller). Wenn man nicht gerade ständig 1K seitige Romane in den Strings speichert, sollte das ziemlich egal sein. Auf der anderen Seite wird bei jedem Zugriff auf die übergebene Variable ein Speicherzugriff mehr benötigt (sowohl lesen, als auch schreiben). Das sind typischerweise 3-4 Takte, was bei häufigem Zugriff doch bremst.

4.) Das Verwenden der Parameter für Rückgabewert ist eine Unart aus der C Zeit, die man auf jeden Fall vermeiden sollte. Der Rückgabewert hat immer mit dem Return Statement zu erfolgen. Sämtliche Fehlercodes werden über Exceptions behandelt. Falls mehr als ein Rückgabewert benötigt wird, dann macht man ein Objekt. Ist das nicht schön möglich, so hat man meistens einen Fehler im Design.
Erstens erkennt man absolut nicht, was was jetzt der Rückgabewert ist und was ein Parameter.
Zweitens kann es sehr leicht passieren, dass man irrtümlich einen Wert überschreibt, den man nicht verändern wollte oder umgekehrt einen Wert nicht hineinschreibt, weil man das byref vergessen hat und auf einmal alte Werte drin stehen. Da sucht man eventuell auch lange.
 
Zurück
Oben