|
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 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 28.06.2010, 21:27 Titel: Nanoprojekt: Ref(ReferenceIdentifier, PointerIdentifier) |
|
|
Ein kleines Projekt das mir, auch wenns nur ein 3 Zeiler ist, viel Nerven gekostet und an anderen Stellen, viele Nerven erspart hat :
Code: |
#macro ref(RefID, PtrID)
#define RefID *cast(TypeOf(PtrID),PtrID)
#endmacro
|
damit referenziert man eine pointervariable.
Bei einigen meiner projekten kam ich des öfteren damit durcheinander ob ich elemente einer type mit -> oder mit . ansprechen muss. Da hab ich mir was einfallen lassen um alles nur noch mit punkten ( . ) anzusprechen. Hier ein kleines beispiel:
Code: |
#macro ref(RefID, PtrID)
#define RefID *cast(TypeOf(PtrID),PtrID)
#endmacro
type testtype
a as integer
b as integer
declare operator cast as string
end type
operator testtype.cast as string
return "" & a & " ..." & b
end operator
dim testpointer as testtype ptr
print "changing pointer values"
testpointer = new testtype
testpointer->a = 1234
testpointer->b = 5678
print "showing pointer values"
print *testpointer
print "a=" & testpointer->a
print "b=" & testpointer->b
ref(testreference, testpointer)
print "showing reference values"
print testreference
print "a=" & testreference.a
print "b=" & testreference.b
print "changing reference values"
testreference.a = 678
testreference.b = 789
print "showing pointer values"
print *testpointer
print "a=" & testpointer->a
print "b=" & testpointer->b
print "showing reference values"
print testreference
print "a=" & testreference.a
print "b=" & testreference.b
sleep
|
Nach meinen erfahrungen ist das macro leider nur so realisierbar.
Wenns einem was nützt, oder andere ideen zur referenzierung von pointern hat, lassts mich wissen |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 29.06.2010, 02:21 Titel: |
|
|
das is aber ganz gefährlicher zündstoff.. sowas kannst du zum beispiel (denk ich mal) nicht in zwei subs mit dem selben namen benutzen oder? #define sind preprozessor-anweisungen und ignorieren damit scopes, das heßit sowas wie "nur in der sub" oder ähnliches existiert vermutlich noch nicht.. aber gut, wenn die sprache einen nötigt, von hand mit pointern rumzumachen, dann kann man sowas irgendwie verstehen ;p _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 29.06.2010, 09:41 Titel: |
|
|
doch klar sind bezeichner die mit define erstellt wurden nur im aktuellen scope oder sub oder funktion verfügbar
(ich benutze den fbc v0.20b)
einfach mal ausprobieren |
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 29.06.2010, 12:11 Titel: |
|
|
dafür bräuchte ich ja fb installiert ;p naja gut wenn das funktioniert ist fein.
aber mal als denkanstoß: was passiert wenn du sowas tust:
Code: | ref(testreference, testpointer)
print 2 testreference.a |
was #define nämlich meistens veranlasst ist einfaches string-replacement, das heißt aus
> print 2 testreference.a
dürfte
> print 2 *cast(TypeOf(PtrID),PtrID).a
werden, was der compiler als multiplikation interpretiertieren dürfte.
vermutlich *solltest* du dein macro als
#define RefID (*cast(....))
definieren, also mit einer ladung klammern extra um sowas zu vermeiden.
aber keine ahnung ob das wirklich passiert ;P probiers einfach mal aus. könnte im ernstfall halt seltsame bugs geben. irgendwo hatte ich das mal für den C-compiler gelesen, das lief ungefähr so:
Code: | #define six 1+5
#define nine 8+1
print six * nine |
und das ergebnis ist nicht wie zu erwarten
(1+5)*(8+1) = 6*9 = 54
sondern dummerweise
1+5*8+1 = 1+40+1 = 42
weiß aber wie gesagt nicht ob FB das genauso verarbeitet, ausprobieren. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 29.06.2010, 13:14 Titel: |
|
|
ja ok, ich kann mir gut vorstellen das es so zu fehlern kommen könnte, auch wenn das in deinem konkreten beispiel nicht der fall ist (habs grade noch ausprobiert).
ich teste das makro mit deinen vorgeschlagenen klammern aus, wenn das überall funktioniert nehm ich die gerne dauerhaft ins makro auf
warum hast du kein freebasic installiert? |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 29.06.2010, 18:05 Titel: |
|
|
Wahrscheinlich, weil er es nicht verwendet. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 29.06.2010, 20:47 Titel: |
|
|
hm.. na egal, er wird sein gründe haben
und leider funktioniert die geklammerte version:
Code: |
#macro ref(RefID, PtrID)
#define RefID (*cast(TypeOf(PtrID),PtrID))
#endmacro
|
leider nicht überall (
z.B.
Code: |
#macro ref(RefID, PtrID)
#define RefID (*cast(TypeOf(PtrID),PtrID))
#endmacro
screen 16,32
type tile64
x as integer
y as integer
image as any ptr = imagecreate(64,64,rgb(255,0,0))
end type
dim tilepointer as tile64 ptr = new tile64
ref(Tile,tilepointer)
put (0,0), tile.image
|
klappt nicht.
während:
Code: |
#macro ref(RefID, PtrID)
#define RefID *cast(TypeOf(PtrID),PtrID)
#endmacro
screen 16,32
type tile64
x as integer
y as integer
image as any ptr = imagecreate(64,64,rgb(255,0,0))
end type
dim tilepointer as tile64 ptr = new tile64
ref(Tile,tilepointer)
put (0,0), tile.image
|
einwandfrei kompiliert und funktioniert |
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 29.06.2010, 21:24 Titel: |
|
|
Man könnte es auch so machen:
Code: | Screen 16,32
type tile64
x as integer
y as integer
image as any ptr = imagecreate(64,64,rgb(255,0,0))
end type
Dim tilereference As tile64
dim tilepointer as tile64 ptr = @tilereference
put (0,0), tilereference.image
sleep |
Generell kann ich nicht verstehen, wofür man das braucht. Ein Pointertype braucht den Pfeil und ein normaler Type den Punkt. Wenn man sich das nicht merken kann, dann sollte man die Variablen entsprechend benennen.
Der Aufwand das Macro aufzurufen wär mir ja zu viel, aber gut, jedem das seine. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 29.06.2010, 22:32 Titel: |
|
|
MOD hat Folgendes geschrieben: | Wenn man sich das nicht merken kann, dann sollte man die Variablen entsprechend benennen. |
Dazu gibt es ja auch passende Konventionen (auch wenn manche Leute solche Präfixe nicht mögen)... z.B. "i" oder "n" als Präfix für ints, "p" für Pointer... _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 30.06.2010, 09:56 Titel: |
|
|
@mod: dein vorschlag ist nicht unbedingt genauso "praktikabel", denn oft kann man es sich als programmierer nicht aussuchen was man als returnwert einer x-beliebigen api-funktion zurück bekommt. meiner erfahrung nach bekommt man von strukturen meistens nur den pointer zurückgeliefert. z.b. bei der funktion imagecreate bekommt man einen zeiger auf eine fb.image-struktur zurückgeliefert.
sowas kann man dann schön mit diesem macro referenzieren.
aber ob man das letzten endes wirklich braucht, stell ich erstmal dahin. ich. hab auch lange und gut ohne dieses macro Programmieren können... jetzt mag ichs kaum noch missen ..
im englischen forum hab ich mir sagen lassen das es unter java z.b. gar keine pointer sondern nur da werden objekte wohl nur per referenz angesprochen.. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.06.2010, 19:22 Titel: |
|
|
OneCypher hat Folgendes geschrieben: | im englischen forum hab ich mir sagen lassen das es unter java z.b. gar keine pointer sondern nur da werden objekte wohl nur per referenz angesprochen.. |
Da ist einfach alles, was kein primitiver Datentyp ist, sofort als Pointer (Zeiger, Referenz, wie auch immer du es nennen willst), behandelt. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
MOD Fleißiger Referenzredakteur
Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 30.06.2010, 19:23 Titel: |
|
|
Wie gesagt, eigentlich weiß man immer, ob es ein Pointer ist oder nicht. Eine Variable, die mit ImageCreate belegt wird, muss vom Typ Any Ptr bzw fb.image Ptr sein. Der Rückgabewert ist immer bekannt. Damit ist es ein leichtes, etwa wie Jojo sagt, Präfixe zu verwenden. Ob Punkt oder Pfeil, da hatte ich nie Probleme, kommt für mich aufs gleiche raus.
Ja, in Java gibt es keine Pointer aus "Sicherheitsgründen". Alles was der Garbagecollector nicht abgreifen würde, könnte ja liegen beleiben, aber das wäre wohl ein anderer Flame |
|
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.
|
|