Board index » delphi » How do I assign pointers?

How do I assign pointers?

I have been programming in Turbo/Borland Pascal for years and have always
tried to avoid the use of pointers as they seem to be poorly implemented in
Pascal in general.  In C they are a snap and quite natural.  

I recently found a need to use pointers in Pascal.  In a simplified way I
want to do basically the following operation (real world useage is a bit
more complicated but it boils down to this):

var
  a, b: integer;
  aptr, bptr: ^integer;

begin
  a := 1;
  b := 2;
  aptr := @a;
  bptr := @b;

  bptr := aptr;
  ...
end;

The line bptr := aptr fails to compile (type mismatch error).  Does this
mean I cannot reassign the value of a pointer???  If so, this makes
pointers in Pascal pretty useless!

Any ideas?
Herb Susmann

 

Re:How do I assign pointers?


Quote
Herb Susmann wrote:

> I have been programming in Turbo/Borland Pascal for years and have always
> tried to avoid the use of pointers as they seem to be poorly implemented in
> Pascal in general.  In C they are a snap and quite natural.

> I recently found a need to use pointers in Pascal.  In a simplified way I
> want to do basically the following operation (real world useage is a bit
> more complicated but it boils down to this):

> var
>   a, b: integer;
>   aptr, bptr: ^integer;

> begin
>   a := 1;
>   b := 2;
>   aptr := @a;
>   bptr := @b;

>   bptr := aptr;
>   ...
> end;

> The line bptr := aptr fails to compile (type mismatch error).  Does this
> mean I cannot reassign the value of a pointer???  If so, this makes
> pointers in Pascal pretty useless!

> Any ideas?
> Herb Susmann

Hi Herb,

First of all, the above code, cut and pasted into BP 7.0, compiles smoothly (provided
you change the last semicolon to a period).

From my experience, I figured out that your actual code must be somewhat different,
such as:

        var
          aptr: ^integer;
          bptr: ^integer;
        begin
          {...}
          bptr := aptr;
        end.

Notice that in this variation the two pointers are not declared in the same line.
This does cause the "type mismatch" error you mention.

The error is due to an internal compiler convention: if you do not use a named type
in a variable declaration, then the variable type is somehow bound to the source
instruction containing its declaration. So, if aptr and bptr are declared in the same
instruction they are considered to be of the same type, and if they are declared in
different instructions they are considered to be different types. Type declarations
are not resolved by equivalence rules.

I believe this is also the reason why you can only use named types (i.e. already
defined in a "type" declaration) for procedure parameters, and I suspect that this
convention greatly simplifies the internal implementation of the BP compiler, which
is well known for its speed.

Now to your code, you would not have any problems if you had declared an explicit
type for your pointers, such as:

        type
          int_ptr : ^integer;
        var
          aptr : int_ptr;  
          bptr : int_ptr;
        begin
          aptr:=bptr;  {or whatever}
        end.

Finally, though I do not wish to start a new Pascal vs. C argument (I write in C
quite often), allow me to comment your statement that:

Quote
> I have been programming in Turbo/Borland Pascal for years and have always
> tried to avoid the use of pointers as they seem to be poorly implemented in
> Pascal in general.  In C they are a snap and quite natural.

1. In C a pointer declaration and a pointer dereference use exactly the same syntax,
which does not seem very natural to me.

2. In C arrays and pointers are used interchangably, which is also not natural.
Pointer arithmetic (such as *a++=1) can lead to misunderstandings (read: bugs),
especially if you mix by accident different pointer types. Of course, traversing an
array by incrementing a pointer can be very efficient, but a good programmer has no
problem to implement it in pascal while respecting the difference between a pointer
and an array.

3. In Pascal you might be using pointers all the time without even knowing it. Just
think of VAR parameters and procedure variables - not to mention strings: C strings
are unnecessarily loaded with pointers, while Pascal strings are just plain text
variables, as they should be. *These* are natural and very elegant ways indeed.

The fact is that in C you have to use pointers for even the most trivial tasks. Maybe
this is why you think pointers in C are natural; they are not natural, they are only
everywhere, so they become familiar to you. In Pascal you are spared of this
experience until you really need pointers for advanced structures (e.g. linked lists,
trees, etc).

Please do not confuse your unequal knowledge of Pascal and C for "poorly implemented
pointers in Pascal". Pascal pointers are very well thought out *abstract* data types,
and not just raw memory addresses.

Greetings,

Votis Kokavessis

Re:How do I assign pointers?


So is there a way to dynamically allocate an array in Pascal,
equivalent to doing this in C:

int i, j, *p, *q;
j = 10;
p = (int *) malloc(j * sizeof (int));
q = p;
for (i = 0; i < j; i++)
{ printf ("%d\n", *q);
  q++;

Quote
}

