Eine Funktion, soll im Hauptprogramm zwei Werte wiedergeben

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Eine Funktion, soll im Hauptprogramm zwei Werte wiedergeben

    Hallo,

    ich habe eine Funktion, die den maximalen Wert eines Feldes ermittelt und zurück gibt.

    VB.NET-Quellcode

    1. Function Maximum(ByVal werte() As Double) As Double
    2. Dim wert As Double
    3. Dim max As Double
    4. For Each wert In werte
    5. If wert > max Then
    6. max = wert
    7. End If
    8. Next
    9. Return max


    Dann soll die Funktion im Hauptprogramm gestartet werden z.B. so:

    VB.NET-Quellcode

    1. Dim maxwert As Double
    2. Dim zahlen() As Double = {2, 8, 4, 2, 6}
    3. maxwert = Maximum(zahlen)


    Jetzt möchte ich, dass im Hauptprogramm auch der minimale Wert ausgegeben wird.
    Jedoch möchte ich dafür keine neue bzw. eigene Funktion erstellen, sondern das in einer Funktion machen, in meinem Fall in der Maximum Funktion.
    Ich habe das Problem, nicht zu verstehen, wie ich in einer Funktion zwei Werte berechnen kann und diese dann an das Hauptprogramm übergeben kann, damit dieses beides ausgibt.
    ja, so ist die Sprache eben: Eine Function kann nur einen Wert zurückgeben.
    In anderen Sprachen - etwa f# ist das anders.

    Man kann sich behelfen.
    Eine Möglichkeit ist, besondere Objekte zurückzugeben, die mehrere Werte enthalten.
    Deine Function könnte zb ein Tuple(Of T, T) zurückgeben, welches die 2 Werte enthält.
    Oder bei min/max ist das einfachste wohl, ein Array zurückzugeben, mit 2 Elementen.

    Übrigens zum Minimax-Problem hab ich eine lustige Extension gecodet, die sich ganz fabelhaft sogar in den Kontext von Linq einfügt: verbesserte AggregatFunktion für Linq-Max / Linq-Min
    Danke ErfinderDesRades,

    und wie ist das dann, z.B. bei einem rechtwinkligen Dreieck.
    Wenn ich da Umfang und Fläche über das Hauptprogramm ausgeben möchte und meine Function soll die beiden Werte berechnen und zurückgeben.
    Mit der Function berechne ich sowohl Umfang, als auch die Fläche.

    VB.NET-Quellcode

    1. Public Function Umfangfla(ByRef a As Double, ByRef b As Double) As Double()
    2. Dim werte(1) As Double
    3. werte(0) = a + b + Math.Sqrt(a ^ 2 + b ^ 2)
    4. werte(1) = (a * b) / 2
    5. Return werte
    6. End Function


    Wie übergebe ich das dann an mein Hauptprogramm? Bzw. wie schaffe ich es, dass mein Hauptprogramm die berechneten Werte ausgibt?

    Normalerweise würde ich, wenn es ein Werte wäre, es so aussehen lassen:

    VB.NET-Quellcode

    1. Dim a, b, u, f As Double
    2. Console.WriteLine("Bitte a eingeben")
    3. a = Console.ReadLine()
    4. Console.WriteLine("Bitte b eingeben")
    5. b = Console.ReadLine()
    6. u = Umfangfla(a, b) 'An der Stelle würde ich meine Function aufrufen, wenn es nur ein Wert wäre.
    7. f = Umfangfla(a, b)
    8. Console.WriteLine("Umfang: {0}", u)
    9. Console.WriteLine("Fläche: {0}", f)
    10. Console.ReadLine()
    Uih! du solltest erst noch dein VS umstellen!
    Weil sowas geht nicht:

    VB.NET-Quellcode

    1. Dim a, b, u, f As Double
    2. Console.WriteLine("Bitte a eingeben")
    3. a = Console.ReadLine()
    die Readline-Funktion gibt kein Double zurück - fang so einen Müll wie in zeile#3 erst garnet an zu coden!
    Unbedingt als erstes Visual Studio - Empfohlene Einstellungen umsetzen!

    va7 schrieb:

    CDbl
    knallt, wenn Du "Roullade mit Klößen" eingibst.
    Dafür gibt es Double.TryParse():

    VB.NET-Quellcode

    1. Dim txt = "123.456"
    2. Dim value As Double
    3. If Not Double.TryParse(txt, value) Then
    4. MessageBox.Show("das war nix")
    5. Return
    6. End If
    7. MessageBox.Show(value.ToString)
    Und solch Berechnungen gehören nicht in eine Console-Anwendung!
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    wie Rod schon sagt: Parse / TryParse ist die bessere Möglichkeit, denn diese Methoden sind nach objektorientierter Logik im Double-Datentyp angelegt. Darüberhinaus ist Parsing ein programmiererisches prinzip, was sich lohnt zu verstehen.
    Zb gibts Parse / TryParse in exakt gleichartiger Logik auch für die Datentypen Short, Integer, Decimal, Date, Timespan, und noch weitere Datentypen.

    Hingegen CDbl() ist ein bischen Quick & Dirty, und kann auch Probleme verursachen, wenn Programme unter verschiedenen Kulturen funktionieren sollen. Das Parse-System bietet Lösungen dafür, CDbl nicht.

    Aber zu deiner Frage mit den mehreren Werten, als Array returnt:

    VB.NET-Quellcode

    1. Public Function Umfangfla(a As Double, b As Double) As Double() 'und vermeide byRef!
    2. Dim werte(1) As Double
    3. werte(0) = a + b + Math.Sqrt(a ^ 2 + b ^ 2)
    4. werte(1) = (a * b) / 2
    5. Return werte
    6. End Function
    7. Sub foo()
    8. Dim a, b As Double
    9. Dim result As Double()
    10. Console.WriteLine("Bitte a eingeben")
    11. a = Double.Parse(Console.ReadLine())
    12. Console.WriteLine("Bitte b eingeben")
    13. b = Double.Parse(Console.ReadLine())
    14. result = Umfangfla(a, b) 'An der Stelle würde ich meine Function aufrufen, wenn es nur ein Wert wäre.
    15. Console.WriteLine("Umfang: {0}", result(0))
    16. Console.WriteLine("Fläche: {0}", result(1))
    17. Console.ReadLine()
    18. End Sub

    Vielen vielen Dank.
    Ich werde mich mit dem TryParse auseinander setzen.
    Vllt. lag mein Problem darin, dass ich die Aufgabenstellung falsch verstanden habe.
    Das ist die Aufgabenstellung:

    Ein rechtwinkliges Dreieck habe die beiden Katheten a und b.
    a) Schreiben Sie ein Unterprogramm, das den Umfang des Dreiecks berechnet und an das aufrufende Programm zurückgibt. Die Katheten des rechtwinkligen Dreiecks sollen an das Unterprogramm übergeben werden. Schreiben Sie zu jeder Zeile einen erklärenden Kommentar.
    b) Schreiben Sie ein Unterprogramm, das Umfang und Fläche des Dreiecks berechnet. Die berechneten Werte für Umfang und Fläche sollen im aufrufenden Programm weiter verwendet werden können. Die Katheten sollen an das Unterprogramm übergeben werden. Schreiben Sie zu jeder Zeile einen erklärenden Kommentar.
    c) Erläutern Sie die Unterschiede in den Parameterlisten der beiden Unterprogramme aus a) und b). Was bedeuten die Schlüsselworte ByVal bzw. ByRef bei der Parameterübergabe.

    Als ich die Aufgabenstellung bei c) gelesen habe, bin ich davon ausgegangen, dass man bei a) das Unterprogramm mit ByVal schreiben soll und bei b) mit ByRef.
    Evtl. stimmt das ja auch, nur bin ich die Aufgabe falsch angegangen?!
    In der

    va7 schrieb:

    Aufgabenstellung
    kommt Console nicht vor.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    va7 schrieb:

    Ich werde mich mit dem TryParse auseinander setzen.
    Ausgezeichnet!

    Guck, wenn man weiß wie, ists auch sehr einfach, sich damit auseinanderzusetzen: VisualStudio richtig nutzen (Google ist nicht deine Mami). Also das Video zeigt noch mehr nützlichen, aber um TryParse zu recherchieren, empfehle ich den ObjectBrowser (dort u.a. auch gezeigt).

    Beachte auch den dortigen letzten Post, weil wenn man den OB blöd eingerichtet hat, dann findet man den schnell als ganzes blöd, weil was darin zu finden ist dann bisserl blöd.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    RodFromGermany, du hast Recht, es steht nichts von Console. Aber wie gesagt, an der Uni beschäftigen wir uns nur mit Console-Anwendungen, daher muss das in der Aufgabenstellung nicht explizit drin stehen, meiner Meinung nach.

    ErfinderDesRades, du hast im Code dazu geschrieben, dass ich ByRef vermeiden sollte, warum?!
    Und mir ist auch die Frage nicht ganz klar, bei b) die berechneten Werte sollen weiter verwendet werden können.
    Wenn ich, also bei a) mit ByVal und bei b) mit ByRef schreiben würde, dann könnte ich doch beides mal die Werte weiter verwenden, oder nicht?
    @va7 : Fakt ist, eine Methode kann nur einen Rückgabewert haben - in VB.Net.
    MMn grhört es sich bei einer solchen Fragestellung zwei Methoden zu haben, eine für die Fläche, eine für den Umfang.
    Aber EdR hatte schon erwähnt, wenn du für den Typ des Rückgabewertes was schlaues auswählst, dann kann man darin auch zwei Sachen verpacken: ​Tuple(Of T1, T2)
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

    va7 schrieb:

    ErfinderDesRades, du hast im Code dazu geschrieben, dass ich ByRef vermeiden sollte, warum?
    bei byRef-Parametern kann der Wert innerhalb der Methode geändert werden mit Rückwirkung auf den Aufrufer.
    Es ist ein anderer Pattern, dass man das mit TryParse, TryCast, TrySelect oder whatever so macht, aber nicht wald und wiesenmäßig.
    Die Gefahr besteht darin, dass mans am Aufruf in vb nicht erkennt, dasses byRef ist, und dann geht man standardmäßig davon aus, dass der Wert, den man reingibt, nicht geändert wird.
    Wird er dann aber doch geändert, dann können sich daraus Bugs ergeben, die absolut fies zu finden sind.

    Ansonsten hat man dir jetzt ja eine Palette von Möglichkeiten aufgezeigt, wie man sich behilft.
    Zum Glück braucht man sowas recht selten.

    zu b) - ja mit byRef ist auch eine der Behelfs-Möglichkeiten, und wurde auch noch nicht genannt, also dass du a als ReturnWert zurückgibst, und b als byRef, oder auch beide als ByRef.