# Experimenting with Pointers and Arrays in C

Can someone explain to me the difference between:

int *arr[5] vs. int (*arr)[5] vs. int *(*arr)[5]

I'm trying to wrap my mind around how pointers/arrays are actually represented in C...

I would suggest using http://cdecl.org.

plus a visit to this page from MSDN: Interpreting more complex declarators.

The first makes a variable named arr that is of an array length 5 of type int*, so it is an array length 5 of int pointers.

The second declares a variable named arr that is a pointer to an array length 5 of type int. So it is a pointer to an array of ints length 5.

The third is a variable named arr that is a pointer to an array of length 5 of type int pointer. So it is a pointer to an array length 5 of int pointers. Or, a pointer to the type of the first case!

To think of how to analyze things like this in the future, realize that parenthesis have the highest priority here so by having (*arr) it is first, and foremost, a pointer. Then the array notation has second highest priority, so (*arr)[5] is a pointer to an array of length 5...but what type of array? Well the type is the lowest priority, so that comes last. If we have int (*arr)[5], then it is a pointer (1st) to an array length 5 (2) of type int (3).

With that we can look at something like: int** (*arr)[7] It is a pointer named arr (1) to an array length 7 (2) of type int**, or pointers to pointers of ints (3).

As far as wondering how pointers/arrays are represented in C...

pointers and arrays are both 32 bit variables (like ints on most systems) that contain a 32 bit address to a memory location (where they point). Arrays obviously point to the beginning of an array, so *arr == arr[0]. While pointers can point to anything. When you declare an array (arr[5], arr[1000], etc.) it makes a pointer named arr as well as reserves whatever space is in between the brackets (5 or 1000). But when you declare a pointer (*arr), it does not reserve any space. Otherwise, the variable arr in both cases is simply a pointer. Also, if you want to be confusing, you could even dereference your pointers like so: pointer[0], instead of *pointer.

As a final note example, we can look at something like: int * (*arr)[5][7] and analyze both what it is and what the compiler is doing:

First, it is a pointer named arr (1), to an array length 5 (2) each to an array length 7 (3) but because an array length n is just a pointer to a reserved location in memory, so really (2) is an array length 5 to a pointer (pointing to memory blocks of size 7). Finally, each of the memory blocks of size 7 (3) is of type int * (4).

So, it is a pointer to an array length 5 of pointers to arrays of length 7 of type int *!

I hope this helps! I know I had a lot of fun playing with C and seeing what was possible and what different things did =)

A pointer is the address of another object. An array is a contiguous block of objects. So:

```int *a[5];
```

a is an array of 5 pointers to int. This means that a represents a block of 5 contiguous address values, where each of those values can hold the address of an int.

```int (*b)[5];
```

b is a pointer to an array of 5 ints. This means that b is a single address value, where that value can hold the address of an array of 5 ints.

```int *(*c)[5];
```

c is a pointer to an array of 5 pointers to int. This means that c is a single address value, where that value can hold the address of an array of 5 pointers to int. This could hold the address of the first object a, so c = &a; would be valid.

int *arr[5] is an array of five int*s. int (*arr)[5] is a pointer to an array of five ints. int *(*arr)[5] is a pointer to an array of int*

Generally, one makes a typedef:

```typedef int fiveintarray[5];

typedef int* intptr;
typedef intptr fiveintptrarray[5];
```

And then uses it:

```fiveintarray array;  //array of five integers
fiveintarray* pointer_to_array; // pointer to array of five integers

fiveintptrarray array; //array of five pointers to integers
fiveintptrarray* pointer_to_array;  //pointer to array of five pointers to integers
```

• int *arr[5] -> an array, of length 5, of pointers to int
• int (*arr)[5] -> a pointer to int arrays of length 5
• int *(*arr)[5] -> a pointer to a pointer to int arrays of length 5