Everyone I asked says "that's a limitation of Pascal - you can't do
that.  Use a linked list or binary tree."  Problem is, you can't
easily do a binary search on a linked list, and binary trees don't
work well unless what you're trying to do allows you to balance the
tree well.

While I was busy reporting email solicitations on Fri, 07 Feb 1997
21:17:45 -0800, Votis <vo...@paratiritis.the.forthnet.gr> wrote:

Quote
>Herb Susmann wrote:

>> I have been programming in Turbo/Borland Pascal for years and have always
>> tried to avoid the use of pointers as they seem to be poorly implemented in
>> Pascal in general.  In C they are a snap and quite natural.

>> I recently found a need to use pointers in Pascal.  In a simplified way I
>> want to do basically the following operation (real world useage is a bit
>> more complicated but it boils down to this):

>> var
>>   a, b: integer;
>>   aptr, bptr: ^integer;

>> begin
>>   a := 1;
>>   b := 2;
>>   aptr := @a;
>>   bptr := @b;

>>   bptr := aptr;
>>   ...
>> end;

>> The line bptr := aptr fails to compile (type mismatch error).  Does this
>> mean I cannot reassign the value of a pointer???  If so, this makes
>> pointers in Pascal pretty useless!

>> Any ideas?
>> Herb Susmann

>Hi Herb,

>First of all, the above code, cut and pasted into BP 7.0, compiles smoothly (provided
>you change the last semicolon to a period).

>From my experience, I figured out that your actual code must be somewhat different,
>such as:

>    var
>      aptr: ^integer;
>      bptr: ^integer;
>    begin
>      {...}
>      bptr := aptr;
>    end.

>Notice that in this variation the two pointers are not declared in the same line.
>This does cause the "type mismatch" error you mention.

>The error is due to an internal compiler convention: if you do not use a named type
>in a variable declaration, then the variable type is somehow bound to the source
>instruction containing its declaration. So, if aptr and bptr are declared in the same
>instruction they are considered to be of the same type, and if they are declared in
>different instructions they are considered to be different types. Type declarations
>are not resolved by equivalence rules.

>I believe this is also the reason why you can only use named types (i.e. already
>defined in a "type" declaration) for procedure parameters, and I suspect that this
>convention greatly simplifies the internal implementation of the BP compiler, which
>is well known for its speed.

>Now to your code, you would not have any problems if you had declared an explicit
>type for your pointers, such as:

>    type
>      int_ptr : ^integer;
>    var
>      aptr : int_ptr;  
>      bptr : int_ptr;
>    begin
>      aptr:=bptr;  {or whatever}
>    end.

>Finally, though I do not wish to start a new Pascal vs. C argument (I write in C
>quite often), allow me to comment your statement that:

>> I have been programming in Turbo/Borland Pascal for years and have always
>> tried to avoid the use of pointers as they seem to be poorly implemented in
>> Pascal in general.  In C they are a snap and quite natural.

>1. In C a pointer declaration and a pointer dereference use exactly the same syntax,
>which does not seem very natural to me.

>2. In C arrays and pointers are used interchangably, which is also not natural.
>Pointer arithmetic (such as *a++=1) can lead to misunderstandings (read: bugs),
>especially if you mix by accident different pointer types. Of course, traversing an
>array by incrementing a pointer can be very efficient, but a good programmer has no
>problem to implement it in pascal while respecting the difference between a pointer
>and an array.

>3. In Pascal you might be using pointers all the time without even knowing it. Just
>think of VAR parameters and procedure variables - not to mention strings: C strings
>are unnecessarily loaded with pointers, while Pascal strings are just plain text
>variables, as they should be. *These* are natural and very elegant ways indeed.

>The fact is that in C you have to use pointers for even the most trivial tasks. Maybe
>this is why you think pointers in C are natural; they are not natural, they are only
>everywhere, so they become familiar to you. In Pascal you are spared of this
>experience until you really need pointers for advanced structures (e.g. linked lists,
>trees, etc).

>Please do not confuse your unequal knowledge of Pascal and C for "poorly implemented
>pointers in Pascal". Pascal pointers are very well thought out *abstract* data types,
>and not just raw memory addresses.

>Greetings,

>Votis Kokavessis

Don Stauffer
+--------------------------------------------+
|  Email welcome except solicitation, which  |
| will be forwarded to domain Administrators |
+--------------------------------------------+

Re:How do I assign pointers?


Quote
Don Stauffer wrote:
> Everyone I asked says "that's a limitation of Pascal - you can't do
> that.  Use a linked list or binary tree."

Alright. I want to know who said that! Give me names...

