Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Verwendung von SUB und FUNCTION in mehreren Programmen

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 01.04.2022, 12:36    Titel: Verwendung von SUB und FUNCTION in mehreren Programmen Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 01.04.2022, 13:14    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 01.04.2022, 13:33    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 01.04.2022, 18:51    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 01.04.2022, 19:33    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 01.04.2022, 20:29    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 02.04.2022, 11:59    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2022, 14:11    Titel: Antworten mit Zitat

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
  1. #DEFINE / ENUM / CONST
  2. TYPE ... END TYPE
  3. DECLARE-Zeilen
  4. SUB / FUNCTION

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 02.04.2022, 15:16    Titel: Antworten mit Zitat

Danke! Langsam sortiert sich das bei mir lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2022, 15:29    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 02.04.2022, 15:58    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2022, 16:39    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 02.04.2022, 16:55    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2022, 17:25    Titel: Antworten mit Zitat

DECLARE SHARED ist ein Fehler. Vielen Dank; ich werde es ausbessern. lächeln
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
kilix



Anmeldungsdatum: 05.02.2022
Beiträge: 175

BeitragVerfasst am: 02.04.2022, 18:11    Titel: Antworten mit Zitat

ich wußte nicht mehr siche ob du der Autor dieses Handbuchs bist, Dazu kann ich dir nur gratulieren!
_________________
Grüße
kilix
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 02.04.2022, 18:32    Titel: Antworten mit Zitat

Danke dir. Es freut mich, wenn es hilfreich ist. lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz