Pointers and references: Difference between revisions

Add Ecstasy example
(→‎{{header|PARI/GP}}: now with references!)
(Add Ecstasy example)
 
(23 intermediate revisions by 7 users not shown)
Line 1:
{{Task|Basic Data Operations}}{{basic data operation}}In this task, the goal is to demonstrate common operations on pointers and references. These examples show pointer operations on the stack, which can be dangerous and is rarely done. Pointers and references are commonly used along with [[Memory allocation]] on the [[heap]].
=={{header|6502 Assembly}}==
6502 Assembly is different from most other assembly languages, in the way constants are specified. When you have a statement like <code>int x = 3</code> in a language like [[C]] or <code>mov eax,3</code> in [[X86 Assembly]], the 3 in both cases is called a ''constant'' or ''immediate'' value, meaning that the value 3 is what gets stored. 6502 Assembly does '''not''' work this way. It uses what is called "Motorola syntax" where an immediate value needs a # in front, or else the number is '''interpreted as a pointer to memory.''' For example:
===Pointers===
<syntaxhighlight lang="6502asm">LDA 8 ;load the byte stored at memory address 0x0008 into the accumulator.
In <code>C</code>, <code>8086 Assembly</code>, and <code>Z80 Assembly</code>, a number that is an operand in an instruction, such as <code>mov ax,3</code> or <code>int x = 3;</code>, is an <i>immediate number</i>, i.e. a constant that equals the value of that number. <code>6502 Assembly</code> is the opposite. A number <b>without</b> a # in front represents a memory address.
LDA #8 ;load the number 8 into the accumulator.</syntaxhighlight>
 
<lang 6502asm>LDA $19 ;load the value at memory address $19 into the accumulator
LDA #$19 ;load the value hexadecimal 19 (decimal 25) into the accumulator</lang>
 
As you can see, the pointer is dereferenced automatically. The 6502 only has 8-bit registers and all memory addresses are 16-bit, so we can't do pointer arithmetic in the same way we could on the z80 for example. (If a one-byte address is specified as an operand, that is just the low byte; the high byte is assumed to equal 00 if none is given.) Rather, the x and y registers are used for offsetting.
 
<lang 6502asm>LDX #$05
LDA $2000,x ;load into the accumulator the byte stored at memory address $2005</lang>
 
The above example also works with y.
 
Pointers in 6502 Assembly can be 8-bit or 16-bit. The 6502 has a 16-bit address space ranging from $0000-$FFFF. An 8-bit pointer assumes the high byte to be zero. These pointers are referred to as pointers to "zero-page RAM" and the CPU is much more efficient at working with them than with 16-bit pointers.
===Double Pointers===
A pointer to a pointer is a little complicated on the 6502. First of all, this is a little-endian processor, so the bytes get swapped. Second, you HAVE to use X or Y. If you don't want to use X or Y to offset, set them to zero before the lookup. Unlike the above example, x and y work differently.
 
<syntaxhighlight lang="6502asm">LDX $2000 ;load the byte at memory address $2000 into X.
<lang 6502>LDA #$30
LDY $75 ;load the byte at memory address $0075 into Y. This instruction executes faster than the one above it.</syntaxhighlight>
STA $2000
LDA #$50
STA $2001
 
===Pointers on the stack===
LDA #$80
{{works with|65c02}}
STA $2005
The 6502's hardware stack is located at memory addresses $0100-$01FF and, unlike most CPU architectures, cannot be relocated to any arbitrary address outside this range. In addition, it uses the empty-stack convention, where the stack pointer points to free space rather than the value on top. Therefore, to create a pointer to the top item of the stack we can do the following:
LDA #$90
<syntaxhighlight lang="6502asm">TSX
STA $2006
LDA $0101,X ;load the byte most recently pushed on the stack into A without pulling it off the stack.</syntaxhighlight>
 
Note that in a subroutine, the value at <code>$0101,x</code> is typically the low byte of the program counter, plus 1. It may be different depending on how many registers you pushed onto the stack prior to entry as well. In this example, we'll look at a hand-written translation of the following [[C]] function (I'm ignoring 8-bit overflow just to keep things easier to write.)
<syntaxhighlight lang="c">inline unsigned char foo (unsigned char a, unsigned char b, unsigned char c){
return a+b+c;
}</syntaxhighlight>
 
<syntaxhighlight lang="6502asm">LDA #arg_C ;load whatever this value is into accumulator
LDX #$05
PHA
LDY #$07
LDA #arg_B
PHA
LDA #arg_A
PHA
foo:
PHX
TSX
;stack looks like this: __, X,LOW(PC),HIGH(PC),arg_A,arg_B,arg_C
;stack pointer points to __, as does $100,X after a TSX
LDA $0106,X ;LDA #arg_C
CLC
ADC $0105,X
CLC
ADC $0104,X ;ADC #arg_A
;we have the desired value in A, now return.
PLX</syntaxhighlight>
 
This can be done as well on the original 6502, but is much more difficult since you don't have <code>PHX/PLX</code>, which means that you can't preserve X or Y without destroying the value in the accumulator. To keep things simple I chose a 65c02 example.
LDA ($2000),y ;the values of $2000 and $2001 are looked up and swapped (this is a little-endian cpu after all)
;and the value at (that address plus Y) is loaded. In this example, this equates to LDA $5037
LDA ($2000,x) ;x is added to $2000 and the values at that address and the one after are looked up and swapped, and the
;value at the resulting address is loaded. In this example, this equates to LDA $9080</lang>
 
===Pointer arithmetic===
The 6502 can offset pointers up to 255 bytes forwards.
<syntaxhighlight lang="6502asm">LDX #$80
LDA $2000,X ;load the byte stored at $2080
LDY #$FF
LDA $2080,Y ;load the byte stored at $217F</syntaxhighlight>
Note that when using zero-page addressing, this offsetting is always modulo 256, meaning there is no "carry" when offsetting, unlike with absolute addressing.
 
<syntaxhighlight lang="6502">LDX #$C0
LDA $80,X ;load from $0040</syntaxhighlight>
 
=={{header|8086 Assembly}}==
Line 42 ⟶ 57:
===Pointers===
In most assemblers, an instruction or a numeric value can be given a label.
<langsyntaxhighlight lang="asm">.model small
.stack 1024
.data ; data segment begins here
Line 55 ⟶ 70:
 
mov ax, @code
mov es, ax</langsyntaxhighlight>
 
<code>equ</code> directives are flexible in that they can be intended as constants or as memory addresses. In this case, the <code>equ</code> directives involving <code>tempByte</code> and <code>tempWord</code> are used as memory addresses.
Line 61 ⟶ 76:
We can load to or from memory with the 8086 in a few different ways. In the example below, the value in a memory address is loaded directly from RAM to a register, or vice versa. Assume the code below takes place immediately after the setup above:
 
<langsyntaxhighlight lang="asm">mov ax,0FFFFh ;see note 1
mov word ptr [ds:tempWord],ax ;store hexadecimal value FFFF into tempWord
 
Line 69 ⟶ 84:
;Note 1:
;UASM doesn't like leading hex digits A-F so a 0 is placed in front.
;It doesn't change the storage type of the operand. (i.e. this is still a 16 bit value even though there are 5 digits)</langsyntaxhighlight>
 
8086 Assembly doesn't enforce data types that much. While your variables may be intended to be byte or word length, there's nothing actually stopping you from using the "wrong" pointer type, as long as the register you're moving to/from matches the size of the pointer variable.
 
<langsyntaxhighlight lang="asm">mov ax, byte ptr [ds:tempByte] ;assembler will generate an error - operands don't match
mov al, word ptr [ds:tempWord] ;assembler will generate an error - operands don't match
mov ax, word ptr [ds:tempByte] ;assembler will allow this even though the intended data size is wrong
mov al, byte ptr [ds:tempWord] ;assembler will allow this even though the intended data size is wrong
</syntaxhighlight>
</lang>
 
You can also define a full double word address like so: <code>UserRamPtr dword UserRam</code>
Then this pointer can be loaded into a segment register and data register with a single command, like so:
<langsyntaxhighlight lang="asm">LDS bx,UserRamPtr ;loads [ds:bx] with UserRamPtr</langsyntaxhighlight>
 
