Pointers and references: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 2: Line 2:
=={{header|6502 Assembly}}==
=={{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:
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:
<lang 6502asm>LDA 8 ;load the byte stored at memory address 0x0008 into the accumulator.
<syntaxhighlight lang="6502asm">LDA 8 ;load the byte stored at memory address 0x0008 into the accumulator.
LDA #8 ;load the number 8 into the accumulator.</lang>
LDA #8 ;load the number 8 into the accumulator.</syntaxhighlight>


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


<lang 6502asm>LDX $2000 ;load the byte at memory address $2000 into X.
<syntaxhighlight lang="6502asm">LDX $2000 ;load the byte at memory address $2000 into X.
LDY $75 ;load the byte at memory address $0075 into Y. This instruction executes faster than the one above it.</lang>
LDY $75 ;load the byte at memory address $0075 into Y. This instruction executes faster than the one above it.</syntaxhighlight>


===Pointers on the stack===
===Pointers on the stack===
{{works with|65c02}}
{{works with|65c02}}
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:
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:
<lang 6502asm>TSX
<syntaxhighlight lang="6502asm">TSX
LDA $0101,X ;load the byte most recently pushed on the stack into A without pulling it off the stack.</lang>
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.)
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.)
<lang C>inline unsigned char foo (unsigned char a, unsigned char b, unsigned char c){
<syntaxhighlight lang="c">inline unsigned char foo (unsigned char a, unsigned char b, unsigned char c){
return a+b+c;
return a+b+c;
}</lang>
}</syntaxhighlight>


<lang 6502asm>LDA #arg_C ;load whatever this value is into accumulator
<syntaxhighlight lang="6502asm">LDA #arg_C ;load whatever this value is into accumulator
PHA
PHA
LDA #arg_B
LDA #arg_B
Line 38: Line 38:
ADC $0104,X ;ADC #arg_A
ADC $0104,X ;ADC #arg_A
;we have the desired value in A, now return.
;we have the desired value in A, now return.
PLX</lang>
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.
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.
Line 44: Line 44:
===Pointer arithmetic===
===Pointer arithmetic===
The 6502 can offset pointers up to 255 bytes forwards.
The 6502 can offset pointers up to 255 bytes forwards.
<lang 6502asm>LDX #$80
<syntaxhighlight lang="6502asm">LDX #$80
LDA $2000,X ;load the byte stored at $2080
LDA $2000,X ;load the byte stored at $2080
LDY #$FF
LDY #$FF
LDA $2080,Y ;load the byte stored at $217F</lang>
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.
Note that when using zero-page addressing, this offsetting is always modulo 256, meaning there is no "carry" when offsetting, unlike with absolute addressing.


<lang 6502>LDX #$C0
<syntaxhighlight lang="6502">LDX #$C0
LDA $80,X ;load from $0040</lang>
LDA $80,X ;load from $0040</syntaxhighlight>


=={{header|8086 Assembly}}==
=={{header|8086 Assembly}}==
Line 57: Line 57:
===Pointers===
===Pointers===
In most assemblers, an instruction or a numeric value can be given a label.
In most assemblers, an instruction or a numeric value can be given a label.
<lang asm>.model small
<syntaxhighlight lang="asm">.model small
.stack 1024
.stack 1024
.data ; data segment begins here
.data ; data segment begins here
Line 70: Line 70:


mov ax, @code
mov ax, @code
mov es, ax</lang>
mov es, ax</syntaxhighlight>


<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.
<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 76: Line 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:
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:


<lang asm>mov ax,0FFFFh ;see note 1
<syntaxhighlight lang="asm">mov ax,0FFFFh ;see note 1
mov word ptr [ds:tempWord],ax ;store hexadecimal value FFFF into tempWord
mov word ptr [ds:tempWord],ax ;store hexadecimal value FFFF into tempWord


Line 84: Line 84:
;Note 1:
;Note 1:
;UASM doesn't like leading hex digits A-F so a 0 is placed in front.
;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)</lang>
;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)</syntaxhighlight>


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


<lang asm>mov ax, byte ptr [ds:tempByte] ;assembler will generate an error - operands don't match
<syntaxhighlight 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 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 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
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>
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:
Then this pointer can be loaded into a segment register and data register with a single command, like so:
<lang asm>LDS bx,UserRamPtr ;loads [ds:bx] with UserRamPtr</lang>
<syntaxhighlight lang="asm">LDS bx,UserRamPtr ;loads [ds:bx] with UserRamPtr</syntaxhighlight>


===Pointer Arithmetic===
===Pointer Arithmetic===


A pointer can be loaded into a register like any other value.
A pointer can be loaded into a register like any other value.
<lang asm>.data
<syntaxhighlight lang="asm">.data
myString db "Hello World!",0 ;the zero is the null terminator
myString db "Hello World!",0 ;the zero is the null terminator
.code
.code
mov bx, seg myString ;load into bx the segment where myString is stored.
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 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.</lang>
mov bx, offset MyString ;the memory address of the beginning of myString. The "H" is stored here.</syntaxhighlight>


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.
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.
<lang asm>add bx, 2 ;add 2 to bx. bx contains the memory address of the first "l" in "Hello"
<syntaxhighlight 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.</lang>
mov al,[ds:bx] ;dereference the pointer and store the value it points to into al.</syntaxhighlight>


=={{header|68000 Assembly}}==
=={{header|68000 Assembly}}==
Line 117: Line 117:
In most assemblers, a line of code or a value in work RAM can be given a label.
In most assemblers, a line of code or a value in work RAM can be given a label.


<lang 68000devpac>myVar equ $100000 ; a section of user ram given a label
<syntaxhighlight lang="68000devpac">myVar equ $100000 ; a section of user ram given a label
myData: ; a data table given a label
myData: ; a data table given a label
dc.b $80,$81,$82,$83</lang>
dc.b $80,$81,$82,$83</syntaxhighlight>


The <code>LEA</code> instruction can load the address of a given label.
The <code>LEA</code> 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.
This isn't needed for values in RAM, but it is needed for loading from data tables in ROM.


<lang 68000devpac>LEA myData,A0 ;address of myData is stored in A0</lang>
<syntaxhighlight lang="68000devpac">LEA myData,A0 ;address of myData is stored in A0</syntaxhighlight>


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.
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.
Line 130: Line 130:
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 loaded into <code>A0</code>, and that <code>D0</code> equaled 0x00000000 prior to the code below.
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 loaded into <code>A0</code>, and that <code>D0</code> equaled 0x00000000 prior to the code below.


<lang 68000devpac>MOVE.B (A0),D0 ;D0 = 0x00000080
<syntaxhighlight lang="68000devpac">MOVE.B (A0),D0 ;D0 = 0x00000080
MOVE.W (A0),D0 ;D0 = 0x00008081
MOVE.W (A0),D0 ;D0 = 0x00008081
MOVE.L (A0),D0 ;D0 = 0x80818283</lang>
MOVE.L (A0),D0 ;D0 = 0x80818283</syntaxhighlight>


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


<lang 68000devpac>LEA myData,A0 ;Assume for this example that data registers all equal 0.
<syntaxhighlight lang="68000devpac">LEA myData,A0 ;Assume for this example that data registers all equal 0.
MOVE.B (A0)+,D0 ;D0 = 00000080
MOVE.B (A0)+,D0 ;D0 = 00000080
MOVE.B (A0)+,D1 ;D1 = 00000081
MOVE.B (A0)+,D1 ;D1 = 00000081
MOVE.B (A0)+,D2 ;D2 = 00000082</lang>
MOVE.B (A0)+,D2 ;D2 = 00000082</syntaxhighlight>




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.''
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.''
<lang 68000devpac>LEA myData+4,A0 ;Assume for this example that data registers all equal 0.
<syntaxhighlight 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),D0 ;D0 = 00000083
MOVE.B -(A0),D1 ;D1 = 00000082
MOVE.B -(A0),D1 ;D1 = 00000082
MOVE.B -(A0),D2 ;D2 = 00000081</lang>
MOVE.B -(A0),D2 ;D2 = 00000081</syntaxhighlight>


