PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänger-VB-Frage


Nahaz
2007-07-21, 19:26:52
Hallo,

ich bin totaler Anfänger im programmieren und bin z.Z. dabei mich auf meine Zwischenprüfung vorzubereiten.

Folgendes Problem:

In der Zwischenprüfung wird verlangt eine einfache VB Konsolenanwendung in drei Teile aufzuteilen, Ausgabe, "Fachkonzept" (nennt man das wirklich so oder ist das nur wieder eine Spezialbezeichung von meinem Ausbilder?) und dann später eine Windows Applikation. Ich hab auch schon einige kleine Programme erfolgreich geschrieben, auch das Beispiel um das es hier geht ist simpel.
Atm sieht das so aus:

Option Strict On
Option Explicit On
Imports System.Console

Public Class Hauptprogramm
Shared Sub main()

Dim zahlpuffer, xpuffer As String
Dim objekt As New QuadratzahlenFachkonzept.Fachkonzept

WriteLine("Qadratzahlen")

Write("Geben Sie die Zahl ein von der die Quadratzahlen berechnet werden sollen: ")
zahlpuffer = System.Console.ReadLine
objekt.eingabe(zahlpuffer)

objekt.verarbeitung()

xpuffer = objekt.ausgabe

WriteLine("{0}*{0}={1}", zahlpuffer, xpuffer)
ReadLine()

End Sub



Option Strict On
Option Explicit On

Public Class Fachkonzept
Dim zahl, x As Integer

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
End Sub

Sub verarbeitung()
For zahl = 1 To zahl
x = zahl * zahl
Next zahl
End Sub

Function ausgabe() As String
ausgabe = CStr(CInt(x))
End Function

End Class


Mein Problem wäre eingentlich nur dass ich es irgendwie nicht schaffe dass bei der Ausgabe 1*1=1, 2*2=4 etc. steht. So wie es jetzt ist hab ich ja nur einfach x = zahl * zahl. Wäre jemand so nett mir zu sagen wie man das richtig macht?

Thx Nahaz

BAGZZlash
2007-07-22, 22:10:42
Hallo,

ich bin totaler Anfänger im programmieren und bin z.Z. dabei mich auf meine Zwischenprüfung vorzubereiten.

Folgendes Problem:

In der Zwischenprüfung wird verlangt eine einfache VB Konsolenanwendung in drei Teile aufzuteilen, Ausgabe, "Fachkonzept" (nennt man das wirklich so oder ist das nur wieder eine Spezialbezeichung von meinem Ausbilder?) und dann später eine Windows Applikation. Ich hab auch schon einige kleine Programme erfolgreich geschrieben, auch das Beispiel um das es hier geht ist simpel.
Atm sieht das so aus:

Option Strict On
Option Explicit On
Imports System.Console

Public Class Hauptprogramm
Shared Sub main()

Dim zahlpuffer, xpuffer As String
Dim objekt As New QuadratzahlenFachkonzept.Fachkonzept

WriteLine("Qadratzahlen")

Write("Geben Sie die Zahl ein von der die Quadratzahlen berechnet werden sollen: ")
zahlpuffer = System.Console.ReadLine
objekt.eingabe(zahlpuffer)

objekt.verarbeitung()

xpuffer = objekt.ausgabe

WriteLine("{0}*{0}={1}", zahlpuffer, xpuffer)
ReadLine()

End Sub



Option Strict On
Option Explicit On

Public Class Fachkonzept
Dim zahl, x As Integer

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
End Sub

Sub verarbeitung()
For zahl = 1 To zahl
x = zahl * zahl
Next zahl
End Sub

Function ausgabe() As String
ausgabe = CStr(CInt(x))
End Function

End Class


Mein Problem wäre eingentlich nur dass ich es irgendwie nicht schaffe dass bei der Ausgabe 1*1=1, 2*2=4 etc. steht. So wie es jetzt ist hab ich ja nur einfach x = zahl * zahl. Wäre jemand so nett mir zu sagen wie man das richtig macht?

Thx Nahaz


Nee, nee, Du brauchst sowas hier:
Ausgabe = Trim(Str$(zahl)) & "*" & Trim(Str$(zahl)) & "=" & Trim(Str$(zahl*zahl))

(VB6-Code)

medi
2007-07-22, 23:32:10
deine schleife ist quatsch