AME

Re:How do I assign pointers?


Quote
Don Stauffer wrote:

> So is there a way to dynamically allocate an array in Pascal,
> equivalent to doing this in C:

> int i, j, *p, *q;
> j = 10;
> p = (int *) malloc(j * sizeof (int));
> q = p;
> for (i = 0; i < j; i++)
> { printf ("%d\n", *q);
>   q++;
> }

Hi Don,

This is a very simple exercise:

type
  int_ptr = ^integer;
  pt = record           { structure used to increment pointers }
         ofs : word;
         seg : word;  
       end;

const
  array_size = 10;

var
  counter : word;
  p, q    : int_ptr;

begin
  getmem( p, array_size*sizeof(integer) );  { no type-casting required! }
  q:=p;
  for counter:=1 to array_size do
  begin
    writeln(q^);                        { warning: array not initialized }
    inc( pt(q).ofs, sizeof(integer) );  { increment pointer }
  end;
  freemem( p, array_size*sizeof(integer) );  { don't forget to clean up }
end.

Quite easy, as you see.

Quote
> Everyone I asked says "that's a limitation of Pascal - you can't do
> that.  Use a linked list or binary tree."  Problem is, you can't
> easily do a binary search on a linked list, and binary trees don't
> work well unless what you're trying to do allows you to balance the
> tree well.

To sort or binary search an array, you do not need to increment pointers.
As I said, this is a method to speed ud sequencially traversing an array.
If you need array indexing, you can use getmem with a pointer to a large
array type such as:

type
  int_array   = array[1..32000] of integer;
  p_int_array = ^int_array;

var
  p : p_int_array;
  j : integer;

begin
  getmem( p, array_size*sizeof(integer) );
  for j:=1 to array_size do something( p^[j] );
  {...}

This technique has been often described in this newsgroup.

The only advantage of C is the possibility of huge arrays (larger than
64K), which you have to code yourself in Pascal through an array of
pointers to array rows (or array segments, if it is one-dimensional). The
"TCollection" structures of TV/OWL can compensate for this.

Happy coding

Votis Kokavessis

Re:How do I assign pointers?


Quote
Don Stauffer wrote:
> So is there a way to dynamically allocate an array in Pascal,
> equivalent to doing this in C:

> int i, j, *p, *q;
> j = 10;
> p = (int *) malloc(j * sizeof (int));
> q = p;
> for (i = 0; i < j; i++)
> { printf ("%d\n", *q);
>   q++;
> }

Mumble mumble mumble... keksekseu charabia? (Pardon my French)

type integerPtr=^integer;
var i,j: integer;
    p,q: integerPtr;
begin j:=10;
      getMem(p,j*SizeOf(integer));
      q:=p;
      for i:=0 to j-1 to
      begin writeln(q^);
            inc(q,SizeOf(integer))
      end;
end.

Et hop! C'est-y pas plus clair comme ca? (Pardon my French again, I
meant to say that *that* was somewhat less obscure than all that
++ stuff)

Note: for earlier version of TP, like TP5, inc(q,SizeOf(integer))
will make the compiler complain that you can't increment a pointer.
The way around it is: typecast it to a longint:

   inc(longint(q),SizeOf(integer))

Re:How do I assign pointers?


Re:How do I assign pointers?


Quote
Votis wrote:
> Of course, traversing an
> array by incrementing a pointer can be very efficient

And once upon a time I went to the trouble of doing that, hoping
to make my program faster. When I timed both versions... lo and
behold, no difference! Yes, the compiler had optimized my
"for i:=1 to n do a[i]...."

Re:How do I assign pointers?


Re:How do I assign pointers?


In article <33035878.4...@trl.telstra.com.au>,
Jacques B.M. Guy <j....@trl.telstra.com.au> wrote:

Quote
>Don Stauffer wrote:

>> So is there a way to dynamically allocate an array in Pascal,
>> equivalent to doing this in C:

>> int i, j, *p, *q;
>> j = 10;
>> p = (int *) malloc(j * sizeof (int));
>> q = p;
>> for (i = 0; i < j; i++)
>> { printf ("%d\n", *q);
>>   q++;
>> }

>Mumble mumble mumble... keksekseu charabia? (Pardon my French)

>type integerPtr=^integer;
>var i,j: integer;
>    p,q: integerPtr;
>begin j:=10;
>      getMem(p,j*SizeOf(integer));
>      q:=p;
>      for i:=0 to j-1 to
>      begin writeln(q^);
>            inc(q,SizeOf(integer))

What on earth are you attempting here? Why is the sizeof(integer) there?

Inc(q) is just enough. That increments it to the next element,

Quote
>      end;
>end.

Osmo

Other Threads