===Pointer Arithmetic===
 
A pointer can be loaded into a register like any other value.
<langsyntaxhighlight lang="asm">.data
myString db "Hello World!",0 ;the zero is the null terminator
.code
mov bx, seg myString ;load into bx the segment where myString is stored.
mov ds, bx ;load this segment into the data segment register. On the 8086, segment registers can't be loaded directly.
mov bx, offset MyString ;the memory address of the beginning of myString. The "H" is stored here.</langsyntaxhighlight>
 
Once we have the pointer to myString in bx, we can perform arithmetic on it like it was an ordinary numerical value. There is no distinction between pointer arithmetic and normal arithmetic in assembly. All arithmetic commands are available for use. If the programmer wishes to use that memory address as a number for some other purpose, that is perfectly legal. However this example will stick to the "proper" uses of pointer arithmetic, i.e. indexing and offsetting.
<langsyntaxhighlight lang="asm">add bx, 2 ;add 2 to bx. bx contains the memory address of the first "l" in "Hello"
mov al,[ds:bx] ;dereference the pointer and store the value it points to into al.</langsyntaxhighlight>
 
=={{header|68000 Assembly}}==
Line 102 ⟶ 117:
In most assemblers, a line of code or a value in work RAM can be given a label.
 
<langsyntaxhighlight lang="68000devpac">myVar equ $100000 ; a section of user ram given a label
myData: ; a data table given a label
dc.b $80,$81,$82,$83</langsyntaxhighlight>
 
The opcode <lang 68000devpaccode>LEA</langcode> instruction can load the address of a given label.
This isn't needed for values in RAM, but it is needed for loading from data tables in ROM.
 
<langsyntaxhighlight lang="68000devpac">LEA myData,A0 ;address of myData is stored in A0</langsyntaxhighlight>
 
The address registers <code>A0-</code> through <code>A6</code> hold 24-bit addresses. While they can contain 32 bits of data, the top byte is ignored.
 
68000 Assembly doesn't care about what type of data is being pointed to. It makes no distinction between bytes, words, longs, or executable code. That is up to the opcodes that interact with the data. For the following, assume that the address "<code>myData"</code> shown above is is loaded into <code>A0</code>, and that <code>D0</code> equaled 0x00000000 prior to the code below.
 
<langsyntaxhighlight lang="68000devpac">MOVE.B (A0),D0 ;D0 = 0x00000080
MOVE.W (A0),D0 ;D0 = 0x00008081
MOVE.L (A0),D0 ;D0 = 0x80818283</langsyntaxhighlight>
 
Putting a + after <code>(A0)</code> auto-increments the pointer by 1,2,or 4 for <code>MOVE.B</code>, <code>MOVE.W</code>, and <code>MOVE.L</code> respectively. The increment happens after the move.
 
<langsyntaxhighlight lang="68000devpac">LEA myData,A0 ;Assume for this example that data registers all equal 0.
MOVE.B (A0)+,D0 ;D0 = 00000080
MOVE.B (A0)+,D1 ;D1 = 00000081
MOVE.B (A0)+,D2 ;D2 = 00000082</langsyntaxhighlight>
 
 
Putting a - before <code>(A0)</code> pre-decrements the pointer by 1,2, or 4 for <code>MOVE.B</code>, <code>MOVE.W</code>, and <code>MOVE.L</code> respectively, ''before the move takes place.''
<langsyntaxhighlight lang="68000devpac">LEA myData+4,A0 ;Assume for this example that data registers all equal 0.
MOVE.B -(A0),D0 ;D0 = 00000083
MOVE.B -(A0),D1 ;D1 = 00000082
MOVE.B -(A0),D2 ;D2 = 00000081</langsyntaxhighlight>
 
<code>LEA</code> can also be used to pre-calculate a complex offset to an address.
<langsyntaxhighlight lang="68000devpac">LEA myData,A0
MOVE.W #$0C,D0
LEA (4,A0,D0),A3</lang> ;A3 = address of myData + 4 + $0C</syntaxhighlight>
 
An address can be offset by an immediate value, a register, or both. Data register offsets are measured at 16 bit word length. Although the second <code>LEA</code> is in brackets, it does NOT dereference the pointer. Let's look at the following example data:
 
<langsyntaxhighlight lang="68000devpac">myPointers: dc.l myData, myData2
myData: dc.b $80,$81,$82,$83
myData2: dc.b $84,$85,$86,$87
</syntaxhighlight>
</lang>
 
These two code snippets <i>are not the same</i>:
<syntaxhighlight lang ="68000devpac">LEA myData2,A1</langsyntaxhighlight>
 
<langsyntaxhighlight lang="68000devpac">LEA myPointers,A1
LEA (4,A1),A1</langsyntaxhighlight>
 
===Pointers on the stack===
Like any other address register, the stack pointer can be dereferenced and loaded from with a <code>MOVE</code> instruction. The 68000 uses the full stack convention, which means that <code>MOVE.L (SP),D0</code> will load the 4 bytes most recently pushed onto the stack into D0, rather than 4 bytes of "empty space" (read: garbage data). If you execute <code>MOVE.L (SP),D0</code> immediately after calling a subroutine with <code>JSR/BSR</code>, you will load D0 with the value of the program counter prior to the call.
 
If you maintain the stack 32-bit aligned at all times, you can offset the stack by multiples of 4 to get the desired parameters, assuming you pushed them in the reverse order they were declared in your function prototype.
 
<syntaxhighlight lang="68000devpac">;implements:
;uint64_t foo (uint16_t a,uint16_t b,uint16_t c){return a+b+c;}
MOVE.L #arg2,-(SP)
MOVE.L #arg1,-(SP)
MOVE.L #arg0,-(SP)
JSR foo
LEA (12,SP),SP ;discard the three values pushed prior to the call.
RTS
 
foo:
;outputs to D0
MOVE.L (4,SP),D0
ADD.L (8,SP),D0
ADD.L (12,SP),D0
RTS</syntaxhighlight>
 
===References===
 
Labeled memory can be read/written to directly, unlike in ARM Assembly.
<syntaxhighlight lang ="68000devpac">MOVE.B #$10,myVar</langsyntaxhighlight>
 
Unlike in C, pointers do not have to point to any specific type of data.
<syntaxhighlight lang ="68000devpac">MOVE.L #$FFEEDDCC,myVar</langsyntaxhighlight>
 
There is nothing stopping you from clobbering nearby stored data. In the above example, the byte FF gets written to $100000, EE to $100001, DD to $100002, and CC to $100003. If you intended myVar to be of byte length, you need to make sure you only use MOVE.B to read/write to/write from myVar.
 
=={{header|Ada}}==
Line 166 ⟶ 202:
 
Create a pool specific access type for an integer
<langsyntaxhighlight lang="ada">type Int_Access is access Integer;
Int_Acc : Int_Access := new Integer'(5);</langsyntaxhighlight>
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.
<langsyntaxhighlight lang="ada">type Safe_Int_Access is not null access Integer;</langsyntaxhighlight>
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
<langsyntaxhighlight lang="ada">declare
type Int_Ptr is access all Integer;
Ref : Int_Ptr;
Line 177 ⟶ 213:
Val : Integer := Var;
begin
Ref := Var'Access; -- "Ref := Val'Access;" would be a syntax error</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="ada">type Safe_Int_Ptr is not null access all Integer;</langsyntaxhighlight>
 
===Addresses===
Ada does not provide pointer arithmetic, but does allow evaluation of the address
<langsyntaxhighlight lang="ada">Var : Integer;
Var_Address : Address := Var'Address;</langsyntaxhighlight>
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
<langsyntaxhighlight 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</langsyntaxhighlight>
===References===
References in Ada are achieved through object renaming declarations. A renaming produces a new view to the object:
<langsyntaxhighlight lang="ada">type Container is array (Positive range <>) of Element;
for I in Container'Range loop
declare
Line 202 ⟶ 238:
Do_Something(Item); -- Here Item is a reference to Container (I)
end;
end loop;</langsyntaxhighlight>
 
The forthcoming standard (Ada 2012) allows a more direct way to reference all the items in a container or an array:
 
