# Pointers

A pointer is an address data type. It is used to store the address of another variable. In Jai, just like C, pointers are defined using the `*` marker; but beware, the syntax is a bit different from C or C++.

``````a : int = 42; // Just a normal integer
b : *int;     // Here's a pointer to a integer.

b = *a; // Point b at a.
print("Value of a is %, address of a is %\n", a, *a);
print("Value of b is %, but b points at address %\n", <<b, b);
``````
Example output
``````Value of a is 42, address of a is 7fff_9ca3_1e28
Value of b is 42, but b points at address 7fff_9ca3_1e28
``````

As you can see there, we use unary `*` to get the address of a variable, and unary `<<` to dereference a pointer.

### Pointer Arithmetic

A pointer is a data address, which is a numeric value. You can perform arithmetic operations such as `+`, `-`, `*`, and `/` on a pointer just as you can on a numeric value. You can check pointers for equality using `==`, `!=`, `<`, `<=`, `>`, and `>=`.

``````array:  int
a: *int = array.data; // set a to point to array.data
a += 1;
``````

In the example above, incrementing pointer `a` by 1 adds 8 to the pointer, since a 64-bit integer consists of 8 bytes. A pointer increments depending on the size of the data the pointer points to.

### void pointer

`variable: *void;` is a void pointer, or a pointer with no associated data type. A void pointer can hold the address of any type and can be typcasted to any type. void pointer has the same functionality as in C.

### Pointers to Pointers

Just like in C++, pointers can also point to other pointers, allowing multiple indirection.

``````a: int = 3;
b: *int = *a;
c: **int = *b;
d: ***int = *c;
print("%\n", << << << d); // prints out the value of a, which is 3
``````

### Function Pointers

Function pointers can be declared almost in the same way as regular functions.

``````function :: (a: int, b: int)->int { // declare function
return a + b;
}

f_ptr: (int,int)->int = function;

// call the function that the function pointer is pointing to
c := f_ptr(1,2);
``````

### Relative pointers

Relative pointers are a way of having a pointer that is not a 64-bit pointer. Instead, the pointer can be 32-bit, 16-bit, or 8-bit. These pointers are serializable.

``````Obj :: struct { var:= 0; }

ptr: *~s32 Obj; // 32-bit relative pointer to an Obj
ptr: *~s16 Obj; // 16-bit relative pointer to an Obj
ptr: *~s8  Obj; //  8-bit relative pointer to an Obj
``````

Relative pointers use the same syntax and operators as normal pointers for assigning and derefering pointers.