Pointers and references: Difference between revisions

From Rosetta Code
Content added Content deleted
m (Added syntax highlighting to C and C++, C++ and Delphi examples.)
(Better explanation of the dynamic arrays in D entry)
Line 247: Line 247:
=={{header|D}}==
=={{header|D}}==


<lang d>void main() {
Grabbing variable address and placing it in a pointer
// Take the address of 'var' and placing it in a pointer:
<lang d>
int var;
int var;
int* ptr = &var;
int* ptr = &var;
</lang>


// Take the pointer to the first item of an array:
Depending on variable type, D will automatically pass either by value or reference
int[10] data;
by value: structs, statically sized arrays, and other primitives (int, char, etc...)
auto p2 = data.ptr;
by reference: classes, dynamically sized arrays, array slices
<lang d>
struct S{}
class C{}



void foo(S s){} // pass by value
// Depending on variable type, D will automatically pass either
void foo(C c){} // pass by reference
void foo(int i){} // pass by value
// by value or reference.
// By value: structs, statically sized arrays, and other
void foo(int[4] i){} // pass by value
// primitives (int, char, etc...);
void foo(int[] i){} // pass by reference
void foo(ref T t){} // pass by reference regardless of what type T really is
// By reference: classes;
// By kind of reference: dynamically sized arrays, array slices.
</lang>

struct S {}
class C {}

void foo1(S s) {} // By value.
void foo2(C c) {} // By reference.
void foo3(int i) {} // By value.
void foo4(int[4] i) {} // By value (unlike C).
void foo6(int[] i) {} // Just length-pointer struct by value.
void foo5(T)(ref T t) {} // By reference regardless of what type
// T really is.
}</lang>


=={{header|Delphi}}==
=={{header|Delphi}}==

Revision as of 10:02, 22 September 2013

Task
Pointers and references
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Integer Operations
Arithmetic | Comparison

Boolean Operations
Bitwise | Logical

String Operations
Concatenation | Interpolation | Comparison | Matching

Memory Operations
Pointers & references | Addresses

In this task, the goal is to demonstrate common operations on pointers and references.

Ada

Pointers

In Ada pointer types are called access types. Access types are subject of so-called accessibility checks, which in Ada are intended to prevent appearance of dangling pointers. (Though accessibility checks can be circumvented)

Create a pool specific access type for an integer <lang ada>type Int_Access is access Integer; Int_Acc : Int_Access := new Integer'(5);</lang> A pool specific access type can be constrained to never be null. For such pointers the compiler can omit checks of being null upon dereferencing. <lang ada>type Safe_Int_Access is not null access Integer;</lang> General access types can deal with objects allocated in any pool as well as ones on the stack. For example, create a pointer to a stack-allocated integer <lang ada>declare

  type Int_Ptr is access all Integer;
  Ref : Int_Ptr;
  Var : aliased Integer := 3;
  Val : Integer := Var;

begin

  Ref := Var'Access; -- "Ref := Val'Access;" would be a syntax error</lang>

The attribute 'Access (and also 'Unchecked_Access) is used to get a pointer to the object. Note that the object has to be declared aliased when it has to be referenced by a pointer, which is why one cannot write Val'Access. General access types can also be constrained to exclude null: <lang ada>type Safe_Int_Ptr is not null access all Integer;</lang>

Addresses

Ada does not provide pointer arithmetic, but does allow evaluation of the address <lang ada>Var : Integer; Var_Address : Address := Var'Address;</lang> Addresses support operations of comparison, addition, and subtraction. Ada also supports conversion between address types and a predefined subtype of Integer named Integer_Address. This accommodates 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 <lang ada>-- 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</lang>

References

References in Ada are achieved through object renaming declarations. A renaming produces a new view to the object: <lang ada>type Container is array (Positive range <>) of Element; for I in Container'Range loop

  declare
     Item : Element renames Container (I);
  begin
     Do_Something(Item); -- Here Item is a reference to Container (I)
  end;

end loop;</lang>

The forthcoming standard (Ada 2012) allows a more direct way to reference all the items in a container or an array:

<lang ada>type Container is array (Positive range <>) of Element; for Item of Container loop

     Do_Something(Item);  

end loop;</lang>

ALGOL 68