<code>LEA</code> can also be used to pre-calculate a complex offset to an address.
<code>LEA</code> can also be used to pre-calculate a complex offset to an address.
<lang 68000devpac>LEA myData,A0
<syntaxhighlight lang="68000devpac">LEA myData,A0
MOVE.W #$0C,D0
MOVE.W #$0C,D0
LEA (4,A0,D0),A3 ;A3 = address of myData + 4 + $0C</lang>
LEA (4,A0,D0),A3 ;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:
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:


<lang 68000devpac>myPointers: dc.l myData, myData2
<syntaxhighlight lang="68000devpac">myPointers: dc.l myData, myData2
myData: dc.b $80,$81,$82,$83
myData: dc.b $80,$81,$82,$83
myData2: dc.b $84,$85,$86,$87
myData2: dc.b $84,$85,$86,$87
</syntaxhighlight>
</lang>


These two code snippets <i>are not the same</i>:
These two code snippets <i>are not the same</i>:
<lang 68000devpac>LEA myData2,A1</lang>
<syntaxhighlight lang="68000devpac">LEA myData2,A1</syntaxhighlight>


<lang 68000devpac>LEA myPointers,A1
<syntaxhighlight lang="68000devpac">LEA myPointers,A1
LEA (4,A1),A1</lang>
LEA (4,A1),A1</syntaxhighlight>


===Pointers on the stack===
===Pointers on the stack===
Line 171: Line 171:
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.
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.


<lang 68000devpac>;implements:
<syntaxhighlight lang="68000devpac">;implements:
;uint64_t foo (uint16_t a,uint16_t b,uint16_t c){return a+b+c;}
;uint64_t foo (uint16_t a,uint16_t b,uint16_t c){return a+b+c;}
MOVE.L #arg2,-(SP)
MOVE.L #arg2,-(SP)
Line 185: Line 185:
ADD.L (8,SP),D0
ADD.L (8,SP),D0
ADD.L (12,SP),D0
ADD.L (12,SP),D0
RTS</lang>
RTS</syntaxhighlight>


===References===
===References===


Labeled memory can be read/written to directly, unlike in ARM Assembly.
Labeled memory can be read/written to directly, unlike in ARM Assembly.
<lang 68000devpac>MOVE.B #$10,myVar</lang>
<syntaxhighlight lang="68000devpac">MOVE.B #$10,myVar</syntaxhighlight>


Unlike in C, pointers do not have to point to any specific type of data.
Unlike in C, pointers do not have to point to any specific type of data.
<lang 68000devpac>MOVE.L #$FFEEDDCC,myVar</lang>
<syntaxhighlight lang="68000devpac">MOVE.L #$FFEEDDCC,myVar</syntaxhighlight>


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 to/write from myVar.
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 to/write from myVar.
Line 202: Line 202:


Create a pool specific access type for an integer
Create a pool specific access type for an integer
<lang ada>type Int_Access is access Integer;
<syntaxhighlight lang="ada">type Int_Access is access Integer;
Int_Acc : Int_Access := new Integer'(5);</lang>
Int_Acc : Int_Access := new Integer'(5);</syntaxhighlight>
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.
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>
<syntaxhighlight lang="ada">type Safe_Int_Access is not null access Integer;</syntaxhighlight>
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
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
<syntaxhighlight lang="ada">declare
type Int_Ptr is access all Integer;
type Int_Ptr is access all Integer;
Ref : Int_Ptr;
Ref : Int_Ptr;
Line 213: Line 213:
Val : Integer := Var;
Val : Integer := Var;
begin
begin
Ref := Var'Access; -- "Ref := Val'Access;" would be a syntax error</lang>
Ref := Var'Access; -- "Ref := Val'Access;" would be a syntax error</syntaxhighlight>
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:
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>
<syntaxhighlight lang="ada">type Safe_Int_Ptr is not null access all Integer;</syntaxhighlight>


===Addresses===
===Addresses===
Ada does not provide pointer arithmetic, but does allow evaluation of the address
Ada does not provide pointer arithmetic, but does allow evaluation of the address
<lang ada>Var : Integer;
<syntaxhighlight lang="ada">Var : Integer;
Var_Address : Address := Var'Address;</lang>
Var_Address : Address := Var'Address;</syntaxhighlight>
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.
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
Ada allows the specification of a starting address for any object
<lang ada>-- Demonstrate the overlay of one object on another
<syntaxhighlight lang="ada">-- Demonstrate the overlay of one object on another
A : Integer;
A : Integer;
B : Integer;
B : Integer;
for B'Address use A'Address;
for B'Address use A'Address;
-- A and B start at the same address</lang>
-- A and B start at the same address</syntaxhighlight>
===References===
===References===
References in Ada are achieved through object renaming declarations. A renaming produces a new view to the object:
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;
<syntaxhighlight lang="ada">type Container is array (Positive range <>) of Element;
for I in Container'Range loop
for I in Container'Range loop
declare
declare
Line 238: Line 238:
Do_Something(Item); -- Here Item is a reference to Container (I)
Do_Something(Item); -- Here Item is a reference to Container (I)
end;
end;
end loop;</lang>
end loop;</syntaxhighlight>


The forthcoming standard (Ada 2012) allows a more direct way to reference all the items in a container or an array:
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;
<syntaxhighlight lang="ada">type Container is array (Positive range <>) of Element;
for Item of Container loop
for Item of Container loop
Do_Something(Item);
Do_Something(Item);
end loop;</lang>
end loop;</syntaxhighlight>


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


Line 267: Line 267:


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


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


Get a reference to the first element of an array:
Get a reference to the first element of an array:
<lang algol68>[9]INT array2;
<syntaxhighlight lang="algol68">[9]INT array2;
REF INT ref3 = array2[LWB array2];</lang>
REF INT ref3 = array2[LWB array2];</syntaxhighlight>
Changing the reference to refer to another object of the array is not possible.
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:
ALGOL 68 also allows pointers to slices of rows and/or columns of arrays:
<lang algol68>[9,9]INT sudoku;
<syntaxhighlight lang="algol68">[9,9]INT sudoku;
REF [,]INT middle;
REF [,]INT middle;
middle := sudoku[4:6,4:6];</lang>
middle := sudoku[4:6,4:6];</syntaxhighlight>


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


Line 297: Line 297:
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.
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.


<lang ARM Assembly>;this example uses VASM syntax, your assembler may not use the # before constants or the semicolon for comments
<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 R1,#0x04000000
MOV R0,#0x403
MOV R0,#0x403
STR R0,[R1] ;store 0x403 into memory address 0x04000000.</lang>
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.
The <code>STR</code> instruction is unusual in that its source is on the left and its destination on the right.
Line 308: Line 308:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
The address of the variable structure itself cannot be changed using built in methods.
The address of the variable structure itself cannot be changed using built in methods.
<lang AutoHotkey>VarSetCapacity(var, 100) ; allocate memory
<syntaxhighlight lang="autohotkey">VarSetCapacity(var, 100) ; allocate memory
NumPut(87, var, 0, "Char") ; store 87 at offset 0
NumPut(87, var, 0, "Char") ; store 87 at offset 0
MsgBox % NumGet(var, 0, "Char") ; get character at offset 0 (87)
MsgBox % NumGet(var, 0, "Char") ; get character at offset 0 (87)
MsgBox % &var ; address of contents pointed to by var structure
MsgBox % &var ; address of contents pointed to by var structure
MsgBox % *&var ; integer at address of var contents (87)</lang>
MsgBox % *&var ; integer at address of var contents (87)</syntaxhighlight>


