is a constant we’ll use later to set a starting capacity of our vectors internal array. 100 is an arbitrary value, and if we were writing this for real we might think a little harder about what an optimal initial capacity might be.`#define VECTOR_INITIAL_CAPACITY 100`

Vector is the definition of our Vector type.`typedef struct { ... }`

size is the current size of the vector,

capacity is the total size of the underlying array

data is a pointer to the first element of the underlying array itself.

vector_init is a function that initializes a vector struct. It sets size to 0, capacity to VECTOR_INITIAL_CAPACITY and allocates an appropriate amount of memory (vector->capacity * sizeof(int)) for the underlying data array.

vector_append appends the given value to the vector. If the underlying data array is full, then calling this function should cause vector->data to expand to accept this value. Increments vector->size.

vector_get returns a value out of a vector at the given index. If the index is below 0 or greater than vector->size - 1, this function should complain about the index being out of bounds.

vector_set sets the value at the given index to the given value. If the index is greater than the vector->size, this function should expand the vector until it is big enough to contain the index and set the value at that index. It should zero-fill all values in between. vector->size should be incremented accordingly.

vector_double_capacity_if_full doubles the underlying data array capacity if vector->size >= vector->capacity. We’ll find out later that changing the size of the array is expensive, so in order to minimize the number of times we need to resize, we double the capacity each time.

vector_free frees the memory allocated for the data array. We leave freeing of the Vector struct itself to client code (so they can use any sort of pointer they like, be it stack or heap, and then clean up after themselves).