Sub verarbeitung()
For zahl = 1 To zahl
x = zahl * zahl
Next zahl
End Sub

macht nix weiter als von 1 bis n zu laufen und am ende nur
x= y * y zu rechnen
kannste dir auch schenken ^^


entweder du machst die schleife ausserhalb der klasse und rufst somit n * die verarbeitung und danach die ausgabe auf oder du baust die ausgabe in jeden schleifendurchlauf in deiner verarbeitungsmethode ein

ach und du könntest die ausgabe auch in der schleife in ein array packen und mit der ausgabenmehtode dann einfach nur das array ausgeben

Der_Donnervogel
2007-07-23, 10:27:25
Nee, nee, Du brauchst sowas hier:
Ausgabe = Trim(Str$(zahl)) & "*" & Trim(Str$(zahl)) & "=" & Trim(Str$(zahl*zahl))

(VB6-Code)
Übrigens das Trim(Str§()) kann man sich eigentlich auch schenken, da ja dank des & automatisch von VB zahl in einen String konvertiert und dann zusammengefügt wird. Will man trotzdem explizit den Typ umwandeln kann man statt Str$ auch CStr() nehmen, das kein führendes Leerzeichen einfügt. Das ist nicht nur schneller als Str() sondern man spart sich auch das Trim().

@Nahaz

Beim Coden bitte aufpassen, nach Möglichkeit keine "globalen" Variablen für Berechnungen verwenden. Die Zählvariable für die for-Schleife sollte umbedingt innerhalb der Prozedur oder gar der for-Schleife selbst deklariert werden. z.B.
For i As Integer = 1 To zahl
Damit spart man sich auf längere Zeit viele Probleme.

Davon abgesehen berücksichtigen, was "medi" geschrieben hat. Ich habe das Programm noch schnell angepaßt, daß es funktioniert. Allerdings habe ich eine "fortschrittlichere" Technik reingebastelt da ich keine Lust hatte mit Arrays rumzufrickeln ;)

edit: Der Code arbeitet übrigens nur für Zahlen > 0 korrekt. Falls man auch negative Zahlen und 0 mit einbeziehen wollte, müßte man noch was ändern.

Sub Main()
Dim zahlpuffer As String
Dim objekt As New Fachkonzept

WriteLine("Qadratzahlen")

Write("Geben Sie die Zahl ein von der die Quadratzahlen berechnet werden sollen: ")
zahlpuffer = System.Console.ReadLine
objekt.eingabe(zahlpuffer)

objekt.verarbeitung()

For Each entry As KeyValuePair(Of Integer, Integer) In objekt.ausgabe
WriteLine(entry.Key & "*" & entry.Key & "=" & entry.Value)
Next

ReadLine()
End Sub

Public Class Fachkonzept
Dim zahl As Integer
Dim ausgaben As IDictionary(Of Integer, Integer) = New SortedList(Of Integer, Integer)

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
End Sub

Sub verarbeitung()
For i As Integer = 1 To zahl
ausgaben.Add(i, i * i)
Next i
End Sub

Function ausgabe() As IDictionary(Of Integer, Integer)
ausgabe = ausgaben
End Function
End Class

Nahaz
2007-07-23, 11:16:10
Danke euch allen für eure Ratschläge, besonders auch dem Donnervogel für die Mühe. :smile:

Ich werd mal versuchen dass ganze irgendwie nachzuvollziehen aber ehrlich gesagt hab ich da so meine Zweifel, aus mir wird sicher kein Programmierer mehr :frown:

Der_Donnervogel
2007-07-24, 00:34:54
Danke euch allen für eure Ratschläge, besonders auch dem Donnervogel für die Mühe. :smile:

Ich werd mal versuchen dass ganze irgendwie nachzuvollziehen aber ehrlich gesagt hab ich da so meine Zweifel, aus mir wird sicher kein Programmierer mehr :frown:
Das kommt alles mit der Übung. :)

Ach ja ein kleiner Fehler war noch drinn, so müßte es richtig sein:
Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
ausgaben.Clear()
End Sub