<langsyntaxhighlight lang="ada">type Container is array (Positive range <>) of Element;
for Item of Container loop
Do_Something(Item);
end loop;</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
The following code creates a pointer to an INT variable:
<langsyntaxhighlight lang="algol68">INT var := 3;
REF INT pointer := var;</langsyntaxhighlight>
Access the integer variable through the pointer:
<langsyntaxhighlight lang="algol68">INT v = pointer; # sets v to the value of var (i.e. 3) #
REF INT(pointer) := 42; # sets var to 42 #</langsyntaxhighlight>
Change the pointer to refer to another object:
<langsyntaxhighlight lang="algol68">INT othervar;
pointer := othervar;</langsyntaxhighlight>
Change the pointer to not point to any object:
<langsyntaxhighlight lang="algol68">pointer := NIL; # 0 cannot be cast to NIL #</langsyntaxhighlight>
Get a pointer to the first element of an array:
<langsyntaxhighlight lang="algol68">[9]INT array;
pointer := array[LWB array];</langsyntaxhighlight>
There is no pointer arithmetic, eg no p +:=3
 
Line 231 ⟶ 267:
 
The following code creates a constant reference to an INT variable, effectively an alias:
<langsyntaxhighlight lang="algol68">REF INT alias = var;</langsyntaxhighlight>
Access the integer variable through the reference:
<langsyntaxhighlight lang="algol68">INT v2 = alias; # sets v2 to the value of var, that is, 3 #
alias := 42; # sets var to 42 #</langsyntaxhighlight>
Constand references cannot be changed to refer to other objects.
 
Pointers can be compared, but only for basic equality:
<langsyntaxhighlight lang="algol68">printf(($"alias "b("IS","ISNT")" var!"l$, alias IS var));</langsyntaxhighlight>
Output: alias IS var!
 
Get a reference to the first element of an array:
<langsyntaxhighlight lang="algol68">[9]INT array2;
REF INT ref3 = array2[LWB array2];</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="algol68">[9,9]INT sudoku;
REF [,]INT middle;
middle := sudoku[4:6,4:6];</langsyntaxhighlight>
 
This includes pointers to sliced character arrays:
<langsyntaxhighlight 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))</langsyntaxhighlight>
Output: straw straw noodle straw straw
 
=={{header|ARM Assembly}}==
Pointers in ARM Assembly are very similar to that on 68000 Assembly. However, ARM Assembly has no address registers. Rather, enclosing a register in brackets treats its value as a memory location.
 
<syntaxhighlight lang="arm assembly">;this example uses VASM syntax, your assembler may not use the # before constants or the semicolon for comments
MOV R1,#0x04000000
MOV R0,#0x403
STR R0,[R1] ;store 0x403 into memory address 0x04000000.</syntaxhighlight>
 
The <code>STR</code> instruction is unusual in that its source is on the left and its destination on the right.
 
ARM Assembly has a variety of options for indexed offsetting thanks to its robust addressing modes and barrel shifter. You can offset by a constant or register, and apply a temporary bit shift to either. The syntax for it takes some getting used to but is well worth learning.
 
=={{header|AutoHotkey}}==
The address of the variable structure itself cannot be changed using built in methods.
<langsyntaxhighlight AutoHotkeylang="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)</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> REM Pointer to integer variable:
pointer_to_varA = ^varA%
!pointer_to_varA = 123456
Line 293 ⟶ 341:
DEF FNmyfunc
= "Returned from myfunc"</langsyntaxhighlight>
 
=={{header|C}} and {{header|C++}}==
The following code creates a pointer to an int variable
<langsyntaxhighlight lang="c">int var = 3;
int *pointer = &var;</langsyntaxhighlight>
 
Access the integer variable through the pointer:
<langsyntaxhighlight lang="c">int v = *pointer; /* sets v to the value of var (i.e. 3) */
*pointer = 42; /* sets var to 42 */</langsyntaxhighlight>
 
Change the pointer to refer to another object
<langsyntaxhighlight lang="c">int othervar;
pointer = &othervar;</langsyntaxhighlight>
 
Change the pointer to not point to any object
<langsyntaxhighlight lang="c">pointer = NULL; /* needs having stddef.h included */</langsyntaxhighlight>
or
<langsyntaxhighlight lang="c">pointer = 0; /* actually any constant integer expression evaluating to 0 could be used, e.g. (1-1) will work as well */</langsyntaxhighlight>
or
<langsyntaxhighlight lang="c">pointer = (void*)0; /* C only, not allowed in C++ */</langsyntaxhighlight>
 
Get a pointer to the first element of an array:
<langsyntaxhighlight lang="c">int array[10];
pointer = array;
/* or alternatively: */
pointer = &array[0];</langsyntaxhighlight>
 
Move the pointer to another object in the array
<langsyntaxhighlight lang="c">pointer += 3; /* pointer now points to array[3] */
pointer -= 2; /* pointer now points to array[1] */</langsyntaxhighlight>
 
Access another object in the same array through the pointer
<langsyntaxhighlight 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] */</langsyntaxhighlight>
 
The following code snippet shows a practical example of using pointers in C with structs. Note there are many ways to access to a value using the * operator.
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 370 ⟶ 418:
}
return i;
}</langsyntaxhighlight>
 
