Pointers and references: Difference between revisions

fortran (+ lang tag here and there)
(Added basic pointer/reference examples for D language)
(fortran (+ lang tag here and there))
Line 316:
;
 
=={{header|Fortran}}==
Since Fortran90, the <tt>pointer</tt> attribute can be given:
 
<lang fortran>real, pointer :: pointertoreal</lang>
 
A so-declared pointer is in an undetermined state: a pointer should be nullified:
 
<lang fortran>nullify(pointertoreal)</lang>
 
But Fortran 95 allows to initialize pointers to NULL (unassociated):
 
<lang fortran>real, pointer :: apointer => NULL()</lang>
 
A pointer can be associated:
 
<lang fortran>real, target :: areal
pointertoreal => areal</lang>
 
The target attribute is needed to say that the ''object'' (the "real" datum) can be referenced through a pointer (it seems it works more like an alias rather than a "true" pointer). The existance of an ''association'' can be tested with <tt>associated</tt> (Fortran 95):
 
<lang fortran>if ( associated(pointertoreal) ) !...</lang>
 
and the association can be nullified as before with <tt>nullify</tt>.
 
The data a "pointer" points to can be allocated as if the <tt>allocatable</tt> attribute were specified.
 
<lang fortran>integer, dimension(:), pointer :: array
allocate(array(100))</lang>
 
That allocate an array of 100 integers; nullifying at this point would give memory leakage; the memory pointed to the array should be deallocated using the <tt>deallocate(array)</tt> code.
 
The function <tt>associated</tt> (Fortran 95) accepts also the optional argument <tt>target</tt>, to check if the pointer is associated to a particular target (working ''de facto'' like an alias)
 
<lang fortran>integer, target :: i
integer, pointer :: pi
!... ...
if ( associated(pi, target=i) ) !...</lang>
 
Associating pointer to an array could help accessing the data of the array in a different manner.
 
<lang fortran>real, dimension(20), target :: a
real, dimension(20,20), target :: b
real, dimension(:), pointer :: p
 
p => a(5:20)
! p(1) == a(5), p(2) == a(6) ...
p => b(10,1:20)
! p(1) == b(10,1), p(2) == b(10,2) ...</lang>
 
Which is different of course from having e.g.
 
<lang fortran>real, dimension(20) :: a
real, dimension(16) :: p
 
p = a(5:20)</lang>
 
In order to create arrays of pointers, the only way is to define a new type:
 
<lang fortran>type intpointer
integer, pointer :: p
end type intpointer
 
!...
type(intpointer), dimension(100) :: parray</lang>
 
It declares an array of 100 <tt>intpointer</tt>, i.e. pointers to integer; the <tt>integer, dimension(:), pointer :: pt</tt> says just that pt is a pointer to an array of X integers.
 
Once a pointer is associated, it can be used as a normal variable/type.
 
There are not other possible operations on Fortran "pointers" (at least before Fortran 2003).
 
=={{header|Haskell}}==
Line 324 ⟶ 393:
However, Haskell supports imperative update of variables. To ensure that these side-effects are ordered, that has to happen inside a monad. So the predefined state monad ''ST'' makes it possible to allocate a ''reference'' (a simple mutable data structure with one field; not the same meaning as the "references" in other languages) with an initial value, read from it, and write to it:
 
<lang haskell>
<pre>
import Data.STRef
 
Line 332 ⟶ 401:
k <- readSTRef p
writeSTRef p (k+1)
</prelang>
 
These are all the operations allowed on references. The type system guarantees that a reference can never leave the monad. The IO monad has similar operations ''newIORef'', ''readIORef'', ''writeIORef''. One can also embed the ST monad in the IO monad with 'stToIO'.
Line 341 ⟶ 410:
If the object that a reference is pointing to is mutable (i.e. it has public fields or it has methods that allows changing of its fields), then it is possible to modify that object's state through the reference; and someone else who has a reference to the same object will see that modification. (Note: this does not change the reference itself, just the object that it points to.) Let us consider a simple class of mutable object:
 
<lang java> public class Foo { public int x = 0; }
 
void somefunction() {
Line 349 ⟶ 418:
a.x = 5; // this modifies the "x" field of the object pointed to by "a"
System.out.println(b.x); // this prints 5, because "b" points to the same object as "a"
}</lang>
 
Java is call-by-value. When passing arguments, you are either passing primitives by value or references by value. There is no such thing as "passing an object" as objects are not values in the language. As noted above, if the object that the reference is pointing to is mutable, then it is possible to modify that object's state through the reference. Then if the calling function has a reference to the same object, they will see that modification through the reference. So if you want to reflect changes in an argument back to the caller, one thing that you can do is wrap the argument as a field in an object, then modify the object through the reference.
Line 359 ⟶ 428:
If you just want a simple mutable "variable" (since variables in OCaml are immutable), you can allocate a ''reference'' (a simple mutable data structure with one field; not the same meaning as the "references" in other languages) with an initial value, read from it, and write to it:
 
<lang ocaml>
<pre>
let p = ref 1;; (* create a new "reference" data structure with initial value 1 *)
let k = !p;; (* "dereference" the reference, returning the value inside *)
p := k + 1;; (* set the value inside to a new value *)
</prelang>
 
(The OCaml web-site provides this [http://caml.inria.fr/resources/doc/guides/pointers.en.html page] on the subject.)
Line 372 ⟶ 441:
Perl does not have pointers, but references. You may think of them as pointers with the insane stuff removed. Any scalar, array element or hash value can contain a reference to a data structure.
 
<lang perl> # start with some var definitions
my $scalar = 'a string';
my @array = ('an', 'array');
Line 380 ⟶ 449:
my $scalarref = \$scalar;
my $arrayref = \@array;
my $hashref = \%hash;</lang>
 
Using a reference
 
<lang perl> # printing the value
print ${$scalar};
print $arrayref->[1]; # this would print "array"
Line 392 ⟶ 461:
${$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</lang>
 
You may also create anonymous references.
 
<lang perl> my $scalarref = \'a scalar';
my $arrayref = ['an', 'array'];
my $hashref = { firstkey => 'a', secondkey => 'hash' }</lang>
 
=={{header|Pop11}}==
Line 442 ⟶ 511:
Python does not have pointers and all Python names (variables) are implicitly references to objects. Python is a late-binding dynamic language in which "variables" are untyped bindings to objects. (Thus Pythonistas prefer the term '''name''' instead of "variable" and the term '''bind''' in lieu of "assign").
 
<lang python> # Bind a literal string object to a name:
a = "foo"
# Bind an empty list to another name:
Line 473 ⟶ 542:
# Call (anymous function object) from inside a list
b[0]("foo") # Note that the function object we original bound to the name "a" continues to exist
# even if its name is unbound or rebound to some other object.</lang>
 
[Note: in some ways this task is meaningless for Python given the nature of its "variable" binding semantics].
Line 482 ⟶ 551:
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.
 
<lang tcl> 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</lang>
 
In practice it's safer and more convenient to use array keys, eg.
 
<lang tcl> set arr(var) 3
set pointer var
set arr($pointer); # returns 3
set arr($pointer) 42; # arr(var) now has value 42</lang>
 
=={{header|Toka}}==