The following code creates a pointer to an INT variable: <lang algol68>INT var := 3; REF INT pointer := var;</lang> Access the integer variable through the pointer: <lang algol68>INT v = pointer; # sets v to the value of var (i.e. 3) # REF INT(pointer) := 42; # sets var to 42 #</lang> Change the pointer to refer to another object: <lang algol68>INT othervar; pointer := othervar;</lang> Change the pointer to not point to any object: <lang algol68>pointer := NIL; # 0 cannot be cast to NIL #</lang> Get a pointer to the first element of an array: <lang algol68>[9]INT array; pointer := array[LWB array];</lang> There is no pointer arithmetic, eg no p +:=3

With references:

The following code creates a constant reference to an INT variable, effectively an alias: <lang algol68>REF INT alias = var;</lang> Access the integer variable through the reference: <lang algol68>INT v2 = alias; # sets v2 to the value of var, that is, 3 # alias := 42; # sets var to 42 #</lang> Constand references cannot be changed to refer to other objects.

Pointers can be compared, but only for basic equality: <lang algol68>printf(($"alias "b("IS","ISNT")" var!"l$, alias IS var));</lang> Output: alias IS var!

Get a reference to the first element of an array: <lang algol68>[9]INT array2; REF INT ref3 = array2[LWB array2];</lang> Changing the reference to refer to another object of the array is not possible.

ALGOL 68 also allows pointers to slices of rows and/or columns of arrays: <lang algol68>[9,9]INT sudoku; REF [,]INT middle; middle := sudoku[4:6,4:6];</lang>

This includes pointers to sliced character arrays: <lang algol68>[30]CHAR hay stack := "straw straw needle straw straw"; REF[]CHAR needle = hay stack[13:18]; needle[2:3] := "oo"; print((hay stack))</lang> Output: straw straw noodle straw straw

AutoHotkey

The address of the variable structure itself cannot be changed using built in methods. <lang AutoHotkey>VarSetCapacity(var, 100)  ; allocate memory NumPut(87, var, 0, "Char") ; store 87 at offset 0 MsgBox % NumGet(var, 0, "Char") ; get character at offset 0 (87) MsgBox % &var  ; address of contents pointed to by var structure MsgBox % *&var ; integer at address of var contents (87)</lang>

BBC BASIC

<lang bbcbasic> REM Pointer to integer variable:

     pointer_to_varA = ^varA%
     !pointer_to_varA = 123456
     PRINT !pointer_to_varA
     
     REM Pointer to variant variable:
     pointer_to_varB = ^varB
     |pointer_to_varB = PI
     PRINT |pointer_to_varB
     
     REM Pointer to procedure:
     PROCmyproc : REM conventional call to initialise
     pointer_to_myproc = ^PROCmyproc
     PROC(pointer_to_myproc)
     
     REM Pointer to function:
     pointer_to_myfunc = ^FNmyfunc
     PRINT FN(pointer_to_myfunc)
     END
     
     DEF PROCmyproc
     PRINT "Executing myproc"
     ENDPROC
     
     DEF FNmyfunc
     = "Returned from myfunc"</lang>

C and C++

The following code creates a pointer to an int variable <lang c>int var = 3; int *pointer = &var;</lang>

Access the integer variable through the pointer: <lang c>int v = *pointer; /* sets v to the value of var (i.e. 3) */

  • pointer = 42; /* sets var to 42 */</lang>

Change the pointer to refer to another object <lang c>int othervar; pointer = &othervar;</lang>

Change the pointer to not point to any object <lang c>pointer = NULL; /* needs having stddef.h included */</lang> or <lang c>pointer = 0; /* actually any constant integer expression evaluating to 0 could be used, e.g. (1-1) will work as well */</lang> or <lang c>pointer = (void*)0; /* C only, not allowed in C++ */</lang>

Get a pointer to the first element of an array: <lang c>int array[10]; pointer = array; /* or alternatively: */ pointer = &array[0];</lang>

Move the pointer to another object in the array <lang c>pointer += 3; /* pointer now points to array[3] */ pointer -= 2; /* pointer now points to array[1] */</lang>

Access another object in the same array through the pointer <lang c>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] */</lang>

C++

With pointers: See 'C' example above.

C++ specific alternative to "The following code creates a pointer to an int variable": <lang cpp>int* pointer2(&var);</lang>

With references:

The following code create a reference to an int variable: <lang cpp>int var = 3; int& ref = var; // or alternatively: int& ref2(var);</lang>

Access the integer variable through the reference <lang cpp>int v = ref; // sets v to the value of var, that is, 3 ref = 42; // sets var to 42</lang>

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: <lang cpp>int array[10]; int& ref3 = array[0];</lang>

Changing the reference to refer to another object of the array is not possible.

Accessing another object of the array through the reference: <lang cpp>v = (&ref)[3]; // read value of array[3]; however doing this is bad style</lang>

