|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1243 Wohnort: Ruhrpott
|
Verfasst am: 19.06.2024, 21:31 Titel: |
|
|
Hallo Revilo,
ich möchte nemored einmal einen Teil der Arbeit abnehmen:
Revilo hat Folgendes geschrieben: | 1) Schleifen:
i=0 ist zu Beginn einer Schleife unnötig
if i>10 then i=10 nach einer Schleife aber sinnvoll, um zu vermeiden, daß mit einer ungewollten 11 weiterechnet wird. Der Rechner kann nun mal kein Feld(11) bearbeiten, wenn es nur
von 1 bis 10 dimensioniert ist. Richtig? |
Wenn ein Programm mit einer nicht initialisierten Variable rechnet, ist das immer ein Programmfehler. Der korrekte Zeitpunkt -um mal bei deinem Beispiel zu bleiben- x auf einen bestimmten Wert zu setzen, ist nicht nach der Schleife, sondern direkt vor der nächsten Operation mit x.
Revilo hat Folgendes geschrieben: | 2) Fehlermeldung "Falscher Parameter"
Originalwert und Parameter einer SUB, an den der Originalwert
übergeben wird, müssen denselben Datentyp haben.
Eine SUB die in ihrem Parameter eine kg - Angabe erwartet, kann
natürlich mit einer °C - Angabe nichts anfangen. 100 °C und 100 kg
haben zwar denselben Zahlenwert (hier eben 100), sind aber trotzdem
zwei ganz verschiedene Dinge.
So ist also eine (integer) - 7 etwas anderes, als eine (single) -7.
Integer = ganze Zahl ohne Kommastelle
Single, Double, Long = reelle Zahl mit Kommastelle, je nach
gewünschter Genauigkeit/Stellenanzahl.
Richtig? |
Falsch. Long ist in QBasic eine 32bit-Integerzahl. Und die Fehlermeldung "Falscher Parameter" bezieht sich auf den Datentyp, nicht auf die Bedeutung der Zahl. Auf welche Einheit sich der Zahlenwert bezieht, also ob °C oder kg, interessiert den Computer nicht, der sieht nur die Zahl. Die korrekte Interpretation der Zahl ist Sache des Programmierers, also Deine.
Revilo hat Folgendes geschrieben: | 3) DIM shared... ist grundsätzlich "Chef-Sache". Richtig? |
Nicht ganz. Wenn du eine Variable gleichen Namens als Parameter übergibst oder innerhalb einer Prozedur (also SUB oder FUNCTION) erneut deklarierst, wird sie dadurch lokal, gilt also nur innerhalb der Prozedur. Das bedeutet: Prozedur beendet ==> Variable weg.
EDIT: Das ist jetzt wohl missverständlich formuliert. Nur die lokale Variable von innerhalb der Prozedur ist weg, die SHARED-Variable außerhalb bleibt unangetastet.
Revilo hat Folgendes geschrieben: | 4) BYVAL (by value) und BYREF (by reference):
Ist das auch wieder ein FreeBasic-Syntax? In QBasic kenne ich es nicht.
|
Diese Unterscheidung gibt es in QBasic nicht, also vergiss es.
Revilo hat Folgendes geschrieben: | 5) Aufruf einer SUB:
Offenbar ist also Syntax 2)
- Fritz(a, b, c) - korrekt
Mit Klammern kann ich beim Aufruf also sowohl bei SUB' s als auch bei Funktionen nichts verkehrt machen. Richtig? |
Richtig.
Gruß
grindstone
EDIT: nemored war schon wieder schneller. Das ist deprimierend! Immerhin sehe ich, daß wir in einigen Punkten unterschiedliche Ansichten haben. _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Zuletzt bearbeitet von grindstone am 19.06.2024, 21:42, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Berkeley
Anmeldungsdatum: 13.05.2024 Beiträge: 71
|
Verfasst am: 19.06.2024, 21:39 Titel: |
|
|
Revilo hat Folgendes geschrieben: | 1) Schleifen:
i=0 ist zu Beginn einer Schleife unnötig
if i>10 then i=10 nach einer Schleife aber sinnvoll, um zu vermeiden, daß mit einer ungewollten 11 weiterechnet wird. Der Rechner kann nun mal kein Feld(11) bearbeiten, wenn es nur
von 1 bis 10 dimensioniert ist. Richtig?
|
Im Fall von FOR passiert das "i=1" ja mit "FOR i=1 TO 10". Du kannst mal mit "PRINT i" testen, ob nach der FOR-Schleife i tatsächlich 11 wäre. Glaub' ich aber nicht.
Wenn du die FOR-Schleife aber nicht "vorsätztlich" abbrichst - mit "EXIT FOR" - weil du mit der Schleife einen bestimmten Wert für i ermitteln willst, kannst du i auch einfach direkt auf 10 setzen - oder ggf. "FOR i=1 TO 9" machen, wenn dann 10 rauskommt, falls der letzte Durchlauf der Schleife unnötig ist, weil so oder so i=10 das Resultat ist. (Optimierung)
Revilo hat Folgendes geschrieben: | 2) Fehlermeldung "Falscher Parameter"
Originalwert und Parameter einer SUB, an den der Originalwert
übergeben wird, müssen denselben Datentyp haben.
|
In etwa. Der Typ BYTE wird mit BYVAL automatisch in INTEGER umgewandelt werden - sind ja beides Ganzzahlen. Aber ein String wird nicht in eine Zahl umgewandelt. Auch hier ist BASIC deutlich unkomplizierter als andere Programmiersprachen. Für BYREF muss logischerweise die übergebene Variable den exakten Datentyp haben, schließlich wird dann mit dessen Speicherplatz gearbeitet.
Revilo hat Folgendes geschrieben: | 3) DIM shared... ist grundsätzlich "Chef-Sache".
|
Es sind "globale" Variablen, auf die du aus jeder SUB zugreifen kannst, das sollte schon Sinn machen. Wie gesagt sollte ein "i" für deine Zählschleifen usw. NICHT global sein, weil eine SUB ja eine andere aufrufen könnte, die dasselbe "i" verwendet. Globale Variablen würde man bei einem Hack&Slay-Spiel wie Diablo / Nethack für die Charakterwerte verwenden. Die ändern sich z.B. nur bei einem "Levelup". Und sie werden vorallem von mehreren verschiedenen SUBs benötigt, will sie aber nicht alle ständig mit jedem Aufruf übergeben müssen.
Revilo hat Folgendes geschrieben: | 4) BYVAL (by value) und BYREF (by reference):
Ist das auch wieder FreeBasic-Syntax? In QBasic kenne ich es nicht.
|
Für BASIC ist es auf alle Fälle sehr ausgefallen, und zudem ein extrem fortschrittliches Konzept. Im Original-BASIC waren alle Variablen global, Unterprogramme hatten auch keine Parameter.
BYVAL(ue) übergibt einen Parameter nur als Wert. Du kannst daher eine Zahl bzw. String oder Variable mit passendem Typ übergeben.
BYREF(erence) übergibt die Adresse der Variable. Du kannst NUR eine Variable übergeben, keinen Wert, und sie muss den exakten Datentyp haben. Was die SUB oder FUNCTION damit auch macht, passiert mit dieser Variable, und nach der Rückkehr wird die Variable die geänderten Werte enthalten.
Revilo hat Folgendes geschrieben: | 5) Aufruf einer SUB:
Offenbar ist also Syntax 2)
- Fritz(a, b, c) - korrekt
Mit Klammern kann ich beim Aufruf also sowohl bei SUBs als auch bei Funktionen nichts verkehrt machen.
|
Bei SUBs sind sie unnötig, bei Funktionen könnte der Compiler schwerlich erkennen, dass es Parameter einer Funktion sind. Ein SUB-Aufruf kann nur die Parameter der SUB enthalten. Ein Funktionsaufruf kann in einer Formel stehen, zum Beispiel "volumen = KREISFLAECHE(32) * hoehe". Ohne Klammern... "volumen = KREISFLAECHE 32 * hoehe"... zumindest für Programmierer problematisch, zu lesen.
Revilo hat Folgendes geschrieben: | Das "AS INTEGER" steht nur in der DECLARE-Zeile und im Kopf des Unterprogramms, nicht aber beim Aufruf.
|
Beim Aufruf ist es ja auch völlig unnötig. Der verwendete Typ muss dann einfach passen, andernfalls kriegst du die Fehlermeldung, dass du einen falschen Parameter hast. Es würde ja keine SUB existieren, die mit den falschen Parametern was anfangen kann. Das "DECLARE" braucht man auch nur, wenn der Aufruf einer SUB im Quelltext vor der eigentlichen SUB kommt, weil der Compiler an dem Punkt die SUB noch nicht kennt und die Parameter nicht überprüfen kann. |
|
Nach oben |
|
|
Berkeley
Anmeldungsdatum: 13.05.2024 Beiträge: 71
|
Verfasst am: 19.06.2024, 21:48 Titel: |
|
|
nemored hat Folgendes geschrieben: | INTEGER und LONG sind ganze Zahlen, wobei ich nicht weiß, welchen Zahlenbereich sie in QBasic einnehmen. |
LONG ist IMMER 32 Bit - außer "LONG INTEGER" - das ist ein eigener Typ, nämlich ein 64 Bit Integer(Ganzzahl). Bei QBasic ist "Integer" laut der Onlinereferenz 16 Bit und deckt damit Werte von -32768 bis +32767 ab. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4663 Wohnort: ~/
|
Verfasst am: 19.06.2024, 22:46 Titel: |
|
|
Zitat: | 3) DIM shared... ist grundsätzlich "Chef-Sache". |
So wie ich die Frage verstanden habe: Nur im Hauptprogramm darf eine Deklaration mit SHARED stattfinden. Das ist für FreeBASIC richtig und für QBasic meines Wissens auch.
Zitat: | EDIT: nemored war schon wieder schneller. Das ist deprimierend! |
Finde ich überhaupt nicht. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4663 Wohnort: ~/
|
Verfasst am: 19.06.2024, 22:54 Titel: |
|
|
Berkeley hat Folgendes geschrieben: | Du kannst mal mit "PRINT i" testen, ob nach der FOR-Schleife i tatsächlich 11 wäre. Glaub' ich aber nicht. |
NEXT erhöht die Laufvariable erst um (Schrittweite) und vergleicht anschließend mit dem Endwert. Du kannst (unter FreeBASIC) gern mal folgendes Programm ausprobieren - aber bring viel Zeit mit.
Code: | FOR i AS UBYTE = 0 TO 255
PRINT i
NEXT |
Immerhin gibt es inzwischen eine hilfreiche Compiler-Warnung. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Berkeley
Anmeldungsdatum: 13.05.2024 Beiträge: 71
|
Verfasst am: 19.06.2024, 23:18 Titel: |
|
|
nemored hat Folgendes geschrieben: |
Code: | FOR i AS UBYTE = 0 TO 255
PRINT i
NEXT |
|
Ich will mir über so was nicht den Kopf zerbrechen und probier's dann einfach schnell aus. Auch so ein INSTR-MID-Gewurschtel. Liegt einer der Werte beim Testlauf um 1 daneben, pass' ich den Code einfach an... Z.B. ein "i-j-1" statt nur "i-j"... |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1243 Wohnort: Ruhrpott
|
Verfasst am: 19.06.2024, 23:48 Titel: |
|
|
Den Typ UBYTE gibt es in QBasic nicht.
@Berkely: Was nemored dir demonstrieren möchte, ist eine ungewollte Endlosschleife. Für den Datentyp UBYTE gilt: 255 + 1 = 0 . Das heisst, das Abbruchkriterium i = 256 wird niemals erfüllt. Da hilft dir auch das Herumprobieren nach Versuch und Irrtum nichts.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 120
|
Verfasst am: 20.06.2024, 14:58 Titel: |
|
|
Hallo nemored,
vielen Dank für deine Antwort.
Bei deiner Angabe:
FOR i = 1 TO 10
IF werte(i) >= 100 THEN EXIT FOR
NEXT
fiel mir ein, daß man so ja auch eine Endlosschleife vermeiden kann. Habe ich selbst schon "sicherheitshalber" des öfteren mal angewendet.
Danke, daß du es mir nochmals in's Gedächtnis gerufen hast.
Eine kleine Frage zu den Parametern in deiner Zeile
DECLARE SUB fritz(fritzA AS INTEGER, fritzB AS INTEGER, fritzC AS INTEGER) hätte ich noch (typische Anfänger-Frage):
Die SUB heißt fritz, die Parameter beginnen alle mit "fritz", also fritzA, fritzB, fritzC .
Sind diese roten "fritze" vom Syntax her zwingend so vorgeschrieben, um irgend einen Bezug zur aufgerufenen SUB fritz herzustellen oder könnten sie "theoretisch " auch Micki, Goofy und Donald heißen?
Gruß Revilo |
|
Nach oben |
|
|
Berkeley
Anmeldungsdatum: 13.05.2024 Beiträge: 71
|
Verfasst am: 20.06.2024, 16:12 Titel: |
|
|
grindstone hat Folgendes geschrieben: | Da hilft dir auch das Herumprobieren nach Versuch und Irrtum nichts. |
Doch, weil ich dann weiß, dass die Schleife nicht mit "=Endwert" endet, sondern mit "NOT <Endwert+STEP"... |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4663 Wohnort: ~/
|
Verfasst am: 20.06.2024, 16:14 Titel: |
|
|
Du kannst sämtliche Variablen (einschließlich Parameter) nennen wie du willst, solange es kein bereits reserviertes Schlüsselwort ist und solange es mit Buchstaben oder Unterstrich beginnt und ausschließlich aus Buchstaben (a-z; keine Umlaute), Ziffern und/oder Unterstrich besteht. Prinzipiell würde ich dazu raten, Namen zu wählen, die etwas über die Bedeutung der Variable aussagen, z. B.
Code: | DECLAre SUB berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER) |
Zur Endlosschleife: Eine FOR-Schleife endet immer irgendwann (außer man legt es darauf an, wie im obigen Beispiel, das so aber in QBasic gar nicht funktioniert - QBasic müsste eine Overflow-Kontrolle haben). Interessant zum Verlassen einer Endlosschleife ist da eher EXIT DO. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
Revilo
Anmeldungsdatum: 26.12.2022 Beiträge: 120
|
Verfasst am: 20.06.2024, 18:23 Titel: |
|
|
Hallo nemored,
aha, ein Parameter könnte also theoretisch auch Donald heißen.
Bedingung:
Der Parameter-Name muß mit einem Buchstaben beginnen, kann aber auch Ziffern und/oder Unterstriche enthalten. Richtig?
Was ist unter der Einschränkung: "solange es kein bereits reserviertes Schlüsselwort ist" zu verstehen? Meinst du damit Begriffe wie "Integer", "Single" oder "Long"?
Dein Syntax:
DECLAre SUB berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER)
enthält zwei verschiedene Datenformate, Double und Integer.
Welches dieser beiden ist für das Ergebnis "Gesamtkosten" zu wählen?
Sorry, aber lernen ist nie ein Spaziergang, nicht für den Schüler und auch nicht für den Lehrer. Wer schwimmen lernen will, muß solange erst mal Wasser schlucken, bis er kapiert hat, dies zu vermeiden. Das kann halt auch etwas dauern.
Da in meinem derzeitigen Programm nur natürliche Zahlen zur Anwendung kommen, bin ich gerade dabei, sämtliche Variablen und Parameter als integer zu definieren.
Ich brauche für mein Programm aber auch ein Feld namens Zelle. Dieses Feld muß 3 Dimensionen haben (9 Zeilen, 9 Spalten und 9 mögl. Werte in jeder Zelle)
Die ersten 1 to 9 sollen für die 1.Dimension, die Zeilen, stehen.
Die zweiten 1 to 9 sollen für die 2.Dimension, die Spalten, stehen.
Die dritten 1 to 9 sollen für die 3.Dimension, die dort mögl. Werte stehen.
Ich habe versucht es zu Beginn des Hauptprogramms wie folgt zu definieren:
DIM shared Zelle(1 to 9 as integer ,1 to 9 as integer, 1 to 9 as integer)
klappt aber nicht.
DIM shared Zelle(1 to 9, 1 to 9 , 1 to 9 ) as integer
klappt auch nicht.
Kannst du mir einen Tipp geben, was ich hier falsch mache?
Wie wäre es fachlich korrekt?
Gruß Revilo |
|
Nach oben |
|
|
Berkeley
Anmeldungsdatum: 13.05.2024 Beiträge: 71
|
Verfasst am: 20.06.2024, 19:39 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Was ist unter der Einschränkung: "solange es kein bereits reserviertes Schlüsselwort ist" zu verstehen? Meinst du damit Begriffe wie "Integer", "Single" oder "Long"? |
Genau. Oder auch "PRINT", "DIM", "CHR" etc. Grundsätzlich gilt es für alles was schon definiert ist, genauso wie deine eigenen Variablen und SUBs. "Schlüsselwort" ist mehr ein Begriff der Programmiersprache C, für die "Befehle", die C kennt.
Revilo hat Folgendes geschrieben: | DECLAre SUB berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER)
enthält zwei verschiedene Datenformate, Double und Integer.
Welches dieser beiden ist für das Ergebnis "Gesamtkosten" zu wählen? |
War doch nur ein Beispiel wie du SUBs und Parameter benennen solltest. Ist ja nicht mal klar was für Gesamtkosten diese SUB berechnen soll, oder für was für ein Programm die ist...
Revilo hat Folgendes geschrieben: | Ich habe versucht es zu Beginn des Hauptprogramms wie folgt zu definieren:
DIM shared Zelle(1 to 9 as integer ,1 to 9 as integer, 1 to 9 as integer)
klappt aber nicht.
DIM shared Zelle(1 to 9, 1 to 9 , 1 to 9 ) as integer
klappt auch nicht. |
Das erste ist ja auch so was von eindeutig verkehrt... Beim zweiten mag vielleicht QBasic die Syntax nicht.
Das FreeBASIC-Portal samt Referenz kennst du ? https://www.freebasic-portal.de/befehlsreferenz/dim-175.html |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4663 Wohnort: ~/
|
Verfasst am: 20.06.2024, 20:44 Titel: |
|
|
Revilo hat Folgendes geschrieben: | Dein Syntax:
DECLAre SUB berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER)
enthält zwei verschiedene Datenformate, Double und Integer.
Welches dieser beiden ist für das Ergebnis "Gesamtkosten" zu wählen? |
Mein Gedanke bei der Deklaration war, dass Preise in der Regel Nachkommastellen besitzen können, die Stückzahl aber eine ganze Zahl ist. Die Gesamtkosten können dann ebenfalls Nachkommastellen besitzen. Das folgt aber nicht aus den Parametern, sondern erschließt sich dann ganz konkret durch die Funktionsweise der SUB, die hier ja nicht weiter ausgeführt ist.
Code: | DIM shared Zelle(1 to 9, 1 to 9 , 1 to 9 ) as integer |
funktioniert in FreeBASIC mit QBasic-Kompatibilitätsmodus, und nach meinem QBasic-Buch sollte es ebenfalls funktionieren. Gibt dir QBasic eine aussagekräftige Fehlermeldung? _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1243 Wohnort: Ruhrpott
|
Verfasst am: 21.06.2024, 09:57 Titel: |
|
|
Code: | DIM shared Zelle(1 to 9, 1 to 9 , 1 to 9 ) as integer | ist korrektes QBasic und gibt keine Fehlermeldung.
Revilo hat Folgendes geschrieben: | Dein Syntax:
DECLAre SUB berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER)
enthält zwei verschiedene Datenformate, Double und Integer.
Welches dieser beiden ist für das Ergebnis "Gesamtkosten" zu wählen?
| Wenn du damit Gesamtkosten berechnen möchtest, solltes du besser eine Funktion verwenden Code: | DECLARE FUNCTION berechneGesamtkosten(einzelpreis AS DOUBLE, stueckzahl AS INTEGER) AS DOUBLE |
Zitat: | Die ersten 1 to 9 sollen für die 1.Dimension, die Zeilen, stehen.
Die zweiten 1 to 9 sollen für die 2.Dimension, die Spalten, stehen.
Die dritten 1 to 9 sollen für die 3.Dimension, die dort mögl. Werte stehen. | Das sieht mir jetzt irgendwie nach Sudoku aus.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|