Die Umsetzung an sich ist sehr einfach gehalten. Um die Ergebnisse nach der Verarbeitung gespeichert zu halten, habe ich statt einem Array ein Dictionary genommen. Diese Datenstruktur erlaubt es, Paare aus einem Schlüssel und einem Wert zu speichern. Da ich konkret eine SortedList verwende werden die Daten nach dem Schlüssel (Key) sortiert. Ich speichere also in jedem Schleifendurchlauf jeweils die Zahl die quadriert wird als Schlüssel und als Wert (Value) das Quadrat der Zahl. Ausgabe, gibt dann einfach eine Referenz auf dieses Dictionary zurück. Die For Each Schleife im main läuft dann alle Elemente des Dictionary durch und gibt eines nach dem anderen aus.

Man hätte das ganze auch mit einem Array machen können, aber das wäre nicht ganz so "schön" gegangen. Man hätte ein Array anlegen können und in Eingabe mit ReDim auf die passende Größe bringen. Anschließend hätte man bei der Verarbeitung jeweils die zu quadrierende Zahl - 1 als Index genommen unter der das Quadrat gespeichert wird. Der Grund ist, daß Arrays bei Index 0 binnen, also das Quadrat von 1 auf Index 0 gespeichert wird. Anschließend hätte man bei der Ausgabe dieses Array übergeben und ausgeben können. Da es ja schnell gemacht ist, hab ich es noch dazu getan. Es werden jetzt in main einfach beide Versionen direkt hintereinander ausgegeben. Hier würde es natürlich um einiges problematischer werden, eine Version mit negativen Zahlen zu machen, da man dann nicht mehr einfach den Index für die Zahl nehmen kann.
Sub Main()
Dim zahlpuffer As String
Dim objekt As New Fachkonzept
Dim objekt2 As New FachkonzeptArray
Dim ausgabe() As Integer

WriteLine("Qadratzahlen")

Write("Geben Sie die Zahl ein von der die Quadratzahlen berechnet werden sollen: ")
zahlpuffer = System.Console.ReadLine
objekt.eingabe(zahlpuffer)

objekt.verarbeitung()

For Each entry As KeyValuePair(Of Integer, Integer) In objekt.ausgabe
WriteLine(entry.Key & "*" & entry.Key & "=" & entry.Value)
Next

WriteLine("Version mit Array:")
objekt2.eingabe(zahlpuffer)
objekt2.verarbeitung()
ausgabe = objekt2.ausgabe

For i As Integer = ausgabe.GetLowerBound(0) To ausgabe.GetUpperBound(0)
Dim zahl As Integer = i + 1
WriteLine(zahl & "*" & zahl & "=" & ausgabe(i))
Next

ReadLine()
End Sub

Public Class Fachkonzept
Dim zahl As Integer
Dim ausgaben As IDictionary(Of Integer, Integer) = New SortedList(Of Integer, Integer)

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
ausgaben.Clear()
End Sub

Sub verarbeitung()
For i As Integer = 1 To zahl
ausgaben.Add(i, i * i)
Next i
End Sub

Function ausgabe() As IDictionary(Of Integer, Integer)
ausgabe = ausgaben
End Function
End Class

Public Class FachkonzeptArray
Dim zahl As Integer
Dim ausgaben() As Integer

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
ReDim ausgaben(zahl - 1)
End Sub

Sub verarbeitung()
For i As Integer = 1 To zahl
ausgaben(i - 1) = i * i
Next i
End Sub

Function ausgabe() As Integer()
ausgabe = ausgaben
End Function

End Class

Außerdem ist der obige Code mit Array nicht ganz so einfach nachzuvollziehen, da man hier mit Indexarithmetik arbeiten muß.

medi
2007-07-24, 06:59:05
zu dem array:
einerseits zwingt dich niemand bei nem array mit 0 anzufangen nur weil deren index standardmässig bei null beginnt und anderseits kannst du auch ein mehrdimensionales array (2dim) nutzen um mit negativen zahlen hantieren zu können. die mMn letzte und einfachste möglichkeit aber wäre es jeweils nur den kompletten ausgabestring, sprich array(0) = "1*1=1", array(1) = "2*2=4", ... in dem array zu speichern.

imo völlig ausreichend am anfang mit arrays zu arbeiten und auch leichter verständlich als solche sondertechniken wie Dictionary's ;)