C#

This example represents usage of Reference and Value. <lang csharp> static void Main(string[] args) { int p;

p = 1; Console.WriteLine("Ref Before: " + p); Value(ref p); Console.WriteLine("Ref After : " + p);

p = 1; Console.WriteLine("Val Before: " + p); Value(p); Console.WriteLine("Val After : " + p);

Console.ReadLine(); }

private static void Value(ref int Value) { Value += 1; } private static void Value(int Value) { Value += 1; } </lang>

Example Result:

Ref Before: 1
Ref After : 2
Val Before: 1
Val After : 1

Common Lisp

See Address_of_a_variable#Common Lisp

D

<lang d>void main() {

   // Take the address of 'var' and placing it in a pointer:
   int var;
   int* ptr = &var;
   // Take the pointer to the first item of an array:
   int[10] data;
   auto p2 = data.ptr;


   // Depending on variable type, D will automatically pass either
   // by value or reference.
   // By value: structs, statically sized arrays, and other
   //           primitives (int, char, etc...);
   // By reference: classes;
   // By kind of reference: dynamically sized arrays, array slices.
   struct S {}
   class C {}
   void foo1(S s) {}        // By value.
   void foo2(C c) {}        // By reference.
   void foo3(int i) {}      // By value.
   void foo4(int[4] i) {}   // By value (unlike C).
   void foo6(int[] i) {}    // Just length-pointer struct by value.
   void foo5(T)(ref T t) {} // By reference regardless of what type
                            // T really is.

}</lang>

Delphi

Delphi ( Object Pascal ) fully supports both typed and untyped pointers.

Examples of pointers

Simple untyped pointer variable:

Variable Declaration

<lang delphi>pMyPointer : Pointer ;</lang>

Simple pointer to a predefined type:

Variable Declaration

<lang delphi>pIntPointer : ^Integer ;</lang>

A pointer to a Record. This is the equivalent to a Struct in C

Type Defintion

<lang delphi>MyRecord = Record

           FName : string[20];
           LName : string[20];
          end;</lang>

Variable Declaration

<lang delphi>pMyRecord : ^MyRecord ;</lang>

Note that when defining a pointer type, unless otherwise, you may refer to the pointed to type before defining it. For example the following is legal despite tFoo not being defined at the pointer definition:

<lang delphi>type

 pFoo = ^tFoo; { allowed despite tFoo not yet being defined }
 tFoo = record
          value1, value2: integer;
        end;</lang>

- Dereferencing a Pointer -

Pointers are dereferenced using the caret '^' symbol. Dereferencing will cause the compiler or RTL to reveal the data that the pointer points to:

<lang delphi>IntVar := pIntPointer^ ;</lang>

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.

<lang delphi>IntVar := integer(MyPointer^);</lang>

- Pushing a Pointer -

Many programmers are familiar with C's ability to increment pointers of any type by using the ++ or -- operators. The equivalent in Delphi is to use either the Inc or Dec standard procedure:

<lang delphi>Inc(PtrVar); //increment by one element Inc(PtrVar, 4); //incremement by four elements Dec(PtrVar); //decrement by one element</lang>

C-style array indexing is also supported by default for PByte (a pointer to a byte), PAnsiChar (a pointer to a singlebyte character) and PWideChar (a pointer to a doublebyte character). For any other typed pointer, it can be enabled using a compiler directive:

<lang delphi>{$POINTERMATH ON} PrevIntVar := MyIntPtr[-1]; Rec4 := MyRecPtr[4];</lang>

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) }
}

Forth

Forth is an untyped language, and treats pointers in much the same way that assembly language does. In Forth, memory is addressable in characters, cells and double cells. Cells are the native word size of the host processor, and are usually either 16 or 32 bits in size. Double cells are twice that size. Address alignment requirements depend on the processor being used to host the Forth system.

To declare a variable that lives in memory:

 variable myvar   \ stores 1 cell
 fvariable myfvar \ stores 1 floating point number (often 8 bytes)
 2variable my2var \ stores 2 cells

This creates the word "myvar", which when executed leaves the address of a cell of memory on the stack. This address may be accessed with @ (fetch) or ! (store):

 1 myvar !  \ place the value 1 into myvar
 myvar @ .  \ prints the value stored in myvar
 1 myvar +! \ add 1 to the value stored in myvar

Other fetch and store operations:

 c@ c!  \ fetch/store a single character
 @  !   \ fetch/store one cell
 2@ 2!  \ fetch/store two cells
 f@ f!  \ fetch/store a floating point value

