PureBoard
http://forums.purebasic.com/german/

Programmier Tipps und Tricks
http://forums.purebasic.com/german/viewtopic.php?f=8&t=4840
Seite 1 von 3

Autor:  PAMKKKKK [ 17.09.2005 18:40 ]
Betreff des Beitrags:  Programmier Tipps und Tricks

Ich mach hier mal eine Sammlung von meinen (kleinen) Programmiertricks für Anfänger mit PB.
Ich hoffe das macht ein Board Admin Sticky!

Mehrere Zeilen Kommentieren
Wer sich schon einmal darüber geärgert hat, das man in PB nicht mehrere Zeilen Kommentieren kann.
Hier ist eine einfache sehr Lösung ohne vor jede Zeile Semikolons zu setzen.
Mit CompilerIf 1=2 (ergibt False) werden die nachfolgendenZeilen nicht ausgeführt bis CompilerEndIf auftaucht.
Wenn man die Zeilen wieder braucht ändert man die Zeile in CompilerIf 1=1 (ergibt True)
Code:
CompilerIf 1=2
  ; Code wird nicht ausgeführt und nicht kompiliert
  ; Code wird nicht ausgeführt und nicht kompiliert
  ; Code wird nicht ausgeführt und nicht kompiliert
  ; Code wird nicht ausgeführt und nicht kompiliert
CompilerEndIf

Code:
CompilerIf 1=1
  ; Code wird ausgeführt und kompiliert
  ; Code wird ausgeführt und kompiliert
  ; Code wird ausgeführt und kompiliert
  ; Code wird ausgeführt und kompiliert
CompilerEndIf


-------------------------------------------------------

IF NOT
PureBasic hat ja nun mal keinen NOT Operator bei IF abfragen.
Da in PureBasic auch negative Werte True sind, und nur die 0 als False gewertet wird (Das sollte mal in die PB Hilfe geschrieben werden!!), kann man bei Rückgabewerten aus Funktionen Testen ob die Funktion 0 zurückgibt.
Beispiel:
Code:
If OpenWindow(2, 100, 100, 200, 100, #PB_Window_SystemMenu, "Window") = 0
  MessageRequester("Fehler", "Fenster konnte nicht geöffnet werden!", #MB_OK|#MB_ICONERROR)
  End ; oder ErrorHandler()
EndIf

Bei dieser Schreibweise ist das IF und ENDIF nahe beisammen.

Man kann sich auch sein eigenes NOT basteln:
Code:
  Procedure Not(expression)
    if expression ; ACHTUNG auch negative Werte sind TRUE!!!!!
      ProcedureReturn 0
    else
      ProcedureReturn 1 ; Nur True wenn  expression = 0
    endif
  EndProcedure
  ;
  a.l = 0
  If Not(a.l)
    PrintN("false")
  Endif
EndIf

(Quelle: http://www.xs4all.nl/~bluez/datatalk/pure1.htm#top)

Die oberen Beispiele Funktionieren aber nicht, wenn man mehrere abfragen mir AND oder OR verknüpft.
Da hilft es dann nur noch den ELSE Zweig zu missbrauchen.
Das Funktioniert immer mit jeder IF variante
Code:
If a=10 And b>=10 And c=20
Else
  MessageRequester("NOT !","Es ist NICHT a=10 And b>=10 And c=20")
EndIf

test = 0
If test
Else
  MessageRequester("If test","test ist NOT TRUE")
EndIf



-------------------------------------------------------


Debuging
Da PureBasic Variablen nicht Automatisch umwandelt (Casted), muss man beim Debuggen immer Zahlen in Strings wandeln,( mit STR(), STRF() usw….).Wen das ein bisschen nervt der kann das in zwei Zeilen Schreiben:

Code:
 ; Schreibweise in einer Zeile
test = 5
Debug "Der Wert von test ist = " + Str(test)

;Schreibweise in 2 Zeilen
test = 7
Debug "Wert von test:"
Debug test



Wenn ihr auch noch Tips habt dann schreibt sie hier. Wir sammel Sie

Autor:  AndyX [ 08.10.2005 20:56 ]
Betreff des Beitrags: 

Die Variablen werden eigentlich schon gecastet. nur halt nicht String zu Zahl und umgekehrt.

If-ElseIf / Select-Case

Lieber

Code:
If bla
  bla()
Elseif blaaaa
  Baaaa()
.....


statt

Code:
Select blaaaaaa
  Case bla
  case Ballllllllaaaaa
    blaaaaaa()
.........


nutzen. Is viel schneller.

Außerdem gibts ja noch diese Lösung:

Code:
Procedure MachWas()
  Print("Ich mach was")
EndProcedure
Procedure GibWasAus(bla.s)
  Print("Ich gebe aus: "+bla)
EndProcedure

Dim Table(1)
Table(0) = @MachWas()
Table(1) = @GibWasAus()

OpenConsole()
input$ = Input()
If input$ = ""
  CallFunctionFast(Table(0))
ElseIf
  CallFunctionFast(Table(1),input$)
Endif


Das hat mir ein Kumpel empfohlen, habs noch nicht genau testen können, obs schneller ist.

Autor:  #NULL [ 20.04.2006 10:18 ]
Betreff des Beitrags: 

hab hier mal was kleines banales für alle, die von ständgigem
Code:
If InitOderOpenIrgendwas()=0
  MessageRequesterUndDieZeileWillNichEnden(.....)
  End
EndIf

genervt sind:
Code:
Procedure check(value.l, text.s)
   If value=0
      MessageRequester("error", text, 0)
      End
   EndIf
EndProcedure

damit kann man ein bisschen platz sparen, z.b so :
Code:
check( InitSprite(), "initsprite() failed")
check( InitKeyboard(), "initkeyboard() failed")
       OR auch so
win1Nr.l=OpenWindow(#PB_Any,50,50,#Win1Width,#Win1Height,#PB_Window_SystemMenu,"window")
check( win1Nr, "openwindow() failed")
       OR auch so
shape1 = LoadSprite(#PB_Any, "shape1.bmp")
check(shape1, "'shape1.bmp' not loaded")

wenn man kein #PB_Any benutzt und den rückgabewert nicht speichern muss gehts soger in einer zeile.
[is nix dolles/ ich hoffe ich werde für mein erstes posting im forum nich gleich ausgelacht :]

man könnte die procedure ja auch den rückgabewert weiterreichen lassen
Code:
sprite = check( LoadSprite(#PB_Any,"sprite.bmp"), "LADEFEHLERBLA!")
....
<edit 27.05 18:58>
momentan benutze ich die funktion so:
Code:
Procedure.l check(value.l, text.s)
   If value=0 And MessageRequester("error", text + Chr(10) + "exit program?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
         End
   Else
      ProcedureReturn value
   EndIf
EndProcedure

Autor:  #NULL [ 01.08.2006 07:53 ]
Betreff des Beitrags: 

eine erdnuß zum messen von zeitverbrauch:
Code:
Procedure t(s.s)
  Static t.l
  Static switch.l
  If switch=0
    t=ElapsedMilliseconds()
  Else
    Debug s+": "+Str(ElapsedMilliseconds()-t)
  EndIf
  switch!1
EndProcedure



um z.b. den zeitverbrauch einer proc zu messen
Code:
t("")
drawMap()
t("dm")


...aber schachteln geht natürlich in der form nicht.

Autor:  Olaf [ 01.08.2006 10:00 ]
Betreff des Beitrags: 

Zeitmessen mal Prozedurabhängig:
Code:
Global Dim ProcedureTime(1)
Global ID=1

Procedure TimeProcedureNeeded(ProcedureIdentifier)
  If ProcedureIdentifier>ID
    ID=ProcedureIdentifier
    ReDim ProcedureTime(ID)
  EndIf
  If ProcedureTime(ProcedureIdentifier)=0
    ProcedureTime(ProcedureIdentifier)=ElapsedMilliseconds()
  Else
    TimeNeeded=ElapsedMilliseconds()-ProcedureTime(ProcedureIdentifier)
    ProcedureTime(ProcedureIdentifier)=0
  ProcedureReturn TimeNeeded
  EndIf
EndProcedure

Aufruf:
Code:
Procedure DoThis()
  For x=0 To 9
    Delay(100)
  Next x
EndProcedure

TimeProcedureNeeded(@DoThis())
DoThis()
Debug TimeProcedureNeeded(@DoThis())

Autor:  #NULL [ 01.08.2006 12:08 ]
Betreff des Beitrags: 

versteh ich da was falsch? oder warum erstelltst du ein array mit z.b. 4 mio elementen für einen einzigen aufruf?
mit einfachen zahlen wie 1,2,3.. als parameter geht's ja auch.
ausserdem, woher willst du wissen, ob bei einem zweiten geschachtelten aufruf eine andere proc-adresse höher ist?

Autor:  Kiffi [ 01.08.2006 12:45 ]
Betreff des Beitrags: 

Hier noch ein netter Tipp, der zeigt, wie sich verschiedenene Zugriffe auf ein
mehrdimensionales Array auf die Geschwindigkeit auswirken kann:

http://www.purebasic.fr/english/viewtopic.php?t=22909

Grüße ... Kiffi

Autor:  coMstructor [ 15.06.2007 19:08 ]
Betreff des Beitrags: 

So, da hab ich nun auch ein Paar kleine Tipps für euch:

Link

Autor:  ts-soft [ 15.06.2007 19:36 ]
Betreff des Beitrags: 

coMstructor hat geschrieben:
So, da hab ich nun auch ein Paar kleine Tipps für euch:

Link

:allright: , aber "Länge der Variablennamen" sollte doch geändert werden.
Die Empfehlung ist von 1990 und dank Autovervollständigung usw. hat das
Wohl nicht mehr seine Berechtigung. Für lokale Variablen in Proceduren kann
man es so halten, aber bei globalen Variablen halte ich längere Namen eher
für Empfehlenswert.

PS: Aber eigentlich fällt mir Deine etwas zu grosse Signatur auf, wäre nett
wenn Du das Bild etwas verkleinern würdest, danke

Autor:  NicTheQuick [ 31.03.2008 01:42 ]
Betreff des Beitrags: 

Wenn man ein statisches Array in einer Structure trotzdem mit "dynamischer"
Größe haben will, muss man sich mit 'AllocateMemory()' und einem
Dummy-Structure-Element behelfen, während man dem statischen Array
selbst die Größe Null gibt. Nur dann beschwert sich der Debugger nicht.
Würde man das statische Array von Anfang an z.B. auf 100000 Elemente
festlegen und irgendwann im Programmverlauf würden dynamisch doch mal
mehr als 100000 Element genutzt, würde sich der Debugger beschweren.
Mit folgender Methode passiert das nicht mehr.
Code:
Structure arr
  StructureUnion
    arr.l[0] ;statisches Array auf Größe Null festlegen
    dummy.l ;Dummy-Element, damit die Struktur eine Größe hat
  EndStructureUnion
EndStructure

;dynamisch Speicher allokieren
Define *a.arr
*a = AllocateMemory(SizeOf(arr) * 10)

;Füllen
For i = 0 To 9
  *a\arr[i] = i + 1
Next

;Lesen
For i = 0 To 9
  Debug *a\arr[i]
Next

Seite 1 von 3 Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/