Der_Donnervogel
2007-07-24, 11:24:21
zu dem array:
einerseits zwingt dich niemand bei nem array mit 0 anzufangen nur weil deren index standardmässig bei null beginnt
Bei VB 6 konnte man noch den Startindex verschieben, aber bei VB.Net ist der unterste Index immer 0, genau wie bei anderen Sprachen auch. Von der Idee die untersten Plätze einfach freizulassen, sollte man sowieso die Finger lassen. Solche Tricks führen sehr schnell zu Fehlern, falls man später mal was ändern will. Deshalb beginne ich immer bei Index 0 falls ich mal was mit Arrays mache und verschiebe dann einfach die Indexe um den entsprechenden Offset, falls nötig.
und anderseits kannst du auch ein mehrdimensionales array (2dim) nutzen um mit negativen zahlen hantieren zu können.
Ja, die Idee hatte ich auch. Natürlich könnte man einfach in der ersten Dimension die Zahl speichern, und in der zweiten das Ergebnis. Im Endeffekt ist das ja fast genau das was ich mit dem Dictionary gemacht habe. Nur daß man beim Dictionary eben sofort sieht, was jetzt der Schlüssel und was der Wert ist ohne mit irgendwelchen Konstanten arbeiten zu müssen.
die mMn letzte und einfachste möglichkeit aber wäre es jeweils nur den kompletten ausgabestring, sprich array(0) = "1*1=1", array(1) = "2*2=4", ... in dem array zu speichern.

Nö, die einfachste Idee wäre es die komplette Ausgabe bereits in der Ausgabefunktion in einen String zu packen und nur noch diesen zurückzugeben. ;) Beide Ideen sind aber schlechter Stil, da sie die Wiederverwendbarkeit einschränken. Bei dem Beispiel ist das sicher egal, aber man sollte sich wenns geht keine schlechten Angewohnheiten antrainieren.
imo völlig ausreichend am anfang mit arrays zu arbeiten und auch leichter verständlich als solche sondertechniken wie Dictionary's ;)
Das kann ich mit einem klaren Jein beantworten. ;) Falls man englisch kann ist die Variante mit dem Dictionary sicher einfacher zu lesen und darum ist es mir eigentlich auch gegangen. Bei einem Array hätte ich alles Kommentieren müssen, beim Dictionary kann man aus den Kommandos schließen was denn gerade getan wird.

Das wirkliche Problem liegt in den Feinheiten. Also was sich zB hinter IDictionary versteckt, oder aber die Tatsache, daß im Array die selben Zahlen mehrfach gespeichert sein könnten, im Dictionary die Keys aber eindeutig sind. Das IDictionary hätte ich mir aber wirklich sparen sollen, denn für Interfaces ist es sicher noch zu früh. Ich bin halt so an die Verwendung von Interfaces gewöhnt, daß das ganz automatisch kommt, wenn es sich anbietet.

Nahaz
2007-07-25, 13:07:35
Nö, die einfachste Idee wäre es die komplette Ausgabe bereits in der Ausgabefunktion in einen String zu packen und nur noch diesen zurückzugeben. ;)

Also die einfachste Methode wäre für mich gerade gut genug ;D
Vielleicht wärst du ja so nett mir diese "einfache" Möglichkeit an meinem Quelltext zu zeigen? =)

Der_Donnervogel
2007-07-25, 17:40:18
Also die einfachste Lösung wäre das:

Public Class FachkonzeptSimpel
Dim zahl As Integer
Dim resultat As String = ""

Sub eingabe(ByVal zahlpuffer As String)
zahl = CInt(zahlpuffer)
End Sub

Sub verarbeitung()
For i As Integer = 1 To zahl
resultat = resultat & i & "*" & i & "=" & (i * i) & vbCrLf
Next i
End Sub

Function ausgabe() As String
ausgabe = resultat
End Function
End Class
wobei es dann im Main so ausschauen würde
Dim objekt3 As New FachkonzeptSimpel
objekt3.eingabe(zahlpuffer)
objekt3.verarbeitung()
WriteLine(objekt3.ausgabe)
Diese Lösung ist zwar sehr simpel, aber auch sehr unschön. Viel besser ist es wenn man nur die errechneten Daten zurück gibt, da man ja nicht wissen kann was der Aufrufer damit machen will. Das Formatieren sollte man dem Nutzer der Daten überlassen.

(übrigens das vbCrLf am Schluß der Zeile die das Resultat erzeugt fügt einen Zeilenumbruch ein).

Nahaz
2007-07-25, 18:05:45
Danke du bist meine Rettung!!! :ulove: