Quote:
> Hello.. I'm trying to generate and use dynamic arrays
>in a Turbo Pascal 7 program. I've got the concepts figured
>out, but seeing as Pascal doesn't allow pointer arithmetic, it
>makes things quite a bit more difficult. However, I wrote a
[deription of problem dropped ...red]
Quote:
>Thanks in advance for any help or suggestions.
[pascal code dropped ...red]
Quote:
>-chris gerber
Chris, when working with an untyped two dimensional array, you have
to multiply the first subscript by the number of elements in the
second dimension.
Your calculation:
p := addptr(basep,(i * j) * 2); { point at element in array }
Should be:
p := addptr(basep, ((i * 11{max "I" items} + j) * 2{Size of 1 item};
You also asked for suggestions, so here are a few:
Your AddPtr function is more complex than it needs to be. It could
be simplified as:
Function AddPtr(BaseVal: Pointer; StepVal: integer): Pointer;
Assembler;
asm
les AX, [BaseVal]
add AX, [StepVal]
mov DX, ES
End;
It takes 5 bytes to call a FAR procedure and 5-bytes for this to be
coded as an inline routine, so a library function could be defined
as inline without increasing the size of the program:
Function AddPtr(BaseVal: Pointer; StepVal: integer): Pointer;
INLINE ($59 { pop CX }
/$58 { pop AX }
/$5A { pop DX }
/$03 /$C1 { add AX,CX }
);
You can also do some simple pointer arithmetic by using a little
type casting
p := Ptr(Seg(BaseP^), Ofs(BaseP^) + (i*11 +j) * Sizeof(Integer));
Since you have version 7.0, you can enable extended syntax and let the
compiler do the pointer arithmetic for you. Add {$X+} at the beginning
of the program, define a TYPE tpInteger = ^Integer then use one of the
following;
p := tpInteger(pChar(BaseP) + (i*11+j)*2);
If you define baseP as a pChar then you can drop the pChar type cast.
p := tpInteger(BaseP + (i*11+j)*2);
If you know for certain that the array will be an array of integers
you can define BaseP as a ^Integer then you can drop both type casts.
Note that we no longer have to multiply by 2 or Sizeof(Integer). That
information is now contained in BaseP and properly handled by the 7.0
compiler:
p := BaseP + (i * 11 + j);
Extended syntax also allows use to Inc and Dec pointers.
For example:
p := tpInteger(BaseP); { Or define BaseP and ^Integer }
Inc(p, i * 11 + j); { compiler adjustes for Sizeof(p^) }
{ hence *2 or Sizeof(Integer) dropped }
This lesson on pointer arithmetic is brought to you by the variables i
and j and the pointer p. <g>
Joking aside, I hope this strengthens your understanding and ability
to manipulate pointers. You've got a fair start and the courage to
experiment so I'm sure you'll have it mastered in no time.
...red