=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
<lang bbcbasic> REM Pointer to integer variable:
<syntaxhighlight lang="bbcbasic"> REM Pointer to integer variable:
pointer_to_varA = ^varA%
pointer_to_varA = ^varA%
!pointer_to_varA = 123456
!pointer_to_varA = 123456
Line 341: Line 341:
DEF FNmyfunc
DEF FNmyfunc
= "Returned from myfunc"</lang>
= "Returned from myfunc"</syntaxhighlight>


=={{header|C}} and {{header|C++}}==
=={{header|C}} and {{header|C++}}==
The following code creates a pointer to an int variable
The following code creates a pointer to an int variable
<lang c>int var = 3;
<syntaxhighlight lang="c">int var = 3;
int *pointer = &var;</lang>
int *pointer = &var;</syntaxhighlight>


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


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


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


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


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


Access another object in the same array through the pointer
Access another object in the same array through the pointer
<lang c>v = pointer[3]; /* accesses third-next object, i.e. array[4] */
<syntaxhighlight lang="c">v = pointer[3]; /* accesses third-next object, i.e. array[4] */
v = pointer[-1]; /* accesses previous object, i.e. array[0] */
v = pointer[-1]; /* accesses previous object, i.e. array[0] */
/* or alternatively */
/* or alternatively */
v = *(pointer + 3); /* array[4] */
v = *(pointer + 3); /* array[4] */
v = *(pointer - 1); /* array[0] */</lang>
v = *(pointer - 1); /* array[0] */</syntaxhighlight>


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


<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>


Line 418: Line 418:
}
}
return i;
return i;
}</lang>
}</syntaxhighlight>


=={{header|c sharp|C#}}==
=={{header|c sharp|C#}}==
This example represents usage of Reference and Value.
This example represents usage of Reference and Value.
<lang csharp>
<syntaxhighlight lang="csharp">
static void Main(string[] args)
static void Main(string[] args)
{
{
Line 448: Line 448:
Value += 1;
Value += 1;
}
}
</syntaxhighlight>
</lang>


Example Result:
Example Result:
Line 466: Line 466:


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


'''With references:'''
'''With references:'''


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


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


References cannot be changed to refer to other objects, and cannot (legally) made to refer to no object.
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:
Get a reference to the first element of an array:
<lang cpp>int array[10];
<syntaxhighlight lang="cpp">int array[10];
int& ref3 = array[0];</lang>
int& ref3 = array[0];</syntaxhighlight>


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


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


=={{header|COBOL}}==
=={{header|COBOL}}==
===Pointers===
===Pointers===
Pointers are declared like so, optionally with the type or program they will point to:
Pointers are declared like so, optionally with the type or program they will point to:
<lang cobol> 01 ptr USAGE POINTER TO Some-Type.
<syntaxhighlight lang="cobol"> 01 ptr USAGE POINTER TO Some-Type.
01 prog-ptr USAGE PROGRAM-POINTER "some-program". *> TO is optional</lang>
01 prog-ptr USAGE PROGRAM-POINTER "some-program". *> TO is optional</syntaxhighlight>


<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>.
<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>.
<lang cobol>ALLOCATE heap-item RETURNING ptr
<syntaxhighlight lang="cobol">ALLOCATE heap-item RETURNING ptr
...
...
FREE ptr</lang>
FREE ptr</syntaxhighlight>


<code>USAGE PROGRAM-POINTER</code> data items are used to point to programs and their entry points.
<code>USAGE PROGRAM-POINTER</code> data items are used to point to programs and their entry points.
{{works with|OpenCOBOL}}
{{works with|OpenCOBOL}}
{{works with|Visual COBOL}}
{{works with|Visual COBOL}}
<lang cobol>SET prog-ptr TO ENTRY "some-program"</lang>
<syntaxhighlight lang="cobol">SET prog-ptr TO ENTRY "some-program"</syntaxhighlight>


Both types of pointer support basic pointer arithmetic.
Both types of pointer support basic pointer arithmetic.
<lang cobol>SET ptr1 UP BY 10
<syntaxhighlight lang="cobol">SET ptr1 UP BY 10
SET ptr2 DOWN BY LENGTH OF foo</lang>
SET ptr2 DOWN BY LENGTH OF foo</syntaxhighlight>


Pointers can also be set to point to where other pointers are pointing or to other pointers themselves.
Pointers can also be set to point to where other pointers are pointing or to other pointers themselves.
<lang cobol>SET ptr1 TO ptr2 *> ptr1 points to where ptr2 points
<syntaxhighlight lang="cobol">SET ptr1 TO ptr2 *> ptr1 points to where ptr2 points
SET ptr2 TO ADDRESS OF ptr3 *> ptr2 points to ptr3</lang>
SET ptr2 TO ADDRESS OF ptr3 *> ptr2 points to ptr3</syntaxhighlight>


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.
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.
<lang cobol>SET ADDRESS OF foo TO ptr
<syntaxhighlight lang="cobol">SET ADDRESS OF foo TO ptr
MOVE "bar" TO foo</lang>
MOVE "bar" TO foo</syntaxhighlight>


===References===
===References===
Object references are declared like so, optionally with the class/interface they will reference:
Object references are declared like so, optionally with the class/interface they will reference:
<lang cobol> 01 obj USAGE OBJECT-REFERENCE "some-object".</lang>
<syntaxhighlight lang="cobol"> 01 obj USAGE OBJECT-REFERENCE "some-object".</syntaxhighlight>


They contain either a reference to an object or <code>NULL</code>.
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.
They are initialised using by invoking a class constructor, and set using the <code>SET</code> statement.
<lang cobol>INVOKE SomeClass "new" RETURNING obj-ref
<syntaxhighlight lang="cobol">INVOKE SomeClass "new" RETURNING obj-ref
SET another-obj-ref TO obj-ref</lang>
SET another-obj-ref TO obj-ref</syntaxhighlight>


<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>).
<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 537: Line 537:
=={{header|D}}==
=={{header|D}}==


<lang d>void main() {
<syntaxhighlight lang="d">void main() {
// Take the address of 'var' and placing it in a pointer:
// Take the address of 'var' and placing it in a pointer:
int var;
int var;
Line 564: Line 564:
void foo5(T)(ref T t) {} // By reference regardless of what type
void foo5(T)(ref T t) {} // By reference regardless of what type
// T really is.
// T really is.
}</lang>
}</syntaxhighlight>


=={{header|Delphi}}==
=={{header|Delphi}}==
Line 576: Line 576:
Variable Declaration
Variable Declaration


<lang delphi>pMyPointer : Pointer ;</lang>
<syntaxhighlight lang="delphi">pMyPointer : Pointer ;</syntaxhighlight>


Simple pointer to a ''predefined'' type:
Simple pointer to a ''predefined'' type:
Line 582: Line 582:
Variable Declaration
Variable Declaration


<lang delphi>pIntPointer : ^Integer ;</lang>
<syntaxhighlight lang="delphi">pIntPointer : ^Integer ;</syntaxhighlight>


A pointer to a ''Record''. This is the equivalent to a ''Struct'' in C
A pointer to a ''Record''. This is the equivalent to a ''Struct'' in C
Line 588: Line 588:
Type Defintion
Type Defintion


<lang delphi>MyRecord = Record
<syntaxhighlight lang="delphi">MyRecord = Record
FName : string[20];
FName : string[20];
LName : string[20];
LName : string[20];
end;</lang>
end;</syntaxhighlight>


Variable Declaration
Variable Declaration


<lang delphi>pMyRecord : ^MyRecord ;</lang>
<syntaxhighlight lang="delphi">pMyRecord : ^MyRecord ;</syntaxhighlight>


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:
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
<syntaxhighlight lang="delphi">type
pFoo = ^tFoo; { allowed despite tFoo not yet being defined }
pFoo = ^tFoo; { allowed despite tFoo not yet being defined }
tFoo = record
tFoo = record
value1, value2: integer;
value1, value2: integer;
end;</lang>
end;</syntaxhighlight>


- Dereferencing a Pointer -
- Dereferencing a Pointer -
Line 609: Line 609:
Pointers are dereferenced using the caret '^' symbol. Dereferencing will cause the compiler or RTL to reveal the data that the pointer points to:
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>
<syntaxhighlight lang="delphi">IntVar := pIntPointer^ ;</syntaxhighlight>


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.
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>
<syntaxhighlight lang="delphi">IntVar := integer(MyPointer^);</syntaxhighlight>


- Pushing a Pointer -
- Pushing a Pointer -
Line 619: Line 619:
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:
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
<syntaxhighlight lang="delphi">Inc(PtrVar); //increment by one element
Inc(PtrVar, 4); //incremement by four elements
Inc(PtrVar, 4); //incremement by four elements
Dec(PtrVar); //decrement by one element</lang>
Dec(PtrVar); //decrement by one element</syntaxhighlight>


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:
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}
<syntaxhighlight lang="delphi">{$POINTERMATH ON}
PrevIntVar := MyIntPtr[-1];
PrevIntVar := MyIntPtr[-1];
Rec4 := MyRecPtr[4];</lang>
Rec4 := MyRecPtr[4];</syntaxhighlight>


=={{header|E}}==
=={{header|E}}==
Line 657: Line 657:
=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
No pointers in EchoLisp. '''Boxes ''' or vectors can be used to perform call-by-reference operations.
No pointers in EchoLisp. '''Boxes ''' or vectors can be used to perform call-by-reference operations.
<lang scheme>
<syntaxhighlight lang="scheme">
(define B (box 42))
(define B (box 42))
→ B ;; box reference
→ B ;; box reference
Line 671: Line 671:
(unbox B)
(unbox B)
→ 666
→ 666
</syntaxhighlight>
</lang>


=={{header|Forth}}==
=={{header|Forth}}==
Line 723: Line 723:
Since Fortran90, the <tt>pointer</tt> attribute can be given:
Since Fortran90, the <tt>pointer</tt> attribute can be given:


<lang fortran>real, pointer :: pointertoreal</lang>
<syntaxhighlight lang="fortran">real, pointer :: pointertoreal</syntaxhighlight>


A so-declared pointer is in an undetermined state: a pointer should be nullified:
A so-declared pointer is in an undetermined state: a pointer should be nullified:


<lang fortran>nullify(pointertoreal)</lang>
<syntaxhighlight lang="fortran">nullify(pointertoreal)</syntaxhighlight>


But Fortran 95 allows to initialize pointers to NULL (unassociated):
But Fortran 95 allows to initialize pointers to NULL (unassociated):


<lang fortran>real, pointer :: apointer => NULL()</lang>
<syntaxhighlight lang="fortran">real, pointer :: apointer => NULL()</syntaxhighlight>


A pointer can be associated:
A pointer can be associated:


<lang fortran>real, target :: areal
<syntaxhighlight lang="fortran">real, target :: areal
pointertoreal => areal</lang>
pointertoreal => areal</syntaxhighlight>


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


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


and the association can be nullified as before with <tt>nullify</tt>.
and the association can be nullified as before with <tt>nullify</tt>.
Line 746: Line 746:
The data a "pointer" points to can be allocated as if the <tt>allocatable</tt> attribute were specified.
The data a "pointer" points to can be allocated as if the <tt>allocatable</tt> attribute were specified.


<lang fortran>integer, dimension(:), pointer :: array
<syntaxhighlight lang="fortran">integer, dimension(:), pointer :: array
allocate(array(100))</lang>
allocate(array(100))</syntaxhighlight>


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.
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 753: Line 753:
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)
The function <tt>associated</tt> (Fortran 95) accepts also the optional argument <tt>target</tt>, to check if the pointer is associated to a particular target (working ''de facto'' like an alias)


<lang fortran>integer, target :: i
<syntaxhighlight lang="fortran">integer, target :: i
integer, pointer :: pi
integer, pointer :: pi
!... ...
!... ...
if ( associated(pi, target=i) ) !...</lang>
if ( associated(pi, target=i) ) !...</syntaxhighlight>


Associating pointer to an array could help accessing the data of the array in a different manner.
Associating pointer to an array could help accessing the data of the array in a different manner.


<lang fortran>real, dimension(20), target :: a
<syntaxhighlight lang="fortran">real, dimension(20), target :: a
real, dimension(20,20), target :: b
real, dimension(20,20), target :: b
real, dimension(:), pointer :: p
real, dimension(:), pointer :: p
Line 767: Line 767:
! p(1) == a(5), p(2) == a(6) ...
! p(1) == a(5), p(2) == a(6) ...
p => b(10,1:20)
p => b(10,1:20)
! p(1) == b(10,1), p(2) == b(10,2) ...</lang>
! p(1) == b(10,1), p(2) == b(10,2) ...</syntaxhighlight>


Which is different of course from having e.g.
Which is different of course from having e.g.


<lang fortran>real, dimension(20) :: a
<syntaxhighlight lang="fortran">real, dimension(20) :: a
real, dimension(16) :: p
real, dimension(16) :: p


p = a(5:20)</lang>
p = a(5:20)</syntaxhighlight>


In order to create arrays of pointers, the only way is to define a new type:
In order to create arrays of pointers, the only way is to define a new type:


<lang fortran>type intpointer
<syntaxhighlight lang="fortran">type intpointer
integer, pointer :: p
integer, pointer :: p
end type intpointer
end type intpointer


!...
!...
type(intpointer), dimension(100) :: parray</lang>
type(intpointer), dimension(100) :: parray</syntaxhighlight>


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.
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 792: Line 792:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>' FB 1.05.0 Win64
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64


Type Cat
Type Cat
Line 838: Line 838:
' print them out
' print them out
Print "i ="; i, "j ="; j
Print "i ="; i, "j ="; j
Sleep</lang>
Sleep</syntaxhighlight>


{{out}}
{{out}}
Line 853: Line 853:
Short of restrictions though, <tt>*</tt> and <tt>&</tt> are used much as they are in C.
Short of restrictions though, <tt>*</tt> and <tt>&</tt> are used much as they are in C.


<lang go>var p *int // declare p to be a pointer to an int
<syntaxhighlight 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>
i = &p // assign i to be the int value pointed to by p</syntaxhighlight>


The zero value of a pointer is called nil. Dereferencing a nil pointer, as in the example above, causes a run-time panic.
The zero value of a pointer is called nil. Dereferencing a nil pointer, as in the example above, causes a run-time panic.
Line 860: Line 860:
Some go types contain pointers in their internal representation and are called reference types. For example, slices, maps, and channels are always reference types.
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>
<syntaxhighlight lang="go">var m map[string]int</syntaxhighlight>


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.
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>
<syntaxhighlight lang="go">m := make(map[string]int)</syntaxhighlight>


Built-in function make allocates and constructs the internal representation and returns a map object ready to use.
Built-in function make allocates and constructs the internal representation and returns a map object ready to use.
Line 870: Line 870:
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
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”)
<syntaxhighlight lang="go">b := []byte(“hello world”)
c := b
c := b
c[0] = 'H'
c[0] = 'H'
fmt.Println(string(b))</lang>
fmt.Println(string(b))</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 880: Line 880:
Go's garbage collector is aware of references created by taking the address of an object.
Go's garbage collector is aware of references created by taking the address of an object.


