A pointer is a variable who’s value is an address in memory. They can be declared as follows:

int x = 4;
int* xPtr = &x;
//or as the result of malloc
int* aPtr = malloc(sizeof(int));

xPtr here is a pointer to the variable x. It’s value is the address of x. Note that the position of the asterisk does not actually matter. it can be next to the variable name, next to the type, it’s the same as C compilers largely ignore whitespace.

Pointer Types

The type of a pointer can vary, but it is always of pointer to element type. For example, pointer to int is represented as int *

They are declared as

int * ptr;

or more generally

type* varname; //whitespace is not syntactically meaningful in C besides separation of symbols so the * can go to either side

Dereference

Accessing the value a pointer actually points to is generally called dereferencing.

Pointers can be dereferenced as follows:

	varname[0];
	//or 
	*varname

In other words, array access and pointer dereference mean very similar things. They are accessing the value at the address of varname.

Note that because of pointer arithmetic, you can also access elements of an array in the following way if you have a pointer to the start of the array:

varname[4];
//equivalent
*(varname + 4)

Initialization

Uninitialized pointers contain garbage values and can point to anywhere in memory. Dereferencing such a pointer would lead to undefined behavior and often causes a segfault. It is generally considered good practice to initialize pointers to either a valid address or to NULL/nullptr.

Pointer to an Array Vs Array of Pointers

Be careful to pay close attention to what kind of data type is being declared, in particular when pointers are involved. For example, in the example below, the following two declarations look similar but are in fact two completely different data types that would behave very differently:

int (*ptr)[10];

This is a pointer to an array of integers.

int *arr[10];

This is an array of pointers to integers. Declarations follow similar rules to operator precedence, though not technically operators. There’s some more interesting examples on the C standard website.

Uses

Pointers are incredibly useful across computer science and are the foundation of many abstract data structures, including linked lists, trees, graphs, heaps, the list goes on and on. The mishandling of pointers however can lead to many errors, including null pointer dereference being one of the most common. This has lead to a different types of pointers, smart pointers, which are a C++ idiomatic way of handling pointers.