Forth also has "value", which is a construct similar to other languages' "reference":

 10 value myval  \ create a new word that returns the value 10
 myval .         \ prints 10
 20 to myval     \ Changes myval to return 20 instead of 10

Forth also has a concept analogous to function pointers - the "execution token". ETs are the address of a word's executable code. The ' character, pronounced "tick", returns the execution token of the next word in the input stream. "Execute" calls the XT on the stack. XT's are cells and can be stored and operated on as desired.

 ' myval         \ Leaves the XT of myval on the stack
 ' myval execute \ Equivalent to just typing "myval"

For pointer arithmetic, standard integer math operations may be used. There are some words that are specifically designed to enable portable pointer arithmetic:

 cell        \ Puts the number of bytes in one cell on the stack
 cell+       \ Adds one cell
 10 cells +  \ adds 10 cells
 aligned     \ rounds the address up to the next cell

An contiguous block of memory may be named with CREATE and allocated with ALLOT.

 create array 20 cells allot

As an example, here is some code to add together an array of cells, expanded and commented:

 : add-cells ( addr n -- sum )
    0 -rot      \ make stack into ( 0 addr n )
    bounds ?do  \ bounds converts an <address count> pair into a <high, low> range
       i @      \ using the current loop index as an address, fetch the cell
       +        \ Add it to the top number on the stack
    cell +loop  \ Advance the loop index by the size of one cell
 ;

Fortran

Since Fortran90, the pointer 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 associated (Fortran 95):

<lang fortran>if ( associated(pointertoreal) ) !...</lang>

and the association can be nullified as before with nullify.

The data a "pointer" points to can be allocated as if the allocatable 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 deallocate(array) code.

The function associated (Fortran 95) accepts also the optional argument target, 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 intpointer, i.e. pointers to integer; the integer, dimension(:), pointer :: pt 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).

Go

Go has pointers but no pointer arithmetic. In general it disallows many operations that are common in other languages but have proven to be common sources of programming errors.

Short of restrictions though, * and & are used much as they are in C.

<lang go>var p *int // declare p to be a pointer to an int i = &p // assign i to be the int value pointed to by p</lang>

The zero value of a pointer is called nil. Dereferencing a nil pointer, as in the example above, causes a run-time panic.

Some go types contain pointers in their internal representation and are called reference types. For example, slices, maps, and channels are always reference types.

<lang go>var m map[string]int</lang>

declares m as object of map type, but does not allocate or create anything. It's internal pointer is nil and attempts to store anything in the map will cause a run-time panic. The following short declaration declares m the same as above, but it also initializes the internal representation.

<lang go>m := make(map[string]int)</lang>

Built-in function make allocates and constructs the internal representation and returns a map object ready to use.

Assignment to a reference type such as a slice, map, or channel does not do a deep copy. It results in two references to the same underlying data. For example

<lang go>b := []byte(“hello world”) c := b c[0] = 'H' fmt.Println(string(b))</lang> Output:

Hello world

Go's garbage collector is aware of references created by taking the address of an object.

<lang go>func three() *int {

   i := 3
   return &i // valid.  no worry, no crash.

}</lang>

Because of this, a common syntax for allocating a struct is to use & with a literal:

<lang go>type pt struct {

   x, y int

}

return &pt{22, 79} // allocates a pt object and returns a pointer to it.</lang>

Haskell

In Haskell, all normal values are immutable, and for those values pointer and reference operations make no sense. Internally, many values are boxed, that is, they contain an extra indirection which can be thought of as a pointer. But that is all handled transparently by the compiler.

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> import Data.STRef

example :: ST s () example = do

 p <- newSTRef 1
 k <- readSTRef p
 writeSTRef p (k+1)

</lang>

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'.

Icon and Unicon

Icon and Unicon do not have a pointer data type and cannot manipulate references. Declarations are not needed for type enforcement and instances of data types are both Self-Descriptive and Safe. Data types additionally fall into either Mutable and Immutable Types. Program semantics treat immutable types as call by value and mutable types such as lists and tables as call by reference.

J

J's "boxes" are, in essence, pointers (except with pass-by-value semantics instead of pass-by-reference semantics, and J does not allow "pointer arithmetic" on boxes).

