pointers headache

Just starting out? Need help? Post your questions and find answers here.
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

pointers headache

Post by ludoke »

I keep struggling with pointers.
I understand in the meantime that pointers are important.
It is also best to avoid global variables and that it is better to use structures.
The examples in the manual are not clear to me.
Is it always better and faster to change variables via pointers ?
But how to do this?
;structure test

Code: Select all

 EnableExplicit 
Structure test
  a.i
  b.i
  d.s
EndStructure
Define one.test  ;
Define two.test
Define *pointer1,*pointer2

*pointer1=@one  ;adres one
*pointer2=@two ;adres two

one\a=10
one\b=20
one\d="test"

two\a=20
two\d="other"

Debug one\d  ;"test"
Debug two\a   ;20
Debug two\d   ;"other"

 *pointer1\a=100    ;change one\a to 100  or change one\b  how do i this ?
 how to read one\a via a pointer ?

Procedure change_something(*pointer1)
  how can I change a,b,c,d with pointers
EndProcedure

Debug one\a
User avatar
STARGÅTE
Addict
Addict
Posts: 2085
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: pointers headache

Post by STARGÅTE »

In your example, the pointer *pointer1 and *pointer2 are "just" links to the original variable one and two.

What you do on *pointer1 or *pointer2, read or write, is performed with one and two.

Code: Select all

 EnableExplicit
Structure test
  a.i
  b.i
  d.s
EndStructure
Define one.test  ;
Define two.test
Define *pointer1.test,*pointer2.test ; Put the structure name as well.

*pointer1=@one  ;adres one
*pointer2=@two ;adres two

one\a=10
one\b=20
one\d="test"

two\a=20
two\d="other"

Debug one\d  ;"test"
Debug two\a   ;20
Debug two\d   ;"other"

*pointer1\a=100    ;change one\a to 100  or change one\b  how do i this ?
Debug *pointer1\d

Procedure change_something(*pointer.test)
  *pointer\a = 123456
EndProcedure

change_something(two)

Debug two\a
Using the pointer to a variable is not faster than using the variable itself, but also not slower.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

Re: pointers headache

Post by ludoke »

is the use of pointers necessary?
Can I make large programs without pointers?
What about threads ?
What is the best way to make mechanical 3D drawings programs.
There are so many ways in pb to draw something on the screen.
Is OpenGL better than PB graphics functions?
Must I use OpenWindowedScreen,cavasgadget or something else?
So many questions.
User avatar
NicTheQuick
Addict
Addict
Posts: 1226
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: pointers headache

Post by NicTheQuick »

Of course you can write large programs without using a single pointer. In some cases it is just easier to be able to work with references or to be able to allocate memory dynamically and use pointers to work with it. But you do not need it.

And regarding the question about your mechanical 3d drawing program: It's also doable without pointers. But that is also a whole other story. Working with 3D is a big step. Pointers are easy in comparison. What kind of programming skills do you have?
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

A thread procedure can only have one parameter, an integer.

So the only way is to use a pointer to a structure with all needed parameters inside.
Since a pointer has the length of an integer you can use this pointer as the parameter.

Code: Select all

Procedure Thread(*Parameter.ThreadParameterStructure)
In my thread structure are always such things like:

Code: Select all

Structure ThreadParameterStructure
  Thread.i
  Semaphore.i
  Exit.i
  ...
EndStructure
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

Re: pointers headache

Post by ludoke »

@NicTheQuick
if pointers aren't really necessary, I'll avoid them.
It is for hobby my programming experience is not that high.

Now what's the best feature to draw on the screen?
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

If you look at 'decode a string'
and you meassure how long a variant with stringfield will need compared to my pointer solution,
then you will know why you need pointers, or you can drink several cups of coffee until your program is finished :wink:
I'm sure it is more then 10 times faster.
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: pointers headache

Post by mk-soft »

Now what's the best feature to draw on the screen?
For 2D Drawing use CanvasGadget and VectorDrawing.
For Games show 3D Examples and Screen3dRequester.pb
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

Only as example:

Code: Select all

EnableExplicit

Procedure.i ParseGCode(*Line, List GCodeList.s())
 
  Protected *Char.Character, Char.i, Ready.i
 
  *Char = *Line
  While *Char\c
    Char = *Char\c     
    If (Char >= 'a' And Char <='z') Or (Char >= 'A' And Char <= 'Z')
      AddElement(GCodeList())
      Ready = #True
    EndIf
   
    If Ready And Char > ' '
      GCodeList() + Chr(Char)
    EndIf
   
    *Char + 2
  Wend
 
  ProcedureReturn ListSize(GCodeList())
 
EndProcedure


Procedure.i ParseGCodeWithStringField(Line$, List GCodeList.s())
  
  Protected CountFields.i, Counter.i
  
  
  CountFields = CountString(Line$, " ")
  For Counter = 1 To CountFields + 1
    AddElement(GCodeList())
    GCodeList() = StringField(Line$, Counter, " ")
  Next
  
  ProcedureReturn ListSize(GCodeList())
  
EndProcedure



Define myString.s, StartTime.q, EndTime.q, i.i, StringFieldTime.q, PointerTime.q
NewList GCodeList.s()



myString = "N100 G01 X1.25 Y1.4 Z2.0 F200 "
For i = 1 To 12
  myString + myString
Next i
myString = RTrim(myString) ; else the Stringfieldversion is wrong
;Debug "Stringsize: " + Len(myString) + " characters"

DisableDebugger
StartTime = ElapsedMilliseconds()
ParseGCodeWithStringField(myString, GCodeList.s())
StringFieldTime = ElapsedMilliseconds() - StartTime
EnableDebugger
Debug "StringField() version: " + Str(StringFieldTime) + #LF$ + "List size: " + Str(ListSize(GCodeList()))
;Debug GCodeList()

ClearList(GCodeList())

DisableDebugger
StartTime = ElapsedMilliseconds()
ParseGCode(@myString, GCodeList())
PointerTime = ElapsedMilliseconds() - StartTime
EnableDebugger
Debug "Pointer version: " + Str(PointerTime) + #LF$ + "List size: " + Str(ListSize(GCodeList()))
;Debug GCodeList()

Debug StrF(StringFieldTime / PointerTime)
10 times was a bit to low :mrgreen:

The benefit gets bigger if the string gets longer

But don't set the loop end value higher then 14.
It will take very long. (Factor 185 on my PC)
Last edited by infratec on Tue Nov 24, 2020 9:41 pm, edited 5 times in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: pointers headache

Post by mk-soft »

For 99% of the programming *pointers are not absolutely necessary.

But for optimised programming *Pointer are the best way.

Pointers are addresses to memory areas. These can be *pointers to single values, or to structured data, or to program code.
The handling of *Pointer must be checked very carefully, because the compiler does not check them itself.

Small example with Parameters ByRef

Code: Select all


Procedure MyFunction(Value1, Value2, *Result.Integer)
  Protected r1
  
  *Result\i = Value1 + Value2
  
  If *Result\i > 0
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
  
EndProcedure

Procedure MyFunctionStr(Value1.s, Value2.s, *Result.String)
  Protected r1
  
  *Result\s = Value1 + Value2
  
  r1 = Len(*Result\s)
  ProcedureReturn r1
  
EndProcedure

Define Value.i

a = MyFunction(100, 200, @Value)

Debug Value

; Special with Strings, Because we need always a variable where stored the pointer to string

Define sVal.String ; This define a Value where stored the Pointer to the String

a = MyFunctionStr("Hello ", "World!", @sVal)

Debug sVal\s
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
ludoke
Enthusiast
Enthusiast
Posts: 153
Joined: Fri Jul 08, 2016 5:35 pm
Location: Essen (Belgium)

Re: pointers headache

Post by ludoke »

Now I'm going crazy, so pointers are needed for speed.
Where can I learn from simple examples ,step by step.

MK-soft
I miss a few steps,
*Result.Integer ;is this a pointer to variable "integer" or is Result an integer type
*Result\i ;it seems something from a structure ??
pointers it seems easy especially for experienced programmers ,I've already looked at so many examples ,but it remains Chinese.Maybe one day I'll understand.
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

ludoke wrote: *Result.Integer ;is this a pointer to variable "integer" or is Result an integer type
*Result\i ;it seems something from a structure ??
Integer is a predefined structure like

Code: Select all

Structure Integer
  i.i
EndStructure
*Result.Integer is a pointer which points to a structure which contains only one integer.
And since there is only one member, you can point directly to one integer variable with it.
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

Code: Select all

Define i.i, *Integer.Integer

i = 10
Debug i

ShowMemoryViewer(@i, SizeOf(Integer))

*Integer = @i
Debug *Integer\i
Debug "Address of the variable i: " + Str(*Integer)
User avatar
skywalk
Addict
Addict
Posts: 3996
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: pointers headache

Post by skywalk »

ludoke wrote:Now I'm going crazy, so pointers are needed for speed.
Where can I learn from simple examples ,step by step.
Pointers are faster in cases where you avoid making copies of lots of memory.
But I am unsure of the benefits dereferencing large structured memory in a loop vs a tight array?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
infratec
Always Here
Always Here
Posts: 6869
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: pointers headache

Post by infratec »

Pointers are not the solution of all problems.

But they can make things easier and faster.
But not all things.

If you want/need multiple return values for a procedure, you need them.
A lot of examples are in the windows API procedures.
Or if you need to return a point with x/y coordinates.

Ok, you can also define all variables as Global, but in a large program you will run very fast into big problems,
which are not easy to locate. Or you need many many variables which always start with the procedure name in front,
to avoid wrong accesses.

You can also define an array of a structure with 1 element and use this as parameter,
but I think that's more complicated then simply use the address of the structure.
Post Reply