Pointers and references: Difference between revisions
(add E examples) |
No edit summary |
||
Line 6: | Line 6: | ||
[[Category:Ada]] |
[[Category:Ada]] |
||
Ada does not have pointers, only access types. |
Ada does not have pointers, only access types. |
||
Create a pool specific access type for an integer |
Create a pool specific access type for an integer |
||
type Int_Access is access Integer; |
type Int_Access is access Integer; |
||
Line 86: | Line 86: | ||
Accessing another object of the array through the reference: |
Accessing another object of the array through the reference: |
||
v = (&ref)[3]; // read value of array[3]; however doing this is bad style |
v = (&ref)[3]; // read value of array[3]; however doing this is bad style |
||
==[[Delphi / Object Pascal]]== |
|||
[[Category:Delphi]] |
|||
Delphi ( Object Pascal / Turbo Pascal ) fully supports both typed and untyped pointers. Since Delphi all pointers have been 32 bit. Previously you could have both long ( 32 bit ) and short ( 16 bit ) pointers. |
|||
'''Examples of pointers''' |
|||
Simple ''untyped'' pointer variable: |
|||
Variable Declaration |
|||
pMyPointer : Pointer ; |
|||
Simple pointer to a ''pre-defined'' type: |
|||
Variable Declaration |
|||
pIntPointer : ^Integer ; |
|||
A pointer to a ''Record''. This is the equivilent to a ''Struct'' in C |
|||
Type Defintion |
|||
MyRecord = Record |
|||
FName : string[20]; |
|||
LName : string[20]; |
|||
end; |
|||
Variable Declaration |
|||
pMyRecord : ^MyRecord ; |
|||
- Dereferencing a Pointer - |
|||
Pointers are dereferenced using the carrot '^' symbol. Dereferencing will cause the compiler or RTL to reveal the data that the pointer points to: |
|||
IntVar := pIntPointer^ ; |
|||
Dereference with a type cast of an ''untyped'' pointer. It is not legal syntax to simply dereference an untyped pointer, since there is nothing to designate its type. It must therefor be "Type Cast" when the dereference takes place as below. |
|||
IntVar := integer(MyPointer^); |
|||
- Pushing a Pointer - |
|||
Many programmers are familiar with C's ability to increment pointers of any type by using the '''++''' or '''--''' operators. Delphi has a very limited implementation of this when using pointers to char. Delphi can use the Inc() & Dec() procedures to increment or decrement a pointer to char. This is the only special case. To increment all other pointers you must use a "Type Cast". The syntax for doing this is: |
|||
p := Inc(integer(p)+1); |
|||
This will increment the pointer by one byte. Since all pointers are actualy 32 bit numbers. Additionaly, if you have a typed pointer you can increment the pointer by the size of the type it points to: |
|||
pInt := Inc(integer(pInt)+sizeof(Integer)) ; |
|||
pMyRecord := inc(integer(pMyRecord)+SizeOf(MyRecord)); |
|||
==[[E]]== |
==[[E]]== |
Revision as of 23:06, 20 March 2007
You are encouraged to solve this task according to the task description, using any language you may know.
In this task, the goal is to desmonstrate common operations on pointers and references.
Ada
Ada does not have pointers, only access types.
Create a pool specific access type for an integer
type Int_Access is access Integer; Int_Acc : Int_Access := new Integer(5);
Create a general access type for an integer
type Int_Ptr is access all Integer; Ref : Int_Ptr; Var : aliased Integer := 3; Ref := Var'access;
Ada does not provide pointer arithmetic, but does allow evaluation of the address
Var : Integer; Var_Address : Address := Var'address;
Addresses support operations of comparison, addition, and subtraction Ada also supports conversion between address types and a pre-defined subtype of Integer named Integer_Address. This accomodates the conversion to a linear addressing of any hardware address scheme including address:offset used in the 8086 processor.
Ada allows the specification of a starting address for any object
-- Demonstrate the overlay of one object on another A : Integer; B : Integer; for B'address use A'address; -- A and B start at the same address
C++
With pointers:
The following code creates a pointer to an int variable
int var = 3; int* pointer = &var; // or alternatively: int* pointer2(&var);
Access the integer variable through the pointer:
int v = *pointer; // sets v to the value of var (i.e. 3) *pointer = 42; // sets var to 42
Change the pointer to refer to another object
int othervar; pointer = &othervar;
Change the pointer to not point to any object
pointer = 0; // or alternatively: pointer = NULL;
Get a pointer to the first element of an array:
int array[10]; pointer = array; // or alternatively: pointer = &array[0];
Move the pointer to another object in the array
pointer += 3; // pointer now points to array[3] pointer -= 2; // pointer now points to array[1]
Access another object in the same array through the pointer
v = pointer[3]; // accesses third-next object, i.e. array[4] v = pointer[-1]; // accesses previous object, i.e. array[0] // or alternatively v = *(pointer + 3); // array[4] v = *(pointer - 1); // array[0]
With references:
The following code create a reference to an int variable:
int var = 3; int& ref = var; // or alternatively: int& ref2(var);
Access the integer variable through the reference
int v = ref; // sets v to the value of var, that is, 3 ref = 42; // sets var to 42
References cannot be changed to refer to other objects, and cannot (legally) made to refer to no object.
Get a reference to the first element of an array:
int array[10]; int& ref3 = array[0];
Changing the reference to refer to another object of the array is not possible.
Accessing another object of the array through the reference:
v = (&ref)[3]; // read value of array[3]; however doing this is bad style
Delphi / Object Pascal
Delphi ( Object Pascal / Turbo Pascal ) fully supports both typed and untyped pointers. Since Delphi all pointers have been 32 bit. Previously you could have both long ( 32 bit ) and short ( 16 bit ) pointers.
Examples of pointers
Simple untyped pointer variable:
Variable Declaration
pMyPointer : Pointer ;
Simple pointer to a pre-defined type:
Variable Declaration
pIntPointer : ^Integer ;
A pointer to a Record. This is the equivilent to a Struct in C
Type Defintion
MyRecord = Record FName : string[20]; LName : string[20]; end;
Variable Declaration
pMyRecord : ^MyRecord ;
- Dereferencing a Pointer -
Pointers are dereferenced using the carrot '^' symbol. Dereferencing will cause the compiler or RTL to reveal the data that the pointer points to:
IntVar := pIntPointer^ ;
Dereference with a type cast of an untyped pointer. It is not legal syntax to simply dereference an untyped pointer, since there is nothing to designate its type. It must therefor be "Type Cast" when the dereference takes place as below.
IntVar := integer(MyPointer^);
- Pushing a Pointer -
Many programmers are familiar with C's ability to increment pointers of any type by using the ++ or -- operators. Delphi has a very limited implementation of this when using pointers to char. Delphi can use the Inc() & Dec() procedures to increment or decrement a pointer to char. This is the only special case. To increment all other pointers you must use a "Type Cast". The syntax for doing this is:
p := Inc(integer(p)+1);
This will increment the pointer by one byte. Since all pointers are actualy 32 bit numbers. Additionaly, if you have a typed pointer you can increment the pointer by the size of the type it points to:
pInt := Inc(integer(pInt)+sizeof(Integer)) ;
pMyRecord := inc(integer(pMyRecord)+SizeOf(MyRecord));
E
E is a memory-safe object-graph language, and as such uses only object references; there are no non-reference values. Mutable storage always consists of an object; in particular, an assignable variable has, if necessary, an underlying "slot" object which can be retrieved.
var x := 0 def slot := &x # define "slot" to be x's slot x := 1 # direct assignment; value is now 1 slot.put(2) # via slot object; value is now 2
There are also mutable data structures:
def flexList := [].diverge() flexList.push(1) flexList.push(2) flexList.snapshot() # returns [1, 2]
User-defined objects can have state by containing it:
var open := true def door { to open() { open := true } to close() { open := false } to walkThrough() { require(open) } }
Perl
Interpeter: Perl v5.x
References are essentially how Perl handles pointers. Any scalar value, element in an array, key of a hash, or value of a hash may contain a reference to any other variable structurer.
# start with some var definitions my $scalar = 'a string'; my @array = ('an', 'array'); my %hash = ( firstkey => 'a', secondkey => 'hash' );
# make pointers my $scalarref = \$scalar; my $arrayref = \@array; my $hashref = \%hash;
Using a reference
# printing the value print ${$scalar}; print $arrayref->[1]; # this would print "array" print $hashref->{'secondkey'}; # this would print "hash"
# changing the value ${$scalar} = 'a new string'; # would change $scalar as well $arrayref->[0] = 'an altered'; # would change the first value of @array as well $hashref->{'firstkey'} = 'a good'; # would change the value of the firstkey name value pair in %hash
You may also create pointers or references without pointing to a previous variable.
my $scalarref; ${$scalarref} = 'a scalar'; my $arrayref = ['an', 'array']; my $hashref = { firstkey => 'a', secondkey => 'hash' }
Tcl
Tcl does not have pointers, however if required a similar level of indirection can be had by storing a variable name in another variable, eg.
set var 3 set pointer var; # assign name "var" not value 3 set pointer; # returns "var" set $pointer; # returns 3 set $pointer 42; # variable var now has value 42
In practice it's safer and more convenient to use array keys, eg.
set arr(var) 3 set pointer var set arr($pointer); # returns 3 set arr($pointer) 42; # arr(var) now has value 42