< used monadically boxes its argument (much like C's & creates a pointer to a value).

> used monadically unboxes its argument (much like C's * dereferences a pointer).

That said, names, in J, refer to their values, and names are generally used when references are needed.

Java

In Java, all values are either primitives (int, char, byte, double, etc.) or they are references to an object. These references are kind of like pointers in C/C++, but you cannot perform arithmetic on them, nor can you directly dereference pointers or take the address of something. All objects are always accessed through references - you create one using new Something(), it returns a reference; and you access an object's fields and methods using the . operator, which takes a reference to the object as its left operand.

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() {
    Foo a; // this declares a reference to Foo object; if this is a class field, it is initialized to null
    a = new Foo(); // this assigns a to point to a new Foo object
    Foo b = a; // this declares another reference to point to the same object that "a" points to
    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.

Modula-3

Modula-3 uses references; However, it does allow arithmetic and address operations (but only in unsafe modules).

Here is an example of a traced reference to an integer. <lang modula3>TYPE IntRef = REF INTEGER;

VAR intref := NEW(IntRef);

intref^ := 10</lang>

The ^ character is the dereference operator, and is suffixed to the reference variable name.

Traced and Untraced

There are two reference types in Modula-3, traced and untraced. Traced reference types are garbage collected, whereas untraced reference types are not. Address arithmetic and address operations are allowed only on untraced reference types. The built-in type ADDRESS is of type UNTRACED REF T. Untraced references are only allowed in unsafe modules.

REFANY

The built-in type REFANY is of type REF T, which is the "root" reference type, and can be a reference of any type. <lang modula3>VAR any: REFANY; any := NEW(REF INTEGER); (* Modula-3 knows that any is now REF INTEGER with a tag added by NEW. *)</lang>

TYPECASE

To determine the type of a variable, you can use TYPECASE. <lang modula3>PROCEDURE Sum(READONLY a: ARRAY OF REFANY): REAL =

 VAR sum := 0.0;
 BEGIN
   FOR i := FIRST(a) TO LAST(a) DO
     TYPECASE a[i] OF
     | NULL => (* skip *)
     | REF INTEGER (e) => sum := sum + FLOAT(e^);
     | REF REAL(e) => sum := sum + e^;
     ELSE (* skip *)
     END;
   END;
   RETURN sum;
 END Sum;</lang>

OCaml

Like Java, Python, and most other languages, many complex data structures in OCaml are boxed, including records, arrays, objects, algebraic data types, etc. In other words, you always refer to them using a level of indirection. Records and objects can contain mutable fields, and elements of arrays are mutable. So when you pass a mutable record or array, you are actually passing a reference and the contents of the record or array can be modified by the called function.

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> 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 *) </lang>

(The OCaml web-site provides this page on the subject.)

ooRexx

In ooRexx, all values are references to an object. These references are kind of like pointers in C/C++, but you cannot perform arithmetic on them, nor can you directly dereference pointers or take the address of something. All objects are always accessed through references - you create one by sending a NEW message to a class object, which returns a reference; and you access an object's methods using the ~ operator, which takes a reference to the object as its left operand.

If the object that a reference is pointing to is mutable (i.e. it has methods that allows changing of its internal variables), 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 oorexx>

::class Foo
::method init 
  expose x
  x = 0 
::attribute x   
::routine somefunction
    a = .Foo~new   -- assigns a to point to a new Foo object 
    b = a          -- b and a now point to the same object 
    a~x = 5        -- modifies the X variable inside the object pointer to by a
    say b~x        -- displays "5" because b points to the same object as a 

</lang>

ooRexx is call-by-value. When passing arguments, you are passing object 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 an attribute of an object, then modify the object through the reference.


PARI/GP

GP does not allow user functions with pointers, but some built-in functions like issquare have pointer arguments: <lang parigp>n=1; issquare(9,&n); print(n); \\ prints 3</lang>

Pari program can use C pointers normally. In fact, all GEN variables are actually pointers to a space within the Pari stack (or, rarely, the Pari heap).

Pascal

See Delphi

Perl

Works with: Perl version 5.x

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');
my %hash = ( firstkey => 'a', secondkey => 'hash' );

# make references
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"
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</lang>

You may also create anonymous references.

<lang perl> my $scalarref = \'a scalar';

my $arrayref = ['an', 'array'];
my $hashref = { firstkey => 'a', secondkey => 'hash' }</lang>

Perl 6

In Perl 6 all non-native values are boxed and accessed via implicit references. (This is like Java or Python, but unlike C or Perl 5, which use explicit referencing and dereferencing.) Variables are references to containers that can contain references to other values. Basic binding (aliasing) of references to names is supported via the := operator, while assignment to mutable containers implies a dereference from the name to the container, followed by copying of values rather than by duplicating pointers. (Assignment of a bare object reference copies the reference as if it were a value, but the receiving container automatically dereferences as necessary, so to all appearances you are putting the object itself into the destination rather than its reference, and we just think the object can be in more than one place at the same time.)

<lang perl6>my $foo = 42; # place a reference to 42 in $foo's item container $foo++; # deref $foo name, then increment the container's contents to 43 $foo.say; # deref $foo name, then $foo's container, and call a method on 43.

$foo := 42; # bind a direct ref to 42 $foo++; # ERROR, cannot modify immutable value

my @bar = 1,2,3; # deref @bar name to array container, then set its values @bar»++; # deref @bar name to array container, then increment each value with a hyper @bar.say; # deref @bar name to array container, then call say on that, giving 2 3 4

@bar := (1,2,3); # bind name directly to a Parcel @bar»++; # ERROR, parcels are not mutable</lang> References to hashes and functions work more like arrays, insofar as a method call acts directly on the container, not on what the container contains. That is, they don't do the extra dereference implied by calling a method on a scalar variable.

To the first approximation, Perl 6 programmers do not think about references much; since everything is a reference, and value semantics are emulated by assign and other mutating operators, the ubiquitous references are largely transparent to the Perl 6 programmer most of the time.

PHP

Actual Reference or Pointer "objects" don't exist in PHP, but you can simply tie any given variable or array value together with the "=&" operator. Adding the "&" symbol before a function name and the times a function is called causes the functions return values to be returned by reference. Adding the "&" synbol before any function parameter, and that parameter is passed by reference into the function.

As an additional note, the "global" keyword, simply references the variable from the $_GLOBALS superglobal array into a variable by the same name in the current scope. This is an important distinction as other functions that you call can actually re-reference the $_GLOBALS value to a different variable, and your function which used the "global" keyword is no longer actually linked to anything in the $_GLOBALS array.

<lang php><?php /* Assignment of scalar variables */ $a = 1; $b =& $a; // $b and $a are now linked together $b = 2; //both $b and $a now equal 2 $c = $b; $c = 7; //$c is not a reference; no change to $a or $b unset($a); //won't unset $b, just $a.

/* Passing by Reference in and out of functions */ function &pass_out() {

   global $filestr;  //$exactly equivalent to: $filestr =& $_GLOBALS['filestr'];
   $filestr = get_file_contents("./bigfile.txt");
   return $_GLOBALS['filestr'];

} function pass_in(&$in_filestr) {

   echo "File Content Length: ". strlen($in_filestr);
   /* Changing $in_filestr also changes the global $filestr and $tmp */
   $in_filestr .= "EDIT";
   echo "File Content Length is now longer: ". strlen($in_filestr);

}

$tmp = &pass_out(); // now $tmp and the global variable $filestr are linked pass_in($tmp); // changes $tmp and prints the length

?></lang>

In most cases, PHP "does the right thing" as pertaining to variables and not duplicating variables in memory that have not been edited. Internally, as variables are copied from one to another, passed in and out of functions, etc, they are Not actually duplicated in memory, but rather referenced until one of these copies is changed (called "copy on write", see debug_zval_dump()). So, in the above functions example, if we took out all the ampersands, it would all work perfectly and not duplicate the big string in memory up until the line where we concatenate and add "EDIT" to the end.

PHP Objects are Always passed by reference, so passing an object into and out of a function, will not make multiple cloned instances of that object. However, arrays are Not objects, and thus, every time they are passed or copied, they need to be passed by reference if you mean for any changes on the child to be applied to the parent.

See Also

PicoLisp

The internal PicoLisp machinery consists completely of pointers. Any data item (except numbers) is a pointer that points to a cell, which in turn consists of two pointers ("cons pair").

The pointers are not evident to the programmer. The development environment presents them as high level structures (symbols or lists). However, the pointer value (the address) can be obtained with the 'adr' function.

"Dereferencing" a pointer is done with the 'car' or 'val' functions. They return the data item at the memory location (CAR or VAL part of a cell). With 'set', a value can be stored in the referred location.

There is no meaningful pointer arithmetics, except functions like 'cdr' or 'nth', which advance the pointer to the next (linked to) location(s). <lang PicoLisp>: (setq L (1 a 2 b 3 c)) # Create a list of 6 items in 'L' -> (1 a 2 b 3 c)

(nth L 4) # Get a pointer to the 4th item

-> (b 3 c)

(set (nth L 4) "Hello") # Store "Hello" in that location

-> "Hello"

L # Look at the modified list in 'L'

-> (1 a 2 "Hello" 3 c)</lang>

Pop11

Pop11 uses reference model, conceptually all Pop11 data consists of references. Therefore, normally there is no need for explicit references:

vars vec1, vec2;
;;; Create a vector and assign (reference to) it to vec1
consvector("a", "b", "c", 3) -> vec1;
;;; Copy (reference to) vector
vec1 -> vec2;
;;; Print value of vec1
vec1 =>
;;; Change first element of vec2
"d" -> vec2(1);
;;; Print value of vec1 -- the value changes because vec1 and
;;; vec2 reference the same vector
vec1 =>

However, if one needs extra indirection one can get it:

vars ref1, ref2;
;;; Allocate a reference to number 42
consref(42) -> ref1;
;;; Copy reference
ref1 -> ref2;
;;; print value
cont(ref2) =>
;;; Change referenced value
17 -> cont(ref2);
;;; print value of first reference
cont(ref1) =>

Standard Pop11 does not allow pointer arithmetics or address operator. There is a low-level extension (Syspop11) which has C-like pointers (with pointer arithmetics), but those does not count as "basic data operation".

PureBasic

Pointers

A pointer's name is preceded by an '*' and are variables of type integer that can hold an address (either 32-bit or 64-bit depending on the OS compiled for), and do not differ from other integer variables in this respect. Pointers can be declared as pointing to structured memory and allow that memory to be de-referenced to allow easier manipulation of its contents. The following code creates a pointer to an integer variable: <lang PureBasic>Define varA.i = 5, varB.i = 0, *myInteger.Integer

  • myInteger = @varA ;set pointer to address of an integer variable

varB = *myInteger\i + 3 ;set variable to the 3 + value of dereferenced pointer, i.e varB = 8</lang> Change pointer to refer to another integer variable: <lang PureBasic>Define varC.i = 12

  • myInteger = @varC</lang>

Change pointer to not point to anything: <lang PureBasic>*myInteger = #Null ;or anything evaluating to zero</lang> Get a pointer to the first element of an array, or any desired element: <lang PureBasic>Dim myArray(10)

  • myInteger = myArray()
Or alternatively
  • myInteger = @myArray(0)
any specific element
  • myInteger = @myArray(4) ;element 4</lang>

PureBasic does not provide pointer arithmetic but it does allow integer math operations on its pointers. This makes it easy to implement a variety of pointer arithmetic with the help of the compiler function SizeOf(). <lang PureBasic>*myInteger + 3 * SizeOf(Integer) ;pointer now points to myArray(3)

  • myInteger - 2 * SizeOf(Integer) ;pointer now points to myArray(1)</lang>

In a similar manner the compiler function OffsetOf() may also be used to obtain the memory offset for an sub-element of a structure if needed: <lang PureBasic>Structure employee

 id.i
 name.s
 jobs.s[20] ;array of job descriptions

EndStructure

Dim employees.employee(10) ;an array of employee's

set a string pointer to the 6th job of the 4th employee
  • myString.String = @employees(3) + OffsetOf(employee\jobs) + 5 * SizeOf(String)</lang>

Addresses of variables or procedure

Addresses to variables and functions are obtained with the '@' operator. <lang PureBasic>*pointer = @varA

  • pointer = @myFunction()</lang>

Addresses of labels

To find the address of a label, you put a question mark (?) in front of the label name. <lang PureBasic>; Getting the address of a lable in the code text$="'Lab' is at address "+Str(?lab) MessageRequester("Info",text$)

Using lables to calculate size

text$="Size of the datasetion is "+Str(?lab2-?lab)+" bytes." MessageRequester("Info",text$)

Using above to copy specific datas

Define individes=(?lab2-?lab1)/SizeOf(Integer) Dim Stuff(individes-1)  ; As PureBasic uses 0-based arrays CopyMemory(?lab1,@Stuff(),?lab2-?lab1)

DataSection

 lab:
 Data.s "Foo", "Fuu"
 lab1:
 Data.i  3,1,4,5,9,2,1,6
 lab2:

EndDataSection</lang>

Python

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:
b = []
# Classes are "factories" for creating new objects: invoke class name as a function:
class Foo(object):
    pass
c = Foo()
# Again, but with optional initialization:
class Bar(object):
    def __init__(self, initializer = None)
        # "initializer is an arbitrary identifier, and "None" is an arbitrary default value
        if initializer is not None:
           self.value = initializer
d = Bar(10)
print d.value
# Test if two names are references to the same object:
if a is b: pass
# Alternatively:
if id(a) == id(b): pass
# Re-bind a previous used name to a function:
def a(fmt, *args):
    if fmt is None:
        fmt = "%s"
     print fmt % (args)
# Append reference to a list:
b.append(a)
# Unbind a reference:
del(a)
# 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].

Racket

As in many other functional languages, Racket doesn't have pointers to its own values. Instead, Racket uses "boxes" that are similar to "ref" types in *ML: <lang racket>

  1. lang racket

(define (inc! b) (set-box! b (add1 (unbox b))))

(define b (box 0)) (inc! b) (inc! b) (inc! b) (unbox b) ; => 3 </lang>

In addition, Racket has a representation of traditional C pointers as part of its FFI, but this is intended only for dealing with foreign code.

SAS

<lang sas>/* Using ADDR to get memory address, and PEEKC / POKE. There is also PEEK for numeric values. */ data _null_; length a b c $4; adr_a=addr(a); adr_b=addr(b); adr_c=addr(c); a="ABCD"; b="EFGH"; c="IJKL"; b=peekc(adr_a,1); call poke(b,adr_c,1); put a b c; run;</lang>

Standard ML

Like OCaml, Standard ML doesn't have pointers but have a "ref" mutable data structure which is the basis of mutability in Standard ML:

<lang sml> val p = ref 1; (* create a new "reference" data structure with initial value 1 *) val k = !p; (* "dereference" the reference, returning the value inside *) p := k + 1; (* set the value inside to a new value *) </lang>

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, e.g.: <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 or the upvar command, e.g.: <lang tcl>set arr(var) 3 set pointer var set arr($pointer); # returns 3 set arr($pointer) 42; # arr(var) now has value 42

set var 3 set pointer var upvar 0 $pointer varAlias; # varAlias is now the same variable as var set varAlias 42; # var now has value 42</lang> This second technique is most commonly used between stack levels (i.e., with the first argument to upvar being 1) so that a local variable of one procedure can be manipulated in another utility procedure that it calls.

Toka

Toka is an untyped language, and treats pointers in a manner similar to that of assembly language. In Toka, memory can be addressed in characters and cells. Cells are the native word size of the host processor, and are generally either 32 or 64 bits in size. Address alignment is dependent on the host processor.

To declare a variable that lives in memory:

variable myvar   #! stores 1 cell

This creates the word "myvar", which when executed leaves the address of a cell of memory on the stack. This address may be accessed with @ (fetch) or ! (store):

1 myvar !  #! place the value 1 into myvar
myvar @ .  #! prints the value stored in myvar
1 myvar +! #! add 1 to the value stored in myvar

Other fetch and store operations:

c@ c!  \ fetch/store a single character
@  !   \ fetch/store one cell

Toka also has an optional "value", which is a construct similar to other languages' "reference":

needs values
10 value myval  #! create a new word that returns the value 10
myval .         #! prints 10
20 to myval     #! Changes myval to return 20 instead of 10

Toka has a concept similar to that of function pointers. The word ` returns the address of a quote which can be invoked or passed around.

` myval         #! Leaves the address of myval on the stack
` myval invoke  #! Equivalent to just typing "myval"

For pointer arithmetic, standard integer math operations may be used. There are some words that are specifically designed to enable portable pointer arithmetic:

cell-size   #! Puts the number of bytes in one cell on the stack
cell+       #! Adds one cell
10 cells +  #! Adds 10 cells
char-size   #! Puts the number of bytes in one character on the stack
char+       #! Adds one char
10 chars +  #! Adds 10 chars

XPL0

<lang XPL0>\Paraphrasing the C example: \This creates a pointer to an integer variable: int Var, Ptr, V; Ptr:= @Var;

\Access the integer variable through the pointer: Var:= 3; V:= Ptr(0); \set V to the value of Var, i.e. 3 Ptr(0):= 42; \set Var to 42

\Change the pointer to refer to another integer variable: int OtherVar; Ptr:= @OtherVar;

\Change the pointer to not point to anything: Ptr:= 0; \or any integer expression that evaluates to 0

\Set the pointer to the first item of an array: int Array(10); Ptr:= Array; \Or alternatively: Ptr:= @Array(0);

\Move the pointer to another item in the array: def IntSize = 4; \number of bytes in an integer Ptr:= Ptr + 3*IntSize; \pointer now points to Array(3) Ptr:= Ptr - 2*IntSize; \pointer now points to Array(1)

\Access an item in the array using the pointer: V:= Ptr(3); \get third item after Array(1), i.e. Array(4) V:= Ptr(-1); \get item immediately preceding Array(1), i.e. Array(0) ]</lang>