|
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 |
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 01.04.2022, 13:36 Titel: Verwendung von SUB und FUNCTION in mehreren Programmen |
|
|
Ich habe mehrere Programme die alle die gleichen Funktionen und/oder SUBs verwenden. Bisher habe ich diese in jedes Programm kopiert was aber offenbar nicht nötig ist. Mit PUBLIC bzw ohne, weil default, sollte es genügen diese Funktionen nur in einem Programm zu haben.
Ich hab das versucht und eine Funktion mit zugehöriger SUB aus einem Programm A in das Programm B (das diese Funktion gar nicht benötigt) verschoben. Das Programm B ließ sich compilieren und aufrufen aber beim Programm A stürzte wxFBE beim Compilieren ab.
Was muss ich machen damit das Programm B, ohne selbst die Funktion samt SUB zu enthalten, lauffähig ist und die Funktion verwenden kann?
Ich vermute, dass das mit dem DECLARE-Befehl zusammenhängt, aber wie?
Leider habe ich in den Handbüchern darüber nichts gefunden was mir weiterhilft (oder hab es unwissentlich überlesen). _________________ Grüße
kilix |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1213 Wohnort: Ruhrpott
|
Verfasst am: 01.04.2022, 14:14 Titel: |
|
|
Sowas lässt sich in FB ganz einfach mit Bibliotheken lösen, die über #Include eingebunden werden.
bibliothek.bi Code: | Function quadrat(a As Integer) As Integer
Return a*a
End Function
Function doppel(a As Integer) As Integer
Return 2 * a
End Function |
programm1.bas Code: | #Include "bibliothek.bi"
Print quadrat(5)
Sleep |
programm2.bas Code: | #Include "bibliothek.bi"
Print doppel(3)
Sleep |
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 01.04.2022, 14:33 Titel: |
|
|
danke grindstone!
das scheint genau das zu sein was ich brauche. Ich dachte auch schon daran ein "Programm" nur mit Funktionen zu schreiben aber wußte nicht wie.
Nun kann ich in einer Blibiothek alle Funktionen sammeln die ich öfter brauche. _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 01.04.2022, 19:51 Titel: |
|
|
Ich empfehle an dieser Stelle auch die Nutzung von #PRAGMA ONCE und/oder #INCLUDE ONCE. Wenn dann beispielsweise von verschiedenen eingebundenen Dateien dieselbe Funktionssammlung benötigt wird, verhindert es, dass die Sammlung mehrfach eingebunden wird (was zum Kompilierfehler "Duplicated definition" führen würde).
#PRAGMA ONCE steht dabei in der Datei mit der Funktionssammlung, während #INCLUDE ONCE "bibliothek.bi" in den Dateien steht, welche die Funktionssammlung einbinden. Eine von beiden Methoden reicht aus, beides gleichzeitig schadet jedoch auch nicht. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 01.04.2022, 20:33 Titel: |
|
|
Danke für den Hinweis!
ich hab noch eine Frage: nemored, erinnerst du dich an meine Frage betreffend die Umwandlung von Umlauten und Sonderzeichen. Du hast damals die Funktion "ersetzeZeichen", die von der SUB "ersetzeUmlaute" aufgerufen wird geschrieben bzw. ergänzt.
Code: |
DECLARE SUB ersetzeUmlaute(byref text as string)
'
' Ersetzen von Umlauten und Sonderzeichen
'
function ersetzeZeichenkette(text as string, alt as string, neu as string) as string
dim z as uinteger, ret as string = text
do
z = instr(ret, alt)
if z = 0 then exit do
ret = left(ret, z-1) & neu & mid(ret, z+len(alt))
loop
return ret
end FUNCTION
'
sub ersetzeUmlaute(byref text as string)
text = ersetzeZeichenkette(text, chr(195, 164), chr(132)) ' ä
text = ersetzeZeichenkette(text, chr(195, 182), chr(148)) ' ö
text = ersetzeZeichenkette(text, chr(195, 188), chr(129)) ' ü
text = ersetzeZeichenkette(text, chr(195, 132), chr(142)) ' Ä
text = ersetzeZeichenkette(text, chr(195, 150), chr(153)) ' Ö
text = ersetzeZeichenkette(text, chr(195, 156), chr(154)) ' Ü
text = ersetzeZeichenkette(text, chr(195, 159), chr(225)) ' ß
text = ersetzeZeichenkette(text, chr(195, 161), chr(133)) ' a mit accenr grave
text = ersetzeZeichenkette(text, chr(195, 165), chr(133)) ' a mit accenr grave
text = ersetzeZeichenkette(text, chr(195, 162), chr(131)) ' a mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 169), chr(130)) ' e mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 168), chr(138)) ' e mit Accent grave
text = ersetzeZeichenkette(text, chr(195, 170), chr(136)) ' e mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 173), chr(161)) ' i mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 174), chr(140)) ' i mit Accent circonflex
text = ersetzeZeichenkette(text, chr(195, 179), chr(162)) ' o mit Accent aigu
text = ersetzeZeichenkette(text, chr(178), chr(149)) ' o mit Accent grave
text = ersetzeZeichenkette(text, chr(180), chr(147)) ' o mit Accent circonflex
text = ersetzeZeichenkette(text, chr(199, 146), chr(208)) ' o mit Tilde?
text = ersetzeZeichenkette(text, chr(195, 186), chr(163)) ' u mit Accent aigu
text = ersetzeZeichenkette(text, chr(195, 177), chr(164)) ' n mit Tilde
text = ersetzeZeichenkette(text, chr(194, 187), chr(175)) ' kleine spitze Klammer zu
text = ersetzeZeichenkette(text, chr(194, 171), chr(174)) ' kleine spitze Klammer auf
text = ersetzeZeichenkette(text, chr(177), chr(176)) ' kleine spitze Klammer auf
text = ersetzeZeichenkette(text, chr(194, 182), chr(244)) ' verkehrtes P
text = ersetzeZeichenkette(text, chr(194, 183), chr(240)) ' kleines Minus
text = ersetzeZeichenkette(text, chr(194, 178), chr(253)) ' ²
text = ersetzeZeichenkette(text, chr(194, 167), chr(021)) ' §
text = ersetzeZeichenkette(text, chr(34, 34), chr(34)) ' "
text = ersetzeZeichenkette(text, chr(195), "") ' Leerstring
end SUB
|
Diese SUB samt Funktion würde ich gerne in die Bibliothek übernehmen. Nachdem beim Theme Bibliothek bisher nur Funktionen genannt wurden meine Frage: kann ich auch SUBs in Bibliotheken schreiben? _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 01.04.2022, 21:29 Titel: |
|
|
Klar. Wenn du willst, kannst du dort auch wichtige Konstanten definieren. Theoretisch kannst du dort auch direkt ausführbaren Code platzieren, das widerspricht aber der Idee einer Bibliothek, weshalb ich es (für diesen Zweck) nicht sinnvoll finde. Aber zum Splitten eines Programms in mehrere Teile ist es durchaus möglich. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 02.04.2022, 12:59 Titel: |
|
|
ich habe noch eine Frage zu dem obigen Beispiel "ersetzeUmlaute":
Diese SUB samt zugehöriger Funktion habe ich in der Bibliothek eingetragen.
Das Anwendungsprogramm ruft die SUB auf die dann die Umwandlung mit Hilfe der Funktion macht.
Ursprünglich hatte ich SUB und FUNKTION im Anwendungsprogramm und, weil die SUB am Ende des Programmes war, am Beginn des Programmes den Befehl
DECLARE SUB.
Wie ist das nun seit ich beides in der Bibliothek habe?
- brauche ich dadas Declae SUB?
- muss es im Programm oder in der Bibliothek sein?
- im Programm muss es dann sicher wieder am Programmanfang stehen aber wo
muss es in der Bibliothek stehen, einfach vor der Funktion (wie oben im
Beispiel) oder am Anfang der Bibliothek? _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 02.04.2022, 15:11 Titel: |
|
|
Es ist ganz einfach so, dass die Programmzeilen beim Kompilieren "von oben nach unten" abgearbeitet werden. Wenn du in der bibliothek.bi die SUB ersetzeUmlaute() drin hast und in deinem Programm meinProgramm.bas nutzen willst, muss das #INCLUDE bibliothek.bi eingebaut werden, bevor du ersetzeUmlaute() aufrufst (außer du arbeitest in meinProgramm.bas selbst mit einem DECLARE, was ich so jetzt aber nicht machen würde).
Innerhalb der bibliothek.bi muss nun wiederum die SUB bekannt sein, bevor sie aufgerufen werden kann. Das ist wichtig, wenn sich Unterprogramme gegenseitig aufrufen. Heißt: Wenn in der SUB foo() die SUB bar() aufgerufen wird, muss bar() vor foo() stehen oder mit DECLARE deklariert worden sein. Wenn sowohl von SUB foo() ein Aufruf von bar() erfolgt als auch in der SUB bar() ein Aufruf von foo(), kommst du um die DECLARE-Zeile nicht herum. Kommt so etwas in deiner Bibliothek nicht vor, dann brauchst du an sich auch kein DECLARE.
Trotzdem ist es gute Praxis, die DECLARE-Zeilen immer anzugeben - dann oben in der Bibliothek, vor den eigentlichen SUBs und FUNCTIONs - weil dann zum einen alle verfügbaren Header noch einmal gebündelt beisammen stehen (wenn man sich schnell einen Überblick über den Funktionsumfang bzw. die Aufrufkonvention verschaffen will) und du dir zum anderen dann keine weitere Gedanken mehr machen musst, wenn sich die Unterprogramme gegenseitig aufrufen.
edit zu "oben in der Bibliothek" - Des Öfteren verwende ich innerhalb einer Bibliothek eigene UDTs, die dann natürlich, wenn sie in den Unterprogrammen gebraucht werden, vor den DECLARE-Zeilen stehen müssen. Meine Reihenfolge in einer Bibliothek ist üblicherweise
- #DEFINE / ENUM / CONST
- TYPE ... END TYPE
- DECLARE-Zeilen
- SUB / FUNCTION
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 02.04.2022, 16:16 Titel: |
|
|
Danke! Langsam sortiert sich das bei mir
Jetzt habe ich ein Problem mit globale Variablen. Ich lese in eine SUB (in der Bibliothek) eine Zeiel aus einem Parametertextfile ein und extrahiere 2 Werte (VarA und VarB)
So sieht das in MEINPROGRAMM.BAS aus:
Code: |
#INCLUDE ONCE "EIGENE.BI" ' eigene Funktionen und SUBs
DIM SHARED AS INTEGER VarA, VarB
BerechnungAB ' SUB zur Berechnung von VarA und VarB
PRINT VarA,VarB
|
und diese SUB steht in der Bibliothek:
Code: |
DECLARE SUB BerechnungAB
SUB BerechnungAB
DIM AS STRING zeile
DIM AS INTEGER tx = FREEFILE
OPEN "PARAM.TXT" FOR INPUT AS #tx
LINE INPUT #tx, zeile
VarA = VAL(LEFT(zeile, 3))
VarB = VAL(RIGHT(zeile, 3))
CLOSE #tx
END SUB
|
Das bringt diese Fehlermeldungen für die Bibliothek:
uild-Fehler:
F:\EIGENE.BI(15) error 42: Variable not declared, VarA in 'VarA = VAL(LEFT(zeile, 3))'
F:\EIGENE.BI(16) error 42: Variable not declared, VarB in 'VarB = VAL(RIGHT(zeile, 3))'
Das verstehe ich nicht weil ich, wie es im Handbuch für Einsteiger beschrieben ist, den Befehl DIM SHARED im Hauptprogramm damit solten das doch Variable sein, die man sowohl im Hauptprogramm als auch in der SUB in der Bibliothek verwenden kann.
(Anmerkung: DIM weil DECLARE SHARED brachte eine Fehlermeldung für das Hauptprogramm) _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 02.04.2022, 16:29 Titel: |
|
|
Trotzdem arbeitet der Compiler die Befehlszeilen von oben ab, und dann stößt er zuerst auf das #INCLUDE und findet in der EIGENE.BI die Variablen VarA und VarB, die bis dahin noch nicht deklariert wurden. Du müsstest die globalen Variablen vor dem #INCLUDE deklarieren.
Aber warum nicht so herum?
Programm
Code: | #INCLUDE ONCE "EIGENE.BI" ' eigene Funktionen und SUBs
DIM SHARED AS INTEGER VarA, VarB
BerechnungAB(VarA, VarB)
PRINT VarA,VarB
|
Bibliothek:
Code: | DECLARE SUB BerechnungAB(BYREF a AS INTEGER, BYREF b AS INTEGER)
SUB BerechnungAB(BYREF a AS INTEGER, BYREF b AS INTEGER)
DIM AS STRING zeile
DIM AS INTEGER tx = FREEFILE
OPEN "PARAM.TXT" FOR INPUT AS #tx
LINE INPUT #tx, zeile
a = VAL(LEFT(zeile, 3))
b = VAL(RIGHT(zeile, 3))
CLOSE #tx
END SUB |
_________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 02.04.2022, 16:58 Titel: |
|
|
Danke!
An so etwas hab ich auch einmal gedacht aber wenn ich die SUB aufrufe muss ich als VarA und VarB 0 eingeben weil sie ja erst in der SUB ermittelt werden. Deshalb habe ich diese Lösung nicht mehr verfolgt.
Um es zu verstehen:
ich habe verstanden, dass der Computer das Programm von oben nach unten durcharbeitet. Was mir nicht klar war ist, dass er durch das INCLUDE die BI durchliest bevor er im Hauptprogramm weiterliest.
D.h. eigentlich, dass ich das DIN SHARED auch vor das INCLUDE schreiben kann, was ich auch jetzt getan habe. Jetzt hatte ich keinen Fehler mehr beim Compilieren.
Wenn ich aber die beiden Lösungen vergleiche gefällt mir deine besser weil das DIM Shared dort steht wo es von der Sache her benötigt wird (der Zusammenhang bleibt bestehen).
Oder gibt es einen anderen Grund, z.B., dass vor dem INCLUDE keine anderen Befehle stehen sollen? _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 02.04.2022, 17:39 Titel: |
|
|
Der einzige Grund, der mir einfällt, ist die Ordnung / Lesbarkeit. Wenn das #INCLUDE sehr weit oben steht, sieht man sofort, was alles eingebunden wird. Wenn sich das #INCLUDE irgendwo tief im Quelltext "versteckt", halte ich das für nicht besonders gut, was die Wartbarkeit des Codes betrifft. Ansonsten darf vor dem #INCLUDE durchaus auch noch was anderes stehen. Bei mir sind das z. B. immer mal wieder #DEFINE-Zeilen, die Einfluss auf die inkludierte Datei nehmen.
Der Grund, warum ich in meinem Vorschlag die SHARED-Variablen aus der EIGENE.BI herausgenommen habe, ist, um die EIGENE.BI unabhängig vom Hauptprogramm zu machen - so kannst du sie auch in ein anderes Programm einbinden, ohne dass dieses Programm zwingend genau diese globalen Variablen verwenden muss. (Bei #DEFINE kann man dann entsprechende Schalter definieren, die dann unterschiedlich arbeiten, je nachdem ob bereits ein #DEFINE erfolgt ist oder nicht. Dann ist es letztlich auch wieder unabhängig vom Hauptprogramm) _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 02.04.2022, 17:55 Titel: |
|
|
Danke für die Hilfe und Geduld! Jetzt läuft es super und ich finde immer mehr was sich als SUB oder Funktion eignet!
Aber eine Frage habe ich noch: wenn ich was brauche suche ich meist im Einsteigerhandbuch. Das ist sehr klar und verständlich geschrieben. Dort steht aber unter 12.2.2 Globale Variablen, dass sie mit DECLARE SHARED definiert werden.
Ich weiß nicht warum das bei mir der Compiler als Fehler gebracht hat, DIM SHARED hat er dann akzeptiert. _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 02.04.2022, 18:25 Titel: |
|
|
DECLARE SHARED ist ein Fehler. Vielen Dank; ich werde es ausbessern. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
kilix
Anmeldungsdatum: 05.02.2022 Beiträge: 175
|
Verfasst am: 02.04.2022, 19:11 Titel: |
|
|
ich wußte nicht mehr siche ob du der Autor dieses Handbuchs bist, Dazu kann ich dir nur gratulieren! _________________ Grüße
kilix |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4601 Wohnort: ~/
|
Verfasst am: 02.04.2022, 19:32 Titel: |
|
|
Danke dir. Es freut mich, wenn es hilfreich ist.
Der Fehler ist ausgebessert. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
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.
|
|