<lang go>func three() *int {
<syntaxhighlight lang="go">func three() *int {
i := 3
i := 3
return &i // valid. no worry, no crash.
return &i // valid. no worry, no crash.
}</lang>
}</syntaxhighlight>


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


<lang go>type pt struct {
<syntaxhighlight lang="go">type pt struct {
x, y int
x, y int
}
}


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


=={{header|Haskell}}==
=={{header|Haskell}}==
Line 899: Line 899:
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:
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>
<syntaxhighlight lang="haskell">
import Data.STRef
import Data.STRef


Line 907: Line 907:
k <- readSTRef p
k <- readSTRef p
writeSTRef p (k+1)
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'.
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 928: Line 928:
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:
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; }
<syntaxhighlight lang="java"> public class Foo { public int x = 0; }


void somefunction() {
void somefunction() {
Line 936: Line 936:
a.x = 5; // this modifies the "x" field of the object pointed to by "a"
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"
System.out.println(b.x); // this prints 5, because "b" points to the same object as "a"
}</lang>
}</syntaxhighlight>


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.
Java is call-by-value. When passing arguments, you are either passing primitives by value or references by value. There is no such thing as "passing an object" as objects are not values in the language. As noted above, if the object that the reference is pointing to is mutable, then it is possible to modify that object's state through the reference. Then if the calling function has a reference to the same object, they will see that modification through the reference. So if you want to reflect changes in an argument back to the caller, one thing that you can do is wrap the argument as a field in an object, then modify the object through the reference.
Line 944: Line 944:


Julia's C interface pointer functions are considered "unsafe" because, like C pointers, they may cause data corruption if used incorrectly.
Julia's C interface pointer functions are considered "unsafe" because, like C pointers, they may cause data corruption if used incorrectly.
<lang julia>x = [1, 2, 3, 7]
<syntaxhighlight lang="julia">x = [1, 2, 3, 7]


parr = pointer(x)
parr = pointer(x)
Line 951: Line 951:


println(xx) # Prints 7
println(xx) # Prints 7
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 977: Line 977:


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.
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.
<lang scala>// Kotlin Native v0.3
<syntaxhighlight lang="scala">// Kotlin Native v0.3


import kotlinx.cinterop.*
import kotlinx.cinterop.*
Line 1,015: Line 1,015:
println(intArray[2]) // print the last element
println(intArray[2]) // print the last element
nativeHeap.free(intArray) // free native memory
nativeHeap.free(intArray) // free native memory
}</lang>
}</syntaxhighlight>


Sample output:
Sample output:
Line 1,036: Line 1,036:
=={{header|Lua}}==
=={{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.
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.
<lang Lua>local table1 = {1,2,3}
<syntaxhighlight lang="lua">local table1 = {1,2,3}
local table2 = table1
local table2 = table1
table2[3] = 4
table2[3] = 4
print(unpack(table1))</lang>
print(unpack(table1))</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 4</pre>
<pre>1 2 4</pre>
Line 1,049: Line 1,049:
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)
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
A=10
Module Beta {
Module Beta {
Line 1,057: Line 1,057:
Beta &A
Beta &A
Print A=11
Print A=11
</syntaxhighlight>
</lang>


====Reference for Functions/lambdas====
====Reference for Functions/lambdas====




<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module TestFuncRef {
Module TestFuncRef {
Function Alfa(x) {
Function Alfa(x) {
Line 1,093: Line 1,093:
}
}
TestFuncRef
TestFuncRef
</syntaxhighlight>
</lang>


===Weak Reference using Strings===
===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.
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
A=10
Dim A(10)=1
Dim A(10)=1
Line 1,108: Line 1,108:
Beta Weak$(A(2))
Beta Weak$(A(2))
Print A(2)=2
Print A(2)=2
</syntaxhighlight>
</lang>


===Pointer of Com Object===
===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.
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 {
Module ShowModalFormWithCLock {
Declare Form1 Form
Declare Form1 Form
Line 1,123: Line 1,123:
}
}
ShowModalFormWithCLock
ShowModalFormWithCLock
</syntaxhighlight>
</lang>


===Pointer of Container===
===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.
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 {
Module CheckArray {
\\ This is a value type array
\\ This is a value type array
Line 1,154: Line 1,154:
}
}
CheckArray
CheckArray
</syntaxhighlight>
</lang>
===Pointers of Groups===
===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).
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 {
Module GroupPointers {
Group Zeta {
Group Zeta {
Line 1,192: Line 1,192:
}
}
GroupPointers
GroupPointers
</syntaxhighlight>
</lang>
====Reference of members of Groups====
====Reference of members of Groups====
We can pass reference from group members, if group has a name.
We can pass reference from group members, if group has a name.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckGroupRef {
Module CheckGroupRef {
Group TestMe {
Group TestMe {
Line 1,234: Line 1,234:
}
}
CheckGroupRef
CheckGroupRef
</syntaxhighlight>
</lang>


=={{header|Modula-3}}==
=={{header|Modula-3}}==
Line 1,240: Line 1,240:


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


VAR intref := NEW(IntRef);
VAR intref := NEW(IntRef);


intref^ := 10</lang>
intref^ := 10</syntaxhighlight>


The <tt>^</tt> character is the dereference operator, and is suffixed to the reference variable name.
The <tt>^</tt> character is the dereference operator, and is suffixed to the reference variable name.
Line 1,253: Line 1,253:
===REFANY===
===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.
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.
<lang modula3>VAR any: REFANY;
<syntaxhighlight 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>
any := NEW(REF INTEGER); (* Modula-3 knows that any is now REF INTEGER with a tag added by NEW. *)</syntaxhighlight>


===TYPECASE===
===TYPECASE===
To determine the type of a variable, you can use <tt>TYPECASE</tt>.
To determine the type of a variable, you can use <tt>TYPECASE</tt>.
<lang modula3>PROCEDURE Sum(READONLY a: ARRAY OF REFANY): REAL =
<syntaxhighlight lang="modula3">PROCEDURE Sum(READONLY a: ARRAY OF REFANY): REAL =
VAR sum := 0.0;
VAR sum := 0.0;
BEGIN
BEGIN
Line 1,270: Line 1,270:
END;
END;
RETURN sum;
RETURN sum;
END Sum;</lang>
END Sum;</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
Line 1,276: Line 1,276:


Create a safe reference:
Create a safe reference:
<lang nim>type Foo = ref object
<syntaxhighlight lang="nim">type Foo = ref object
x, y: float
x, y: float


var f: Foo
var f: Foo
new f</lang>
new f</syntaxhighlight>


Accessing the reference:
Accessing the reference:
<lang nim>echo f[]</lang>
<syntaxhighlight lang="nim">echo f[]</syntaxhighlight>


When accessing values the dereference operator [] can be left out:
When accessing values the dereference operator [] can be left out:
<lang nim>echo f[].x
<syntaxhighlight lang="nim">echo f[].x
f[].y = 12
f[].y = 12
echo f.y
echo f.y
f.x = 13.5</lang>
f.x = 13.5</syntaxhighlight>


Create an (unsafe) pointer to an int variable:
Create an (unsafe) pointer to an int variable:
<lang nim>var x = 3
<syntaxhighlight lang="nim">var x = 3
var p = addr x</lang>
var p = addr x</syntaxhighlight>


Access the integer variable through the pointer:
Access the integer variable through the pointer:
<lang nim>echo p[]
<syntaxhighlight lang="nim">echo p[]
p[] = 42</lang>
p[] = 42</syntaxhighlight>


Change the pointer to refer to another object:
Change the pointer to refer to another object:
<lang nim>var y = 12
<syntaxhighlight lang="nim">var y = 12
p = addr y</lang>
p = addr y</syntaxhighlight>


Change the pointer to not point to any object:
Change the pointer to not point to any object:
<lang nim>p = nil</lang>
<syntaxhighlight lang="nim">p = nil</syntaxhighlight>


=={{header|OCaml}}==
=={{header|OCaml}}==
Line 1,312: Line 1,312:
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:
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>
<syntaxhighlight lang="ocaml">
let p = ref 1;; (* create a new "reference" data structure with initial value 1 *)
let p = ref 1;; (* create a new "reference" data structure with initial value 1 *)
let k = !p;; (* "dereference" the reference, returning the value inside *)
let k = !p;; (* "dereference" the reference, returning the value inside *)
p := k + 1;; (* set the value inside to a new value *)
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.)
(The OCaml web-site provides this [http://caml.inria.fr/resources/doc/guides/pointers.en.html page] on the subject.)
Line 1,335: Line 1,335:
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:
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>
<syntaxhighlight lang="oorexx">
::class Foo
::class Foo
::method init
::method init
Line 1,347: Line 1,347:
a~x = 5 -- modifies the X variable inside the object pointer to by a
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
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.
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>
<br>With the Use Arg instruction, a subroutine get access to the caller's argument object by reference:
<br>With the Use Arg instruction, a subroutine get access to the caller's argument object by reference:
<lang oorexx>a.='not set'
<syntaxhighlight lang="oorexx">a.='not set'
a.3=3
a.3=3
Say 'Before Call sub: a.3='a.3
Say 'Before Call sub: a.3='a.3
Line 1,371: Line 1,371:
Say 'in sub2: a.='a.
Say 'in sub2: a.='a.
Say 'in sub2: a.3='a.3 -- this changes the local a.
Say 'in sub2: a.3='a.3 -- this changes the local a.
Return</lang>
Return</syntaxhighlight>
{{out}}
{{out}}
<pre>Before Call sub: a.3=3
<pre>Before Call sub: a.3=3
Line 1,381: Line 1,381:
=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
Some built-in functions like <code>issquare</code> have pointer arguments:
Some built-in functions like <code>issquare</code> have pointer arguments:
<lang parigp>n=1;
<syntaxhighlight lang="parigp">n=1;
issquare(9,&n);
issquare(9,&n);
print(n); \\ prints 3</lang>
print(n); \\ prints 3</syntaxhighlight>


{{Works with|PARI/GP|2.12.0}}
{{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:
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:
<lang parigp>boxit(~L, x)=listput(L, x);
<syntaxhighlight lang="parigp">boxit(~L, x)=listput(L, x);
S=List();
S=List();
boxit(S,1);
boxit(S,1);
S</lang>
S</syntaxhighlight>
{{out}}
{{out}}
<pre>1</pre>
<pre>1</pre>
Line 1,401: Line 1,401:
Pascal does not support pointer operations on the stack.
Pascal does not support pointer operations on the stack.
In fact, Pascal does not even “know” there is a stack.
In fact, Pascal does not even “know” there is a stack.
<lang pascal>program pointerDemo;
<syntaxhighlight lang="pascal">program pointerDemo;


type
type
Line 1,442: Line 1,442:
released after `program` termination.
released after `program` termination.
}
}
end.</lang>
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).
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>).
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>.
It is imperative the selectors in <tt>dispose</tt> match to the corresponding <tt>new</tt>.
<lang pascal>program variantRecordDemo;
<syntaxhighlight lang="pascal">program variantRecordDemo;


type
type
Line 1,462: Line 1,462:
{ … }
{ … }
dispose(head, true);
dispose(head, true);
end.</lang>
end.</syntaxhighlight>
As a special case of pointers, functions and procedures can be passed as parameters to routines.
As a special case of pointers, functions and procedures can be passed as parameters to routines.
<lang pascal>program routineParameterDemo(output);
<syntaxhighlight lang="pascal">program routineParameterDemo(output);


procedure foo(function f: Boolean);
procedure foo(function f: Boolean);
Line 1,478: Line 1,478:
begin
begin
foo(bar);
foo(bar);
end.</lang>
end.</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
Line 1,485: Line 1,485:
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.
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.


<lang perl> # start with some var definitions
<syntaxhighlight lang="perl"> # start with some var definitions
my $scalar = 'aa';
my $scalar = 'aa';
my @array = ('bb', 'cc');
my @array = ('bb', 'cc');
Line 1,493: Line 1,493:
my $scalarref = \$scalar;
my $scalarref = \$scalar;
my $arrayref = \@array;
my $arrayref = \@array;
my $hashref = \%hash;</lang>
my $hashref = \%hash;</syntaxhighlight>


Using a reference
Using a reference


<lang perl> # accessing the value
<syntaxhighlight lang="perl"> # accessing the value
print $$scalarref; # 'aa'
print $$scalarref; # 'aa'
print @$arrayref; # 'bbcc'
print @$arrayref; # 'bbcc'
Line 1,506: Line 1,506:
$$scalarref = 'a new string'; # changes $scalar
$$scalarref = 'a new string'; # changes $scalar
$arrayref->[0] = 'foo'; # changes the first value of @array
$arrayref->[0] = 'foo'; # changes the first value of @array
$hashref->{'dd'} = 'bar'; # changes the value with key 'dd' in %hash</lang>
$hashref->{'dd'} = 'bar'; # changes the value with key 'dd' in %hash</syntaxhighlight>


You may also create anonymous references:
You may also create anonymous references:


<lang perl> my $scalarref = \'a scalar';
<syntaxhighlight lang="perl"> my $scalarref = \'a scalar';
my $arrayref = ['an', 'array'];
my $arrayref = ['an', 'array'];
my $hashref = { firstkey => 'a', secondkey => 'hash' }</lang>
my $hashref = { firstkey => 'a', secondkey => 'hash' }</syntaxhighlight>


=={{header|Phix}}==
=={{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.
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.


<!--<lang Phix>(notonline)-->
<!--<syntaxhighlight lang="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: #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>
<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,523: Line 1,523:
<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: #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>
<span style="color: #7060A8;">free</span><span style="color: #0000FF;">(</span><span style="color: #000000;">addr</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->


There are in fact 5 variants of poke: poke1, poke2, poke4, poke8, and pokeN which allows the size to be dynamically specified.
There are in fact 5 variants of poke: poke1, poke2, poke4, poke8, and pokeN which allows the size to be dynamically specified.
Line 1,532: Line 1,532:


You can, of course use pointers via inline assembly (but only as a last resort/if you are mental enough):
You can, of course use pointers via inline assembly (but only as a last resort/if you are mental enough):
<lang Phix>atom mypi
<syntaxhighlight lang="phix">atom mypi
#ilASM{
#ilASM{
fldpi
fldpi
Line 1,540: Line 1,540:
lea rdi,[mypi]
lea rdi,[mypi]
[]
[]
call :%pStoreFlt }</lang>
call :%pStoreFlt }</syntaxhighlight>
or
or
<lang Phix>string mystring = "mystring"
<syntaxhighlight lang="phix">string mystring = "mystring"
#ilASM{
#ilASM{
[32]
[32]
Line 1,551: Line 1,551:
lea rsi,[rbx+rsi*4] -- byte[rsi] is 'm'
lea rsi,[rbx+rsi*4] -- byte[rsi] is 'm'
[]
[]
}</lang>
}</syntaxhighlight>
Of course in a reference counted language like Phix, playing directly with the innards like that may have dire unexpected side effects.
Of course in a reference counted language like Phix, playing directly with the innards like that may have dire unexpected side effects.
Line 1,557: Line 1,557:
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:
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:


<!--<lang Phix>-->
<!--<syntaxhighlight lang="phix">-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span>
<span style="color: #0000FF;">...</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>
<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>
<!--</lang>-->
<!--</syntaxhighlight>-->


It is a general optimisation, applied by the complier whenever and wherever it can, without the programmer having to do anything special.
It is a general optimisation, applied by the complier whenever and wherever it can, without the programmer having to do anything special.
Line 1,576: Line 1,576:
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.
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
<syntaxhighlight lang="php"><?php
/* Assignment of scalar variables */
/* Assignment of scalar variables */
$a = 1;
$a = 1;
Line 1,603: Line 1,603:
pass_in($tmp); // changes $tmp and prints the length
pass_in($tmp); // changes $tmp and prints the length


?></lang>
?></syntaxhighlight>


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.
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,634: Line 1,634:
'[http://software-lab.de/doc/refN.html#nth nth]', which advance the pointer to
'[http://software-lab.de/doc/refN.html#nth nth]', which advance the pointer to
the next (linked to) location(s).
the next (linked to) location(s).
<lang PicoLisp>: (setq L (1 a 2 b 3 c)) # Create a list of 6 items in 'L'
<syntaxhighlight lang="picolisp">: (setq L (1 a 2 b 3 c)) # Create a list of 6 items in 'L'
-> (1 a 2 b 3 c)
-> (1 a 2 b 3 c)


Line 1,644: Line 1,644:


: L # Look at the modified list in 'L'
: L # Look at the modified list in 'L'
-> (1 a 2 "Hello" 3 c)</lang>
-> (1 a 2 "Hello" 3 c)</syntaxhighlight>


=={{header|PL/I}}==
=={{header|PL/I}}==
Line 1,652: Line 1,652:
* control statements: ALLOCATE, FREE
* control statements: ALLOCATE, FREE
Simple examples:
Simple examples:
<lang pli>
<syntaxhighlight lang="pli">
dcl i fixed bin(31);
dcl i fixed bin(31);
dcl p pointer;
dcl p pointer;
Line 1,675: Line 1,675:
p=addr(i1); t=addr(i2), q=addr(p); s=addr(t);
p=addr(i1); t=addr(i2), q=addr(p); s=addr(t);
q->p->j = s->t->k + 3; /* to say i1=i2+3 */
q->p->j = s->t->k + 3; /* to say i1=i2+3 */
</syntaxhighlight>
</lang>


=={{header|Pop11}}==
=={{header|Pop11}}==
Line 1,719: Line 1,719:
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.
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:
The following code creates a pointer to an integer variable:
<lang PureBasic>Define varA.i = 5, varB.i = 0, *myInteger.Integer
<syntaxhighlight lang="purebasic">Define varA.i = 5, varB.i = 0, *myInteger.Integer


*myInteger = @varA ;set pointer to address of an integer variable
*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>
varB = *myInteger\i + 3 ;set variable to the 3 + value of dereferenced pointer, i.e varB = 8</syntaxhighlight>
Change pointer to refer to another integer variable:
Change pointer to refer to another integer variable:
<lang PureBasic>Define varC.i = 12
<syntaxhighlight lang="purebasic">Define varC.i = 12
*myInteger = @varC</lang>
*myInteger = @varC</syntaxhighlight>
Change pointer to not point to anything:
Change pointer to not point to anything:
<lang PureBasic>*myInteger = #Null ;or anything evaluating to zero</lang>
<syntaxhighlight lang="purebasic">*myInteger = #Null ;or anything evaluating to zero</syntaxhighlight>
Get a pointer to the first element of an array, or any desired element:
Get a pointer to the first element of an array, or any desired element:
<lang PureBasic>Dim myArray(10)
<syntaxhighlight lang="purebasic">Dim myArray(10)
*myInteger = myArray()
*myInteger = myArray()
;Or alternatively:
;Or alternatively:
*myInteger = @myArray(0)
*myInteger = @myArray(0)
;any specific element
;any specific element
*myInteger = @myArray(4) ;element 4</lang>
*myInteger = @myArray(4) ;element 4</syntaxhighlight>
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>.
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>.
<lang PureBasic>*myInteger + 3 * SizeOf(Integer) ;pointer now points to myArray(3)
<syntaxhighlight lang="purebasic">*myInteger + 3 * SizeOf(Integer) ;pointer now points to myArray(3)
*myInteger - 2 * SizeOf(Integer) ;pointer now points to myArray(1)</lang>
*myInteger - 2 * SizeOf(Integer) ;pointer now points to myArray(1)</syntaxhighlight>
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:
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:
<lang PureBasic>Structure employee
<syntaxhighlight lang="purebasic">Structure employee
id.i
id.i
name.s
name.s
Line 1,748: Line 1,748:


;set a string pointer to the 6th job of the 4th employee
;set a string pointer to the 6th job of the 4th employee
*myString.String = @employees(3) + OffsetOf(employee\jobs) + 5 * SizeOf(String)</lang>
*myString.String = @employees(3) + OffsetOf(employee\jobs) + 5 * SizeOf(String)</syntaxhighlight>
===Addresses of variables or procedure===
===Addresses of variables or procedure===
Addresses to variables and functions are obtained with the '@' operator.
Addresses to variables and functions are obtained with the '@' operator.
<lang PureBasic>*pointer = @varA
<syntaxhighlight lang="purebasic">*pointer = @varA
*pointer = @myFunction()</lang>
*pointer = @myFunction()</syntaxhighlight>
===Addresses of labels===
===Addresses of labels===
To find the address of a label, you put a question mark (?) in front of the label name.
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
<syntaxhighlight lang="purebasic">; Getting the address of a lable in the code
text$="'Lab' is at address "+Str(?lab)
text$="'Lab' is at address "+Str(?lab)
MessageRequester("Info",text$)
MessageRequester("Info",text$)
Line 1,774: Line 1,774:
Data.i 3,1,4,5,9,2,1,6
Data.i 3,1,4,5,9,2,1,6
lab2:
lab2:
EndDataSection</lang>
EndDataSection</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
Line 1,780: Line 1,780:
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").
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:
<syntaxhighlight lang="python"> # Bind a literal string object to a name:
a = "foo"
a = "foo"
# Bind an empty list to another name:
# Bind an empty list to another name:
Line 1,811: Line 1,811:
# Call (anymous function object) from inside a list
# 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
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>
# even if its name is unbound or rebound to some other object.</syntaxhighlight>


[Note: in some ways this task is meaningless for Python given the nature of its "variable" binding semantics].
[Note: in some ways this task is meaningless for Python given the nature of its "variable" binding semantics].
Line 1,818: Line 1,818:


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:
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>
<syntaxhighlight lang="racket">
#lang racket
#lang racket


Line 1,828: Line 1,828:
(inc! b)
(inc! b)
(unbox b) ; => 3
(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.
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,836: Line 1,836:
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.)
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.)


<lang perl6>my $foo = 42; # place a reference to 42 in $foo's item container
<syntaxhighlight lang="raku" line>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++; # 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.say; # deref $foo name, then $foo's container, and call a method on 43.
Line 1,848: Line 1,848:


@bar := (1,2,3); # bind name directly to a List
@bar := (1,2,3); # bind name directly to a List
@bar»++; # ERROR, parcels are not mutable</lang>
@bar»++; # ERROR, parcels are not mutable</syntaxhighlight>
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.
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,859: Line 1,859:


=={{header|SAS}}==
=={{header|SAS}}==
<lang sas>/* Using ADDR to get memory address, and PEEKC / POKE. There is also PEEK for numeric values. */
<syntaxhighlight lang="sas">/* Using ADDR to get memory address, and PEEKC / POKE. There is also PEEK for numeric values. */
data _null_;
data _null_;
length a b c $4;
length a b c $4;
Line 1,871: Line 1,871:
call poke(b,adr_c,1);
call poke(b,adr_c,1);
put a b c;
put a b c;
run;</lang>
run;</syntaxhighlight>


=={{header|Scala}}==
=={{header|Scala}}==
Line 1,884: Line 1,884:
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 (->).
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 (->).


<lang Shale>#!/usr/local/bin/shale
<syntaxhighlight lang="shale">#!/usr/local/bin/shale


aVariable var // Create aVariable
aVariable var // Create aVariable
Line 1,906: Line 1,906:


// Shale pointers can point to any Shale object, like numbers, strings, variables
// Shale pointers can point to any Shale object, like numbers, strings, variables
// and code fragments.</lang>
// and code fragments.</syntaxhighlight>


{{out}}
{{out}}
Line 1,918: Line 1,918:
=={{header|Sidef}}==
=={{header|Sidef}}==
A simple example of passing a variable-reference to a function:
A simple example of passing a variable-reference to a function:
<lang ruby>func assign2ref(ref, value) {
<syntaxhighlight lang="ruby">func assign2ref(ref, value) {
*ref = value;
*ref = value;
}
}
Line 1,924: Line 1,924:
var x = 10;
var x = 10;
assign2ref(\x, 20);
assign2ref(\x, 20);
say x; # x is now 20</lang>
say x; # x is now 20</syntaxhighlight>


=={{header|Standard ML}}==
=={{header|Standard ML}}==
Line 1,930: Line 1,930:
Like OCaml, Standard ML doesn't have pointers but have a "ref" mutable data structure which is the basis of mutability in 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>
<syntaxhighlight lang="sml">
val p = ref 1; (* create a new "reference" data structure with initial value 1 *)
val p = ref 1; (* create a new "reference" data structure with initial value 1 *)
val k = !p; (* "dereference" the reference, returning the value inside *)
val k = !p; (* "dereference" the reference, returning the value inside *)
p := k + 1; (* set the value inside to a new value *)
p := k + 1; (* set the value inside to a new value *)
</syntaxhighlight>
</lang>


=={{header|Tcl}}==
=={{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.:
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
<syntaxhighlight lang="tcl">set var 3
set pointer var; # assign name "var" not value 3
set pointer var; # assign name "var" not value 3
set pointer; # returns "var"
set pointer; # returns "var"
set $pointer; # returns 3
set $pointer; # returns 3
set $pointer 42; # variable var now has value 42</lang>
set $pointer 42; # variable var now has value 42</syntaxhighlight>
In practice it's safer and more convenient to use array keys or the <tt>upvar</tt> command, e.g.:
In practice it's safer and more convenient to use array keys or the <tt>upvar</tt> command, e.g.:
<lang tcl>set arr(var) 3
<syntaxhighlight lang="tcl">set arr(var) 3
set pointer var
set pointer var
set arr($pointer); # returns 3
set arr($pointer); # returns 3
Line 1,952: Line 1,952:
set pointer var
set pointer var
upvar 0 $pointer varAlias; # varAlias is now the same variable as var
upvar 0 $pointer varAlias; # varAlias is now the same variable as var
set varAlias 42; # var now has value 42</lang>
set varAlias 42; # var now has value 42</syntaxhighlight>
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.
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,995: Line 1,995:
=={{header|VBA}}==
=={{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.
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.
<lang vb>Dim samplevariable as New Object
<syntaxhighlight lang="vb">Dim samplevariable as New Object
Dim anothervariable as Object
Dim anothervariable as Object
Set anothervariable = sameplevariable</lang>
Set anothervariable = sameplevariable</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
Line 2,007: Line 2,007:


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.
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.
<lang ecmascript>// This function takes a string (behaves like a value type) and a list (reference type).
<syntaxhighlight lang="ecmascript">// 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.
// The value and the reference are copied to their respective parameters.
var f = Fn.new { |s, l|
var f = Fn.new { |s, l|
Line 2,022: Line 2,022:
f.call(s, l)
f.call(s, l)
System.print(l)
System.print(l)
System.print(s)</lang>
System.print(s)</syntaxhighlight>


{{out}}
{{out}}
Line 2,031: Line 2,031:


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>\Paraphrasing the C example:
<syntaxhighlight lang="xpl0">\Paraphrasing the C example:
\This creates a pointer to an integer variable:
\This creates a pointer to an integer variable:
int Var, Ptr, V;
int Var, Ptr, V;
Line 2,062: Line 2,062:
V:= Ptr(3); \get third item after Array(1), i.e. Array(4)
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)
V:= Ptr(-1); \get item immediately preceding Array(1), i.e. Array(0)
]</lang>
]</syntaxhighlight>


=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
Line 2,068: Line 2,068:
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.
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.


<lang z80>ld a,(&C000) ;load the accumulator with the value from the memory address &C000.
<syntaxhighlight lang="z80">ld a,(&C000) ;load the accumulator with the value from the memory address &C000.


ld hl,&D000
ld hl,&D000
Line 2,081: Line 2,081:


ld IX,&F000
ld IX,&F000
ld a,(IX+3) ;load A with the byte stored at &F003, The Game Boy cannot use this addressing mode.</lang>
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.
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.
Line 2,087: Line 2,087:
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)
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)


<lang z80>ld h,(bc) ;if (bc) or (de) is the operand of a LD command, the other operand must be A.
<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.</lang>
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:
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:


<lang z80>inc (HL) ;increment the byte pointed to by HL
<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.
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.
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.</lang>
;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.
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.


<lang z80>ld hl,PointerTable
<syntaxhighlight lang="z80">ld hl,PointerTable
ld e,(hl)
ld e,(hl)
inc hl
inc hl
Line 2,112: Line 2,112:


; ld L,E
; ld L,E
; ld H,D</lang>
; 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:
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:


<lang z80>ld hl,PointerTable
<syntaxhighlight lang="z80">ld hl,PointerTable
ld a,(hl)
ld a,(hl)
ld (SMC+1),a ;SMC+1 points to low byte of the operand
ld (SMC+1),a ;SMC+1 points to low byte of the operand
Line 2,127: Line 2,127:


SMC:
SMC:
ld a,&BEEF ;gets overwritten with the pointer stored in entry 0 of PointerTable.</lang>
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.
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.
<lang z80>ld hl,PointerTable
<syntaxhighlight lang="z80">ld hl,PointerTable
ld a,(index)
ld a,(index)
add a ;this is a table of 16-bit values so double our index
add a ;this is a table of 16-bit values so double our index
Line 2,145: Line 2,145:
ld d,(hl) ;get the Ath entry of PointerTable and store it into DE.
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.</lang>
ld (referenceStorage),DE ;store DE into ram for later use as a reference.</syntaxhighlight>


=={{header|zkl}}==
=={{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.
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.
<lang zkl>fcn f(r){r.inc()} r:= Ref(1); f(r); r.value; //-->2</lang>
<syntaxhighlight lang="zkl">fcn f(r){r.inc()} r:= Ref(1); f(r); r.value; //-->2</syntaxhighlight>
A Ref can hold any value. inc is a special case convenience for numbers.
A Ref can hold any value. inc is a special case convenience for numbers.
<lang zkl>fcn f(lst){lst.append(5)} f(L()); //-->L(5)</lang>
<syntaxhighlight lang="zkl">fcn f(lst){lst.append(5)} f(L()); //-->L(5)</syntaxhighlight>
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.
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.