Arrays

Arrays are a method of sequentially storing a type of variable. One of the most common uses you'll have for an array is an array of chars, known as a "string". A string is simply an array of chars with a special character to signify the end of the array/string, the null terminator character, '\0' (ASCII value 0x00).

What is an array?

An array is simply a chunk of memory set aside for the specified number of variables, and a pointer directed to the first of these variables. This is why arrays 'start' at index 0, as the number inside the square brackets is an offset from the pointer to the first element.

For example, assume the following array:

int intArray[5] = {7, 12, 4, 9, 2};

intArray is a pointer to the memory containing first element of the array, and if we offset this pointer by 0, we point to the memory containing 7. That's what's meant by the notation intArray[0]. In the same way, intArray[2] refers to memory 2 steps away from the first element, and will retrieve the value 4

What's with the square brackets?

When you refer to an element with square bracket notation, this offsets and dereferences the pointer. That is, the following notations are the same thing:

intArray[3] <==> *(intArray + 3)

In the second method, we can see we offset the intArray pointer by 3, and then dereference the pointer to retrieve the value of the memory being pointed to. The square bracket notation saves a lot of typing and some mental load in trying to understand what we're looking at.

So arrays are just pointers?

Not quite. As I mentioned earlier, arrays are pointers and a chunk of memory to hold a number of variables. For example, you can't assign an array to another value:

int a[5] = {0};
int b[10] = {0};
int c[5] = {0};

// The following lines are invalid
// a = a;
// a = b;
// a = c;

However, you can set a pointer to the value of an array:

int a[5] = {0};
int* p;

p = a;
p[2] = 10;

// The following lines are invalid
// a = p;

So arrays and pointers aren't quite the same, for instance pointers can be assigned to, while arrays cannot. Also notice that we can still use the square bracket notation with a pointer.

Declaring an array

Arrays are a fixed size (decided at declaration), and you can't use a variable to declare the size of an array, e.g.

#include <stdio.h>

int main(){
    int size;
    
    printf("Please enter the size of the array: ");
    scanf("%d", &size);
    
    int array[size] = {0};
    
    return 0;
}

The above is not valid C, as the size of array needs to be determined at compile time. Even something as simple as

int size = 20;
int array[size] = {0};

is a no-go.

Jacob note: Well, not quite true. From C standard 99 onwards you can define an array with a variable defined size. However... I find this weird, because it kind of breaks my knowledge of the stack :P One actual limitation of this is that you can't initialise a variable length array.

Creating an array with undetermined size

To create an array with a size determined while the program is running, we need to use malloc() to create our own chunk of memory, instead of relying on memory from the stack. Modifying our example above where we get the size of the array from the user:

#include <stdio.h>
#include <stdlib.h>

int main(){
    int size;
    
    printf("Please enter the size of the array: ");
    scanf("%d", &size);
    
    int* array = malloc(sizeof(int) * size);
    if (array == NULL){
        printf("Not enough memory!");
        abort();
    }
    
    free (array);
    
    return 0;
}

Now we've set aside enough memory for size ints. Notice here that we've kind of 'ditched' arrays, as we're simply dealing with a pointer to memory (remember there's a difference!), but we're using the idea of them conceptually. As shown previously, we can still use square bracket notation with our pointer to use this pointer in a way familiar to using an array.

To learn more about malloc() and free() check out <page that has not yet been written, let me know if you want it!>