=={{header|c sharp|C#}}==
This example represents usage of Reference and Value.
<langsyntaxhighlight lang="csharp">
static void Main(string[] args)
{
Line 400 ⟶ 448:
Value += 1;
}
</syntaxhighlight>
</lang>
 
Example Result:
Line 418 ⟶ 466:
 
C++ specific alternative to "The following code creates a pointer to an int variable":
<syntaxhighlight lang ="cpp">int* pointer2(&var);</langsyntaxhighlight>
 
'''With references:'''
 
The following code create a reference to an int variable:
<langsyntaxhighlight lang="cpp">int var = 3;
int& ref = var;
// or alternatively:
int& ref2(var);</langsyntaxhighlight>
 
Access the integer variable through the reference
<langsyntaxhighlight lang="cpp">int v = ref; // sets v to the value of var, that is, 3
ref = 42; // sets var to 42</langsyntaxhighlight>
 
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:
<langsyntaxhighlight lang="cpp">int array[10];
int& ref3 = array[0];</langsyntaxhighlight>
 
Changing the reference to refer to another object of the array is not possible.
 
Accessing another object of the array through the reference:
<langsyntaxhighlight lang="cpp">v = (&ref)[3]; // read value of array[3]; however doing this is bad style</langsyntaxhighlight>
 
=={{header|COBOL}}==
===Pointers===
Pointers are declared like so, optionally with the type or program they will point to:
<syntaxhighlight lang cobol="cobolfree"> 01 ptr USAGE USAGEIS POINTER TO Some-Type.
01 prog-ptr USAGE USAGEIS PROGRAM-POINTER TO "some-program". *> TO is optional</langsyntaxhighlight>
 
<code>USAGE POINTER</code> data items are used in conjunction with <code>BASED</code> data items, with <code>ALLOCATE</code> optionally giving a pointer the address of the allocated memory. Pointers can also be used to free allocated memory, which will cause the pointer to be set to <code>NULL</code>.
<langsyntaxhighlight cobollang="cobolfree">ALLOCATE01 heap-item RETURNINGPICTURE IS X, ptrBASED.
 
...
PROCEDURE DIVISION.
FREE ptr</lang>
ALLOCATE heap-item RETURNING ptr
*> ...
FREE ptr</syntaxhighlight>
 
<code>USAGE PROGRAM-POINTER</code> data items are used to point to programs and their entry points.
{{works with|OpenCOBOL}}
{{works with|Visual COBOL}}
<langsyntaxhighlight cobollang="cobolfree">SET prog-ptr TO ENTRY "some-program"</langsyntaxhighlight>
 
Both types of pointer support basic pointer arithmetic.
<langsyntaxhighlight cobollang="cobolfree">SET ptr1 UP BY 10
SET ptr2 DOWN BY LENGTH OF foo</langsyntaxhighlight>
 
Pointers can also be set to point to where other pointers are pointing or to other pointers themselves.
<langsyntaxhighlight cobollang="cobolfree">SET ptr1 TO ptr2 *> ptr1 points to where ptr2 points
SET ptr2 TO ADDRESS OF ptr3 *> ptr2 points to ptr3</langsyntaxhighlight>
 
To alter the value pointed to by a pointer, the <code>SET</code> statement is needed once again and is used to set the address of <code>BASED</code> or <code>LINKAGE SECTION</code> data items, which can then be used to modify the data.
<langsyntaxhighlight cobollang="cobolfree">SET ADDRESS OF foo TO ptr
MOVE "bar" TO foo</langsyntaxhighlight>
 
===References===
Object references are declared like so, optionally with the class/interface they will reference:
<syntaxhighlight lang cobol="cobolfree"> 01 obj USAGE USAGEIS OBJECT-REFERENCE "some-object".</langsyntaxhighlight>
 
They contain either a reference to an object or <code>NULL</code>.
 
They are initialised using by invoking a class constructor, and set using the <code>SET</code> statement.
<langsyntaxhighlight cobollang="cobolfree">INVOKE SomeClass "new" RETURNING obj-ref
SET another-obj-ref TO obj-ref</langsyntaxhighlight>
 
<code>LINKAGE SECTION</code> data items are essentially references, being passed either the address of an argument (<code>BY REFERENCE</code>), the address of a copy of an argument (<code>BY CONTENT</code>) or the address itself, suitable for using with pointers (<code>BY VALUE</code>).
Line 489 ⟶ 540:
=={{header|D}}==
 
<langsyntaxhighlight lang="d">void main() {
// Take the address of 'var' and placing it in a pointer:
int var;
Line 516 ⟶ 567:
void foo5(T)(ref T t) {} // By reference regardless of what type
// T really is.
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
Line 528 ⟶ 579:
Variable Declaration
 
<syntaxhighlight lang ="delphi">pMyPointer : Pointer ;</langsyntaxhighlight>
 
Simple pointer to a ''predefined'' type:
Line 534 ⟶ 585:
Variable Declaration
 
<syntaxhighlight lang ="delphi">pIntPointer : ^Integer ;</langsyntaxhighlight>
 
A pointer to a ''Record''. This is the equivalent to a ''Struct'' in C
Line 540 ⟶ 591:
Type Defintion
 
<langsyntaxhighlight lang="delphi">MyRecord = Record
FName : string[20];
LName : string[20];
end;</langsyntaxhighlight>
 
Variable Declaration
 
<syntaxhighlight lang ="delphi">pMyRecord : ^MyRecord ;</langsyntaxhighlight>
 
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:
 
<langsyntaxhighlight lang="delphi">type
pFoo = ^tFoo; { allowed despite tFoo not yet being defined }
tFoo = record
value1, value2: integer;
end;</langsyntaxhighlight>
 
- Dereferencing a Pointer -
Line 561 ⟶ 612:
Pointers are dereferenced using the caret '^' symbol. Dereferencing will cause the compiler or RTL to reveal the data that the pointer points to:
 
<langsyntaxhighlight lang="delphi">IntVar := pIntPointer^ ;</langsyntaxhighlight>
 
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.
 
<langsyntaxhighlight lang="delphi">IntVar := integer(MyPointer^);</langsyntaxhighlight>
 
- Pushing a Pointer -
Line 571 ⟶ 622:
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:
 
<langsyntaxhighlight lang="delphi">Inc(PtrVar); //increment by one element
Inc(PtrVar, 4); //incremement by four elements
Dec(PtrVar); //decrement by one element</langsyntaxhighlight>
 
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:
 
<langsyntaxhighlight lang="delphi">{$POINTERMATH ON}
PrevIntVar := MyIntPtr[-1];
Rec4 := MyRecPtr[4];</langsyntaxhighlight>
 
=={{header|E}}==
Line 609 ⟶ 660:
=={{header|EchoLisp}}==
No pointers in EchoLisp. '''Boxes ''' or vectors can be used to perform call-by-reference operations.
<langsyntaxhighlight lang="scheme">
(define B (box 42))
→ B ;; box reference
Line 623 ⟶ 674:
(unbox B)
→ 666
</syntaxhighlight>
</lang>
 
=={{header|Ecstasy}}==
In Ecstasy, all values are references to objects. These references are like pointers in C, but address information is not accessible, and no arithmetic operations can be performed on them. Additionally, each reference is itself an object, providing reflective information about the reference.
 
Objects are always accessed and manipulated through references, using the <code>.</code> ("dot") operator.
 
Ecstasy uses call-by-value. When passing arguments, all arguments are references, passed by value.
 
<syntaxhighlight lang="ecstasy">
module test {
@Inject Console console;
 
public class Point(Int x, Int y) {
@Override String toString() = $"({x},{y})";
}
 
void run() {
Point p = new Point(0, 0);
p.x = 7;
p.y = p.x;
console.print($"{p=}");
 
// obtain the reference object itself
Ref<Point> r = &p;
console.print($"{r.actualType=}");
}
}
</syntaxhighlight>
 
{{out}}
<pre>
x$ xec test
p=(7,7)
r.actualType=Point
</pre>
 
=={{header|Forth}}==
Line 675 ⟶ 761:
Since Fortran90, the <tt>pointer</tt> attribute can be given:
 
<syntaxhighlight lang ="fortran">real, pointer :: pointertoreal</langsyntaxhighlight>
 
A so-declared pointer is in an undetermined state: a pointer should be nullified:
 
<syntaxhighlight lang ="fortran">nullify(pointertoreal)</langsyntaxhighlight>
 
But Fortran 95 allows to initialize pointers to NULL (unassociated):
 
<langsyntaxhighlight lang="fortran">real, pointer :: apointer => NULL()</langsyntaxhighlight>
 
A pointer can be associated:
 
<langsyntaxhighlight lang="fortran">real, target :: areal
pointertoreal => areal</langsyntaxhighlight>
 
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 existence of an ''association'' can be tested with <tt>associated</tt> (Fortran 95):
 
<langsyntaxhighlight lang="fortran">if ( associated(pointertoreal) ) !...</langsyntaxhighlight>
 
and the association can be nullified as before with <tt>nullify</tt>.
Line 698 ⟶ 784:
The data a "pointer" points to can be allocated as if the <tt>allocatable</tt> attribute were specified.
 
<langsyntaxhighlight lang="fortran">integer, dimension(:), pointer :: array
allocate(array(100))</langsyntaxhighlight>
 
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.
Line 705 ⟶ 791:
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)
 
<langsyntaxhighlight lang="fortran">integer, target :: i
integer, pointer :: pi
!... ...
if ( associated(pi, target=i) ) !...</langsyntaxhighlight>
 
Associating pointer to an array could help accessing the data of the array in a different manner.
 
<langsyntaxhighlight lang="fortran">real, dimension(20), target :: a
real, dimension(20,20), target :: b
real, dimension(:), pointer :: p
Line 719 ⟶ 805:
! p(1) == a(5), p(2) == a(6) ...
p => b(10,1:20)
! p(1) == b(10,1), p(2) == b(10,2) ...</langsyntaxhighlight>
 
Which is different of course from having e.g.
 
<langsyntaxhighlight lang="fortran">real, dimension(20) :: a
real, dimension(16) :: p
 
p = a(5:20)</langsyntaxhighlight>
 
In order to create arrays of pointers, the only way is to define a new type:
 
<langsyntaxhighlight lang="fortran">type intpointer
integer, pointer :: p
end type intpointer
 
!...
type(intpointer), dimension(100) :: parray</langsyntaxhighlight>
 
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.
Line 744 ⟶ 830:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Type Cat
Line 790 ⟶ 876:
' print them out
Print "i ="; i, "j ="; j
Sleep</langsyntaxhighlight>
 
{{out}}
Line 805 ⟶ 891:
Short of restrictions though, <tt>*</tt> and <tt>&</tt> are used much as they are in C.
 
<langsyntaxhighlight 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</langsyntaxhighlight>
 
The zero value of a pointer is called nil. Dereferencing a nil pointer, as in the example above, causes a run-time panic.
Line 812 ⟶ 898:
Some go types contain pointers in their internal representation and are called reference types. For example, slices, maps, and channels are always reference types.
 
<syntaxhighlight lang ="go">var m map[string]int</langsyntaxhighlight>
 
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.
 
<langsyntaxhighlight lang="go">m := make(map[string]int)</langsyntaxhighlight>
 
Built-in function make allocates and constructs the internal representation and returns a map object ready to use.
Line 822 ⟶ 908:
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
 
<langsyntaxhighlight lang="go">b := []byte(“hello world”)
c := b
c[0] = 'H'
fmt.Println(string(b))</langsyntaxhighlight>
Output:
<pre>
Line 832 ⟶ 918:
Go's garbage collector is aware of references created by taking the address of an object.
 
<langsyntaxhighlight lang="go">func three() *int {
i := 3
return &i // valid. no worry, no crash.
}</langsyntaxhighlight>
 
Because of this, a common syntax for allocating a struct is to use & with a literal:
 
<langsyntaxhighlight lang="go">type pt struct {
x, y int
}
 
return &pt{22, 79} // allocates a pt object and returns a pointer to it.</langsyntaxhighlight>
 
=={{header|Haskell}}==
Line 851 ⟶ 937:
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:
 
<langsyntaxhighlight lang="haskell">
import Data.STRef
 
Line 859 ⟶ 945:
k <- readSTRef p
writeSTRef p (k+1)
</syntaxhighlight>
</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'.
Line 880 ⟶ 966:
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:
 
<langsyntaxhighlight lang="java"> public class Foo { public int x = 0; }
 
void somefunction() {
Line 888 ⟶ 974:
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"
}</langsyntaxhighlight>
 
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.
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
'''Also works with fq, a Go implementation of a large subset of jq'''
 
In the context of JSON, "JSON Pointer" usually refers to RFC 6901,
which defines a string format for accessing values from a JSON document
in an analogous manner as XPath defines a mechanism for accessing values from an XML document.
 
jq has no built-in support for JSON Pointer as it already provides an analogous mechanism
based on paths expressed as arrays. Specifically, a JSON array of strings and integers can be used to specify
a path, $p, and jq provides a function `getpath($p)` for accessing the value at the given path, $p.
 
In this entry, we will use the term "JSON pointer" to refer to either a JSON Pointer string, or a jq array path.
 
Neither JSON nor jq provides a mechanism for handling embedded JSON pointers, but a common convention
is to use a JSON object with a key named "$ref" as a reference. We will adopt this convention here,
as illustrated by the following JSON document:
 
<pre>
[
{
"name": "John",
"birthplace": "London"
},
{
"name": "Jim",
"birthplace": "Paris",
"father": {
"$ref": "/0"
}
}
]
</pre>
 
In the following, we extend jq's support for array paths to JSON pointers, and
add functionality for dereferencing "$ref" values, whether expressed as
array paths or JSON Pointer values.
 
Thus we will be able to write expressions such as:
<pre>
deref([1, "father"])
deref( "/1/father" )
</pre>
to retrieve the details concerning Jim's father.
 
We shall also ensure that deref can be used with jq's native query capabilities:
<pre>
deref( .[1]["father"] )
deref( .[1] | .father )
</pre>
 
'''Library'''
<syntaxhighlight lang=jq>
# Convert a jq array path to a JSON Pointer
def jsonpointer:
def encode: gsub("~"; "~0") | gsub("/"; "~1");
reduce .[] as $x
("";
if ($x|type) == "string" then "\(.)/\($x|encode)"
else . + "/\($x)" end );
 
# Is the input syntactically a jq array path?
def isarraypath:
type == "array" and
all(.[]; type == "string" or (type == "number" and floor == .));
 
# The JSON Pointer spec allows 0 both for indexing an array and for retrieving a key named "0".
# disambiguate($k) accordingly disambiguates $k w.r.t. `.`.
# $k should be a string or integer.
# If $k is a string and . is an object then: if has($k) then $k else null end.
# If $k is an integer and . is an array, then emit $k.
# If $k is an integer-valued string and . is an array then exit $k|tonumber.
# Otherwise emit null
def disambiguate( $k ):
if ($k|type) == "string"
then if type == "object" then $k
elif type == "array" and ($k|test("^[0-9]+$"))
then ($k|tonumber)
else null
end
elif ($k|type) == "number" and type == "array"
then $k
else null
end;
 
# $array should be an array of strings and integers.
# Emit the disambiguated array, suitable for running getpath/1.
# Emit null if disambiguation fails at any point.
def disambiguatePath($array):
. as $in
| reduce $array[] as $x ([];
if . then . as $path
| ($in | getpath($path) | disambiguate($x)) as $y
| if $y then . + [ $y ]
else null
end
else .
end);
 
# getjsonpointer() is like getpath() but for jsonpointer pointers
def getjsonpointer($pointer):
if $pointer == "" then . # special case
else
# first decode ~1, then ~0
($pointer | split("/") | .[1:]
| map(gsub("~1"; "/") | gsub("~0"; "~"))) as $array
| disambiguatePath($array) as $apath
| if $apath then getpath($apath) else null end
end;
 
# like getpath() but allow $p to be a jsonpointer or an array
def getpointer($p):
if ($p|type) == "string" then getjsonpointer($p)
elif ($p|isarraypath) then getpath($p)
else $p
end;
# dereference $pointer, but not recursively.
# $pointer can be a jsonpointer pointer, or a jq array path,
# but one can also call deref(query) where `query` is a jq query yielding a $ref object.
def deref($pointer):
def resolve($x):
if ($x | type) == "object"
then $x["$ref"] as $ref
| if $ref then getpointer($ref)
else $x
end
else $x
end;
 
if ($pointer|type) == "string"
then resolve(getpointer($pointer))
elif ($pointer|isarraypath)
then resolve(getpath($pointer))
else resolve($pointer)
end;
</syntaxhighlight>
'''Examples'''
These examples correspond to the John/Jim JSON document shown above.
In each case, the result would be "John".
<pre>
getpointer("/0/name") # JSON Pointer
 
getpointer([0, "name"] ) # array path
 
deref("/1/father").name # JSON Pointer
 
deref([1,"father"] ).name # array path
 
deref(.[1]["father"] ).name # jq query
 
deref(.[1] | .father).name # jq query
 
deref(.[] | select(.name == "Jim").father ).name # jq query
</pre>
 
=={{header|Julia}}==
Line 896 ⟶ 1,140:
 
Julia's C interface pointer functions are considered "unsafe" because, like C pointers, they may cause data corruption if used incorrectly.
<langsyntaxhighlight lang="julia">x = [1, 2, 3, 7]
 
parr = pointer(x)
Line 903 ⟶ 1,147:
 
println(xx) # Prints 7
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 929 ⟶ 1,173:
 
The following example may help to make some of this clear. Although the Kotlin types have been specified to help with this, in practice they would usually be omitted and inferred by the compiler.
<langsyntaxhighlight lang="scala">// Kotlin Native v0.3
 
import kotlinx.cinterop.*
Line 967 ⟶ 1,211:
println(intArray[2]) // print the last element
nativeHeap.free(intArray) // free native memory
}</langsyntaxhighlight>
 
Sample output:
Line 988 ⟶ 1,232:
=={{header|Lua}}==
Lua does not have pointers but it is worth remembering that assigning a table to a new variable creates a reference to that table, not a copy of it.
<langsyntaxhighlight Lualang="lua">local table1 = {1,2,3}
local table2 = table1
table2[3] = 4
print(unpack(table1))</langsyntaxhighlight>
{{out}}
<pre>1 2 4</pre>
Line 1,001 ⟶ 1,245:
Read Statement get a weak reference and make it a normal reference. Variable X can't get new reference. We can't get reference from an item in a container (array, inventory, stack)
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
A=10
Module Beta {
Line 1,009 ⟶ 1,253:
Beta &A
Print A=11
</syntaxhighlight>
</lang>
 
====Reference for Functions/lambdas====
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module TestFuncRef {
Function Alfa(x) {
Line 1,045 ⟶ 1,289:
}
TestFuncRef
</syntaxhighlight>
</lang>
 
===Weak Reference using Strings===
Every time we use the string as weak reference, interpreter make resolve to reference. See point after $, A weak reference can be change any time. We can pass array items using Weak$() to get the right reference.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
A=10
Dim A(10)=1
Line 1,060 ⟶ 1,304:
Beta Weak$(A(2))
Print A(2)=2
</syntaxhighlight>
</lang>
 
===Pointer of Com Object===
We can declare objects (Com type) and we get a pointer, but that pointer leave until the end of module, which we create the pointer. We may declare properties for these objects, and also that properties use smart pointers, so the com object has only one pointer, which deleted at the exit of module (where created). Com objects are internal GUI objects. We use Method to call methods and return values. We can use With to read, set values, and to bound properties to names. In the example below we make Title$ as property "Title" of form Form1. We can use Nothing to delete objects (names can't get another object), it is optional, but has to do with the release of resource, and when happen. For forms it is better to use it as in the example below.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module ShowModalFormWithCLock {
Declare Form1 Form
Line 1,075 ⟶ 1,319:
}
ShowModalFormWithCLock
</syntaxhighlight>
</lang>
 
===Pointer of Container===
There are three containers, Arrays, Inventories and Stacks. Arrays have two interfaces, the value one and the pointer one. The value one has parenthesis in the name. Containers may have items other containers. Usually containers combined with functions and statements, but because they are COM objects (but pointers inside work different from other Com objects), we can use statemends Method and With as for com objects.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckArray {
\\ This is a value type array
Line 1,106 ⟶ 1,350:
}
CheckArray
</syntaxhighlight>
</lang>
===Pointers of Groups===
Groups are value types, but we can make pointers for them. Assigning a Group to a Group we get a combination, the group at the left get all the members of the group at the right (except the situation we have define a Set function for Group, and handle the assignment as we wish, or not defined it but define a value function so interpreter treat it as read only and throw error).
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module GroupPointers {
Group Zeta {
Line 1,144 ⟶ 1,388:
}
GroupPointers
</syntaxhighlight>
</lang>
====Reference of members of Groups====
We can pass reference from group members, if group has a name.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckGroupRef {
Group TestMe {
Line 1,186 ⟶ 1,430:
}
CheckGroupRef
</syntaxhighlight>
</lang>
 
=={{header|Modula-3}}==
Line 1,192 ⟶ 1,436:
 
Here is an example of a traced reference to an integer.
<langsyntaxhighlight lang="modula3">TYPE IntRef = REF INTEGER;
 
VAR intref := NEW(IntRef);
 
intref^ := 10</langsyntaxhighlight>
 
The <tt>^</tt> character is the dereference operator, and is suffixed to the reference variable name.
Line 1,205 ⟶ 1,449:
===REFANY===
The built-in type <tt>REFANY</tt> is of type <tt>REF T</tt>, which is the "root" reference type, and can be a reference of any type.
<langsyntaxhighlight lang="modula3">VAR any: REFANY;
any := NEW(REF INTEGER); (* Modula-3 knows that any is now REF INTEGER with a tag added by NEW. *)</langsyntaxhighlight>
 
===TYPECASE===
To determine the type of a variable, you can use <tt>TYPECASE</tt>.
<langsyntaxhighlight lang="modula3">PROCEDURE Sum(READONLY a: ARRAY OF REFANY): REAL =
VAR sum := 0.0;
BEGIN
Line 1,222 ⟶ 1,466:
END;
RETURN sum;
END Sum;</langsyntaxhighlight>
 
=={{header|Nim}}==
Line 1,228 ⟶ 1,472:
 
Create a safe reference:
<langsyntaxhighlight lang="nim">type Foo = ref object
x, y: float
 
var f: Foo
new f</langsyntaxhighlight>
 
Accessing the reference:
<syntaxhighlight lang ="nim">echo f[]</langsyntaxhighlight>
 
When accessing values the dereference operator [] can be left out:
<langsyntaxhighlight lang="nim">echo f[].x
f[].y = 12
echo f.y
f.x = 13.5</langsyntaxhighlight>
 
Create an (unsafe) pointer to an int variable:
<langsyntaxhighlight lang="nim">var x = 3
var p = addr x</langsyntaxhighlight>
 
Access the integer variable through the pointer:
<langsyntaxhighlight lang="nim">echo p[]
p[] = 42</langsyntaxhighlight>
 
Change the pointer to refer to another object:
<langsyntaxhighlight lang="nim">var y = 12
p = addr y</langsyntaxhighlight>
 
Change the pointer to not point to any object:
<langsyntaxhighlight lang="nim">p = nil</langsyntaxhighlight>
 
=={{header|OCaml}}==
Line 1,264 ⟶ 1,508:
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:
 
<langsyntaxhighlight 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 *)
</syntaxhighlight>
</lang>
 
(The OCaml web-site provides this [http://caml.inria.fr/resources/doc/guides/pointers.en.html page] on the subject.)
Line 1,287 ⟶ 1,531:
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:
 
<langsyntaxhighlight lang="oorexx">
::class Foo
::method init
Line 1,299 ⟶ 1,543:
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
</syntaxhighlight>
</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.
<br>
<br>With the Use Arg instruction, a subroutine get access to the caller's argument object by reference:
<langsyntaxhighlight lang="oorexx">a.='not set'
a.3=3
Say 'Before Call sub: a.3='a.3
Line 1,323 ⟶ 1,567:
Say 'in sub2: a.='a.
Say 'in sub2: a.3='a.3 -- this changes the local a.
Return</langsyntaxhighlight>
{{out}}
<pre>Before Call sub: a.3=3
Line 1,333 ⟶ 1,577:
=={{header|PARI/GP}}==
Some built-in functions like <code>issquare</code> have pointer arguments:
<langsyntaxhighlight lang="parigp">n=1;
issquare(9,&n);
print(n); \\ prints 3</langsyntaxhighlight>
 
{{Works with|PARI/GP|2.12.0}}
User functions and certain built-in functions (listput, listpop, mapput, etc.; all those with [http://pari.math.u-bordeaux.fr/dochtml/html-stable/usersch5.html#GP-prototypes-parser-codes parser code] W) can take arguments by reference with the prefix ~ operator:
<langsyntaxhighlight lang="parigp">boxit(~L, x)=listput(L, x);
S=List();
boxit(S,1);
S</langsyntaxhighlight>
{{out}}
<pre>1</pre>
Line 1,349 ⟶ 1,593:
 
=={{header|Pascal}}==
''See also [[Pointers_and_references#Delphi | Delphi]]''
 
Pascal does not support pointer operations on the stack.
In fact, Pascal does not even “know” there is a stack.
<syntaxhighlight lang="pascal">program pointerDemo;
 
type
{
A new pointer data type is declared by `↑` followed by a data type name,
the domain.
The domain data type may not have been declared yet, but must be
declared within the current `type` section.
Most compilers do not support the reference token `↑` as specified in
the ISO standards 7185 and 10206, but use the alternative `^` (caret).
}
integerReference = ^integer;
 
var
integerLocation: integerReference;
 
begin
{
The procedure `new` taken one pointer variable and allocates memory for
one new instance of the pointer domain’s data type (here an `integer`).
The pointer variable will hold the address of the allocated instance.
}
new(integerLocation);
{
Dereferencing a pointer is done via appending `↑` to the variable’s
name. All operations on the domain type are now possible.
}
integerLocation^ := 42;
{
The procedure `dispose` takes one pointer variable and releases the
underlying memory. The supplied variable is otherwise not modified.
}
dispose(integerLocation);
{
In Pascal, `dispose` is not necessary. Any excess memory is automatically
released after `program` termination.
}
end.</syntaxhighlight>
Furthermore, <tt>new</tt> and <tt>dispose</tt> accept further parameters if the pointer variable’s domain type is a variant <tt>record</tt> (or, in Extended Pascal, a schema).
This permits the processor to allocate memory merely for the specified variant (or, in Extended Pascal, a discriminant), but also forbids you to change the variant (of a <tt>record</tt>).
It is imperative the selectors in <tt>dispose</tt> match to the corresponding <tt>new</tt>.
<syntaxhighlight lang="pascal">program variantRecordDemo;
 
type
fooReference = ^foo;
foo = record
case Boolean of
false: ( );
true: (location: fooReference);
end;
var
head: fooReference;
begin
new(head, true);
{ … }
dispose(head, true);
end.</syntaxhighlight>
As a special case of pointers, functions and procedures can be passed as parameters to routines.
<syntaxhighlight lang="pascal">program routineParameterDemo(output);
 
procedure foo(function f: Boolean);
begin
writeLn(f);
end;
 
function bar: Boolean;
begin
bar := false
end;
 
begin
foo(bar);
end.</syntaxhighlight>
 
=={{header|Perl}}==
Line 1,356 ⟶ 1,681:
Perl has "references" that roughly correspond with "smart pointers" of C-like languages. Due to reference-counting semantics, they can never point to something that does not exist. Any scalar container (which includes array elements and hash values, but not hash keys) can hold a reference to a data structure.
 
<langsyntaxhighlight lang="perl"> # start with some var definitions
my $scalar = 'aa';
my @array = ('bb', 'cc');
Line 1,364 ⟶ 1,689:
my $scalarref = \$scalar;
my $arrayref = \@array;
my $hashref = \%hash;</langsyntaxhighlight>
 
Using a reference
 
<langsyntaxhighlight lang="perl"> # accessing the value
print $$scalarref; # 'aa'
print @$arrayref; # 'bbcc'
Line 1,377 ⟶ 1,702:
$$scalarref = 'a new string'; # changes $scalar
$arrayref->[0] = 'foo'; # changes the first value of @array
$hashref->{'dd'} = 'bar'; # changes the value with key 'dd' in %hash</langsyntaxhighlight>
 
You may also create anonymous references:
 
<langsyntaxhighlight lang="perl"> my $scalarref = \'a scalar';
my $arrayref = ['an', 'array'];
my $hashref = { firstkey => 'a', secondkey => 'hash' }</langsyntaxhighlight>
 
=={{header|Phix}}==
Phix does not have pointers, other than for playing with raw allocated memory, typically for interfacing with another language pre-compiled into a dll/so, although for that builtins/cffi.e offers a more grown-up mechanism with seamless 32/64 bit portability. There is no pointer math beyond sizes in bytes.
 
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (assumes 32 bit)</span>
<span style="color: #7060A8;">poke4</span><span style="color: #0000FF;">(</span><span style="color: #000000;">addr</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span><span style="color: #000000;">SOME_CONSTANT</span><span style="color: #0000FF;">})</span>
Line 1,394 ⟶ 1,719:
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">peek4s</span><span style="color: #0000FF;">({</span><span style="color: #000000;">addr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- prints {x,y}</span>
<span style="color: #7060A8;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">addr</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
 
There are in fact 5 variants of poke: poke1, poke2, poke4, poke8, and pokeN which allows the size to be dynamically specified.
Line 1,403 ⟶ 1,728:
 
You can, of course use pointers via inline assembly (but only as a last resort/if you are mental enough):
<langsyntaxhighlight Phixlang="phix">atom mypi
#ilASM{
fldpi
Line 1,411 ⟶ 1,736:
lea rdi,[mypi]
[]
call :%pStoreFlt }</langsyntaxhighlight>
or
<langsyntaxhighlight Phixlang="phix">string mystring = "mystring"
#ilASM{
[32]
Line 1,422 ⟶ 1,747:
lea rsi,[rbx+rsi*4] -- byte[rsi] is 'm'
[]
}</langsyntaxhighlight>
Of course in a reference counted language like Phix, playing directly with the innards like that may have dire unexpected side effects.
Line 1,428 ⟶ 1,753:
Phix does not have references, however everything is passed by reference, with copy-on-write semantics. Unless the source and destination are the same, and it is local, so it cannot possibly be referenced elsewhere, in which case automatic pass-by-reference is used, which for Phix means skipping the reference counting. For example:
 
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span>
<span style="color: #0000FF;">...</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">myfunc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
 
It is a general optimisation, applied by the complier whenever and wherever it can, without the programmer having to do anything special.
Line 1,447 ⟶ 1,772:
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.
 
<langsyntaxhighlight lang="php"><?php
/* Assignment of scalar variables */
$a = 1;
Line 1,474 ⟶ 1,799:
pass_in($tmp); // changes $tmp and prints the length
 
?></langsyntaxhighlight>
 
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.
Line 1,505 ⟶ 1,830:
'[http://software-lab.de/doc/refN.html#nth nth]', which advance the pointer to
the next (linked to) location(s).
<langsyntaxhighlight PicoLisplang="picolisp">: (setq L (1 a 2 b 3 c)) # Create a list of 6 items in 'L'
-> (1 a 2 b 3 c)
 
Line 1,515 ⟶ 1,840:
 
: L # Look at the modified list in 'L'
-> (1 a 2 "Hello" 3 c)</langsyntaxhighlight>
 
=={{header|PL/I}}==
Line 1,523 ⟶ 1,848:
* control statements: ALLOCATE, FREE
Simple examples:
<langsyntaxhighlight lang="pli">
dcl i fixed bin(31);
dcl p pointer;
Line 1,546 ⟶ 1,871:
p=addr(i1); t=addr(i2), q=addr(p); s=addr(t);
q->p->j = s->t->k + 3; /* to say i1=i2+3 */
</syntaxhighlight>
</lang>
 
=={{header|Pop11}}==
Line 1,590 ⟶ 1,915:
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:
<langsyntaxhighlight PureBasiclang="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</langsyntaxhighlight>
Change pointer to refer to another integer variable:
<langsyntaxhighlight PureBasiclang="purebasic">Define varC.i = 12
*myInteger = @varC</langsyntaxhighlight>
Change pointer to not point to anything:
<langsyntaxhighlight PureBasiclang="purebasic">*myInteger = #Null ;or anything evaluating to zero</langsyntaxhighlight>
Get a pointer to the first element of an array, or any desired element:
<langsyntaxhighlight PureBasiclang="purebasic">Dim myArray(10)
*myInteger = myArray()
;Or alternatively:
*myInteger = @myArray(0)
;any specific element
*myInteger = @myArray(4) ;element 4</langsyntaxhighlight>
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 <tt>SizeOf()</tt>.
<langsyntaxhighlight PureBasiclang="purebasic">*myInteger + 3 * SizeOf(Integer) ;pointer now points to myArray(3)
*myInteger - 2 * SizeOf(Integer) ;pointer now points to myArray(1)</langsyntaxhighlight>
In a similar manner the compiler function <tt>OffsetOf()</tt> may also be used to obtain the memory offset for an sub-element of a structure if needed:
<langsyntaxhighlight PureBasiclang="purebasic">Structure employee
id.i
name.s
Line 1,619 ⟶ 1,944:
 
;set a string pointer to the 6th job of the 4th employee
*myString.String = @employees(3) + OffsetOf(employee\jobs) + 5 * SizeOf(String)</langsyntaxhighlight>
===Addresses of variables or procedure===
Addresses to variables and functions are obtained with the '@' operator.
<langsyntaxhighlight PureBasiclang="purebasic">*pointer = @varA
*pointer = @myFunction()</langsyntaxhighlight>
===Addresses of labels===
To find the address of a label, you put a question mark (?) in front of the label name.
<langsyntaxhighlight PureBasiclang="purebasic">; Getting the address of a lable in the code
text$="'Lab' is at address "+Str(?lab)
MessageRequester("Info",text$)
Line 1,645 ⟶ 1,970:
Data.i 3,1,4,5,9,2,1,6
lab2:
EndDataSection</langsyntaxhighlight>
 
=={{header|Python}}==
Line 1,651 ⟶ 1,976:
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").
 
<langsyntaxhighlight lang="python"> # Bind a literal string object to a name:
a = "foo"
# Bind an empty list to another name:
Line 1,682 ⟶ 2,007:
# 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.</langsyntaxhighlight>
 
[Note: in some ways this task is meaningless for Python given the nature of its "variable" binding semantics].
Line 1,689 ⟶ 2,014:
 
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:
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,699 ⟶ 2,024:
(inc! b)
(unbox b) ; => 3
</syntaxhighlight>
</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.
Line 1,707 ⟶ 2,032:
In Raku 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 <tt>:=</tt> 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.)
 
<syntaxhighlight lang="raku" perl6line>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.
Line 1,719 ⟶ 2,044:
 
@bar := (1,2,3); # bind name directly to a List
@bar»++; # ERROR, parcels are not mutable</langsyntaxhighlight>
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.
 
Line 1,730 ⟶ 2,055:
 
=={{header|SAS}}==
<langsyntaxhighlight 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;
Line 1,742 ⟶ 2,067:
call poke(b,adr_c,1);
put a b c;
run;</langsyntaxhighlight>
 
=={{header|Scala}}==
Line 1,755 ⟶ 2,080:
Shale pointers must point to a Shale object, effected by the pointer assignment operator (&=). Referencing the objected pointed to is done with the dereference operator (->).
 
<langsyntaxhighlight Shalelang="shale">#!/usr/local/bin/shale
 
aVariable var // Create aVariable
Line 1,777 ⟶ 2,102:
 
// Shale pointers can point to any Shale object, like numbers, strings, variables
// and code fragments.</langsyntaxhighlight>
 
{{out}}
Line 1,789 ⟶ 2,114:
=={{header|Sidef}}==
A simple example of passing a variable-reference to a function:
<langsyntaxhighlight lang="ruby">func assign2ref(ref, value) {
*ref = value;
}
Line 1,795 ⟶ 2,120:
var x = 10;
assign2ref(\x, 20);
say x; # x is now 20</langsyntaxhighlight>
 
=={{header|Standard ML}}==
Line 1,801 ⟶ 2,126:
Like OCaml, Standard ML doesn't have pointers but have a "ref" mutable data structure which is the basis of mutability in Standard ML:
 
<langsyntaxhighlight 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 *)
</syntaxhighlight>
</lang>
 
=={{header|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.:
<langsyntaxhighlight 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</langsyntaxhighlight>
In practice it's safer and more convenient to use array keys or the <tt>upvar</tt> command, e.g.:
<langsyntaxhighlight lang="tcl">set arr(var) 3
set pointer var
set arr($pointer); # returns 3
Line 1,823 ⟶ 2,148:
set pointer var
upvar 0 $pointer varAlias; # varAlias is now the same variable as var
set varAlias 42; # var now has value 42</langsyntaxhighlight>
This second technique is most commonly used between stack levels (i.e., with the first argument to <tt>upvar</tt> being 1) so that a local variable of one procedure can be manipulated in another utility procedure that it calls.
 
Line 1,866 ⟶ 2,191:
=={{header|VBA}}==
Formally VBA does not have pointers or references. Objects are created with the "New" keyword, and assignments require the keyword "Set". Getting the memory address of a pointer is not documented in VBA.
<langsyntaxhighlight lang="vb">Dim samplevariable as New Object
Dim anothervariable as Object
Set anothervariable = sameplevariable</langsyntaxhighlight>
 
=={{header|Wren}}==
Line 1,878 ⟶ 2,203:
 
The following example illustrates the difference by passing both value and reference type parameters to a function. Note that in Wren parameters are always passed by value.
<langsyntaxhighlight ecmascriptlang="wren">// This function takes a string (behaves like a value type) and a list (reference type).
// The value and the reference are copied to their respective parameters.
var f = Fn.new { |s, l|
Line 1,893 ⟶ 2,218:
f.call(s, l)
System.print(l)
System.print(s)</langsyntaxhighlight>
 
{{out}}
Line 1,902 ⟶ 2,227:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">\Paraphrasing the C example:
\This creates a pointer to an integer variable:
int Var, Ptr, V;
Line 1,933 ⟶ 2,258:
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)
]</langsyntaxhighlight>
 
=={{header|Z80 Assembly}}==
Pointers can be used in several different ways on the Z80.
As with nearly all assembly languages, the Z80 does not enforce data types (except byte vs word). This means that a 16-bit integer in a register pair can be used as a pointer at any time. A value in <code>HL</code>, <code>BC</code>, <code>DE</code>, <code>IX</code>, or <code>IY</code> can be temporarily treated as a pointer by enclosing it in brackets. In addition, the accumulator can load from or store to a constant pointer.
 
<syntaxhighlight lang="z80">ld a,(&C000) ;load the accumulator with the value from the memory address &C000.
 
ld hl,&D000
ld e,(hl) ;load the E register with the byte at memory address &D000.
 
ld bc,(&E000) ;load the register pair BC from memory address &E000. The Game Boy cannot use this addressing mode.
; This is the same as:
; ld a,(&E000)
; ld c,a
; ld a,(&E001)
; ld b,a
 
ld IX,&F000
ld a,(IX+3) ;load A with the byte stored at &F003, The Game Boy cannot use this addressing mode.</syntaxhighlight>
 
Keep in mind that <code>HL</code>, <code>IX</code>, and <code>IY</code> are more flexible in the valid addressing modes that can be used.
Below are examples of code that are '''not valid''' and will be rejected by your assembler (regardless of whether you are programming on a "real" Z80 or a Game Boy)
 
<syntaxhighlight lang="z80">ld h,(bc) ;if (bc) or (de) is the operand of a LD command, the other operand must be A.
ld e,(&A000) ;if a constant pointer is the operand of a LD command, the other operand must be A.</syntaxhighlight>
 
 
In addition, <code>(HL)</code>, <code>(IX+n)</code>, and <code>(IY+n)</code> can be used with most commands that work with 8-bit register operands. (n is a signed, constant offset.) Some examples include:
 
<syntaxhighlight lang="z80">inc (HL) ;increment the byte pointed to by HL
rrc (IX+5) ;take the byte pointed to by IX+5 and rotate it right. The value of IX is unchanged.
sub (IY-23) ;subtract the value of the byte that is 23 bytes before IY, from A.
;The value of that byte at that address is unchanged, as is IY.</syntaxhighlight>
 
 
Pointers that point to other pointers are a little tricky to dereference on the Z80. It's very difficult to do this without using a second register pair to hold the pieces temporarily.
 
<syntaxhighlight lang="z80">ld hl,PointerTable
ld e,(hl)
inc hl
ld d,(hl)
; depending on what we need to do next, we might need this new pointer back in HL. There are a few ways to do this:
; ex de,hl
 
; push de
; pop hl
 
; ld L,E
; ld H,D</syntaxhighlight>
 
 
If you're able to use self-modifying code you can get away with using fewer registers, provided you know what the bytecode should look like:
 
<syntaxhighlight lang="z80">ld hl,PointerTable
ld a,(hl)
ld (SMC+1),a ;SMC+1 points to low byte of the operand
 
inc hl ;increment HL so we can fetch the high byte
 
ld a,(hl)
ld (SMC+2),a ;SMC+2 points to high byte of the operand
 
SMC:
ld a,&BEEF ;gets overwritten with the pointer stored in entry 0 of PointerTable.</syntaxhighlight>
 
 
Making a new reference to an existing object is a common practice for when another function needs to use a value you looked up recently.
<syntaxhighlight lang="z80">ld hl,PointerTable
ld a,(index)
add a ;this is a table of 16-bit values so double our index
add L
ld L,a
ld a,H
adc 0
ld H,a ;offset HL by our index
 
 
ld e,(hl)
inc hl
ld d,(hl) ;get the Ath entry of PointerTable and store it into DE.
 
ld (referenceStorage),DE ;store DE into ram for later use as a reference.</syntaxhighlight>
 
=={{header|zkl}}==
Pointers don't exist and neither do conventional references but mutable containers can act like references: List, Ref (strong reference), GarbageMan.WeakRef (weak reference) and others.
<langsyntaxhighlight lang="zkl">fcn f(r){r.inc()} r:= Ref(1); f(r); r.value; //-->2</langsyntaxhighlight>
A Ref can hold any value. inc is a special case convenience for numbers.
<langsyntaxhighlight lang="zkl">fcn f(lst){lst.append(5)} f(L()); //-->L(5)</langsyntaxhighlight>
Weak refs can hold anything the garbage collect can see. You can only look at the value, not change it. If it should hold a Ref or List, you can change those. The contents of a Weak Ref will vaporize sometime after the contents are no longer visible.
 
162

edits