Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 07.01.2013, 12:00 Titel: QBasic Taschenrechner |
|
|
Hi-di-ho miteinander.
Ich gurke schon einige Zeit mit QBasic herum und habe mir einige Hausaufgaben der früheren Programmierer geholt.
Ich schreib einfach mal was ich bis jetzt gemacht habe:
Die Aufgabe bestand darin einen Taschenrechner mit den Grundrechenfunktionen zu schreiben.
Soweit kein Problem.
Subs erstellt für addition, subtraktion, division und multiplikation und das hat auch alles einwandfrei funktioniert.
Dann sehe ich jetzt den nächsten Teil dieser Übung ...
"Der Taschenrechner soll eine Vollständige Rechnung ausrechnen können ..."
Als beispielsrechnung ist gegeben:
15*3-5/4
... wie mach ich das denn nun?
Wie bringe ich QBasic dazu eine schon im Vorraus eingegebene Rechnung korrekt auszurechnen _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 07.01.2013, 12:55 Titel: |
|
|
Also ... nur damit man es richtig versteht:
Der Programmbenutzer gibt eine Gleichung ein, welche das Programm dann ausrechnen soll ...
als Input die gleichung etc.
Wie bewerkstellige ich das?
Auf dem Üblichen Weg mit den einfachen Rechnungen ist das wohl kaum zu bewerkstelligen ... und da ich nicht wirklich ahnung von QBasic habe und mir bei der schweizer internetseite tutorials mir die "tutorials" (haha) durchgelesen habe ... wird mir das auch nicht wirklich ersichtlich ... _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 07.01.2013, 13:10 Titel: |
|
|
Hi Surican,
willkommen im Forum!
Surican hat Folgendes geschrieben: | "Der Taschenrechner soll eine Vollständige Rechnung ausrechnen können ..."
Als beispielsrechnung ist gegeben: 15*3-5/4 |
Surican hat Folgendes geschrieben: | Der Programmbenutzer gibt eine Gleichung ein, welche das Programm dann ausrechnen soll ... |
Wenn es um einen Term wie oben angegeben geht (Man nennt das auch "Infix-Notation".), wird es schon deutlich komplizierter als das bloße Verrechnen zweier Operanden mit einer Sub (z. B. Addieren mit zwei Parametern).
In manchen anderen Programmiersprachen gibt eine "eval"-Funktion, um einen als Zeichenkette gegebenen Ausdruck auszurechnen. QBasic kennt soetwas jedoch nicht.
Um das Ergebnis eines solchen Terms zu bestimmen, musst du die Formel Zeichen für Zeichen parsen. Am besten du erzeugst aus der Zeichenkette erst mal eine Reihung von Tokens, also in dem Fall logischen Formel-Bestandteilen. Beispielsweise wäre in einer Formel wie "34+2*5" die "3" ein eigenes Zeichen, die "4" ein eigenes Zeichen, ... Damit lässt sich schwierig arbeiten. Von daher fasst man diesen Input erst mal zu sinnvollen Blöcken zusammen: Zahl,Operator,Zahl,Operator,Zahl
Siehe zum Thema auch: Tokenizer / Lexer
Ein möglicher Ansatz, Infix-Eingaben zu handhaben, wäre, die Formel zuerst in die Postfix-Notation (alias Umgekehrte Polnische Notation (UPN)) umzuschreiben und anschließend diese zu verarbeiten. (Einen Stack in QBasic zu bauen, ist allerdings auch etwas "unschön".)
Man kann die Eingabe in der Infix-Notation allerdings auch direkt verarbeiten. Ein guter Ansatz dafür ist das Precedence Climbing (danke übrigens an dkl für den Tipp vor einiger Zeit! ).
Surican hat Folgendes geschrieben: | Programmbenutzer gibt eine Gleichung ein, welche das Programm dann ausrechnen soll |
Übrigens: Eine richtige Gleichung (z. B. "2*x = 10*3-x") nach einer Unbekannten aufzulösen, ist noch mal viel schwieriger. Aber ich hab's so verstanden, dass du mit "Gleichung" einen Term wie den oben meinst.
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
|
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 07.01.2013, 14:25 Titel: |
|
|
Soetwas hatte ich schon geahnt
Also werd ich wirklich diese Zeichenblöcke machen müssen
okay ... ich melde mich wenn ich das Programm ... "fertig" habe
(wobei ein solches Unterfangen unmöglich ist ... denn ... wenn es funktioniert ... ist es noch lange nicht fertig)
also dann .. ran ans werk _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 07.01.2013, 15:09 Titel: |
|
|
... gut ... QBasic 1 : 0 ich ..
Ich geb mich geschlagen
Ich würde bis zum St. Nimmerleinstag dran sitzen, denn es soll mit unendlich vielen Zahlen verrechnet werden ...
Das mit den einzelnen Blöcken hab ich ja schon verstanden ... es funktioniert auch ... aber das die ganze Zeit so weiter machen? ...
ich weiß ja nicht ...
Kennt denn keiner eine andere Möglichkeit? _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
|
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 07.01.2013, 15:50 Titel: |
|
|
Gut ... also vorweg erstmal ne erklärung zu dem Code
Ich hab mir jetzt 4 Zahlen genommen die mit ihren Beiwerten verrechnet werden sollen:
Code: | CLS
PRINT "Taschenrechner"
PRINT ""
PRINT ""
PRINT ""
DO
INPUT "Geben Sie die erste Zahl ein"; z1
INPUT "Geben Sie die Rechenart ein"; r1$
INPUT "Geben Sie die erste Zahl ein"; z2
INPUT "Geben Sie die Rechenart ein"; r2$
INPUT "Geben Sie die erste Zahl ein"; z3
INPUT "Geben Sie die Rechenart ein"; r3$
INPUT "Geben Sie die vierte Zahl ein"; z4
IF r1$ = "+" THEN
erg = erg + z1 + z2
END IF
IF r1$ = "-" THEN
erg = erg + z1 - z2
END IF
IF r1$ = "*" THEN
erg = erg + z1 * z2
END IF
IF r1$ = "/" THEN
erg = erg + z1 / z2
END IF
IF r2$ = "+" THEN
erg = erg + z3
END IF
IF r2$ = "-" THEN
erg = erg - z3
END IF
IF r2$ = "*" THEN
erg = erg * z3
END IF
IF r2$ = "/" THEN
erg = erg / z3
END IF
IF r3$ = "+" THEN
erg = erg + z4
END IF
IF r3$ = "-" THEN
erg = erg - z4
END IF
IF r3$ = "*" THEN
erg = erg * z4
END IF
IF r3$ = "/" THEN
erg = erg / z4
END IF
INPUT "Möchten Sie mit diesem zwischenergebnis weiter rechnen?"; w1$
LOOP UNTIL w1$ = "n"
PRINT "Ihr Ergebnis lautet:"; erg; "." |
Das einzige Problem ist:
Punkt vor Strichrechnung kann man hierbei vergessen ...
wie setze ich das denn nun wieder um? _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 08.01.2013, 00:41 Titel: |
|
|
Hast du die von Sebastian verlinkten Seiten überhaupt gelesen? - der Code schaut nämlich nicht danach aus, dass du dich an Sebastians gute Ratschläge gehalten hättest.
Du sollst nämlich wohl nicht einzelne Eingaben vom Nutzer verlangen, sondern einen Term als ganzes einlesen und dann, wie Sebastian bereits oberhalb erwähnt hat, "parsen" - sprich: in logisch zusammengehörige Teile zerlegen. Das wären die Teile, die du aktuell separat einliest, wie Zahlenwerte und Operanden. In QBasic stehen dir viele Funktionen zum untersuchen, bearbeiten und herausnehmen von Teilen einer Zeichenkette zur Verfügung: u.a. MID, LEFT, RIGHT. Zum Konvertieren des Zahlenwertes als Zeichenkette zu einer Zahl stellt QBasic die Funktion VAL zu Verfügung. Zum Unterscheiden zwischen Zahl, Operator und Leerzeichen kannst du auch den in QBasic per ASC ermittelten ASCII Code des jeweiligen Zeichens zur Klasseneinteilung verwenden.
Wenn du die einzelnen Teile hast schaust du dir am Besten die von Sebastian bereits verlinkte Erklärung zu "Precedence climbing" an oder informierst dich an anderen Stellen im Web über "Precedence climbing", wenn dir die eine Erklärung noch unklar sein sollte - Google/Bing/etc. ist dazu dein bestes Werkzeug. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
dreael Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 2507 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 08.01.2013, 21:28 Titel: |
|
|
Ein richtiger Compiler/Parser, der mit Verschachtelung zurechtkommt, ist nicht so einfach für einen Programmiereinsteiger, aber Abarbeitung mit umgekehrter polnischer Notation dagegen ist verhältnismässig einfach zu realisieren.
Grundbasis aber ist für jede Methode ein Syntaxdiagramm, z.B. EBNF. => Vor Erstellung eines Codes am besten einmal einen Rechenausdruck in dieser Form darstellen.
Einfache gehaltenes Beispiel:
Ziffer = "0" | "1" | ... "9";
Zahl = [ "-" ] Ziffer { Ziffer } [ "." Ziffer { Ziffer } ];
PunktRechnung = Zahl { ( "*" | "/" ) Zahl };
StrichRechnung = PunktRechnung { ( "+" | "-" ) PunktRechnung };
Syntaktisch passendes Beispiel:
-1+5*7.1/3.55-2.01/-6.03
Will man noch Klammern erlauben, so braucht es sofort weitere und geänderte Regeln:
Ausdruck = Zahl | "(" StrichRechnung ")";
PunktRechnung = Ausdruck { ( "*" | "/" ) Ausdruck };
An dieser Stelle liegt bereits Rekursion vor.
Umgekehrte polnische Notation kann dagegen auch alle Rechenausdrücke verarbeiten und kommt ohne Rekursion aus:
Stackoperation = Zahl | "+" | "-" | "*" | "/";
UmgekPolnAusdruck = Stackoperation { " " Stackoperation };
=> kann ich QB relativ einfach mit INSTR()-Suche nach Leerzeichen umgesetzt werden. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
|
Surican
Anmeldungsdatum: 07.01.2013 Beiträge: 6
|
Verfasst am: 09.01.2013, 09:17 Titel: |
|
|
Danke ihr beiden für die Tipps,
ich werde versuchen mich reinzulesen
Zitat: | Hast du die von Sebastian verlinkten Seiten überhaupt gelesen? - der Code schaut nämlich nicht danach aus, dass du dich an Sebastians gute Ratschläge gehalten hättest.
|
Die Seiten habe ich mir gewissenhaft durchgelesen ... nur verstanden hab ich rein garnichts
Von der Funktionsweise her schon ... nur das umsetzen ... graah!
Und da meine Methode am einfachsten war (zwar falsch, aber immerhin rechnet er die strichaufgaben) habe ich diese genommen ... _________________ PRINT "Dies ist eine Signatur"
PRINT "Und dies die zweite Programmierzeile"
PRINT "Meinen Sie das stimmt?"
INPUT "Geben Sie ihre Antwort ein."; a1 |
|
Nach oben |
|
|
|