Storing and accessing LOTS of data

Imagine that we wanted to calculate the first 20 Fibonacci numbers, like we did a while back. That would look something like this, right?

int num1 = 0;
int num2 = 1;
 
for(int i = 0; i < 20; ++i)
{
	printf("Number: %d\n", num1);
 
	int answer = num1 + num2;
	num1 = num2;
	num2 = answer;
}

Suppose instead of printing these numbers we wanted to store/remember them, so we wouldn’t need to calculate them every time we wanted to see what they are. We might do something like this:

int num1 = 0;
int num2 = 1;
 
int fib1;
int fib2;
int fib3;
 
for(int i = 0; i < 20; ++i)
{
	if(i == 0)
	{
		fib1 = num1;
	}
 
	else if(i == 1)
	{
		fib1 = num2;
	}
	
	else if(i == 2)
	{
		fib1 = num3;
	}
	.
	.
	.
	//eventually...
	
	int answer = num1 + num2;
	num1 = num2;
	num2 = answer;
}

Yeah, that ain’t gonna work. Maybe it works for a problem where we only need to store 20 things, but what if we needed to store 100? Or 5000? This kind of coding solution doesn’t scale very well.

So, what do we do? We need something that lets us:

  • Create many variables (or at least space for data) using one line of code
  • Access these variables/spots in a way that accounts for scale (meaning, we don’t need to individually name each one to access it!)

So far, we’ve only dealt with simple variables that hold a single value, like integers, floats, and bools:

//Variable x represents a single memory location
//with the size of an integer (usually 4 bytes)
//If we read the data (binary 0s and 1s) from this 
//memory location, we know how to interpret it 
 
int x = 47;
Variablex
Typeint
Value47
Size in memory4 bytes

But now we need something a bit different. Enter, arrays!


Arrays

An array is a data structure that allows us to store a collection of data. An individual piece of data in the array is called an element.

To create an array in C, we must specify the type of the array (is this an integer array? A float array?). We must also specify the size of the array (the number of elements it will contain):

//This is how we declare an integer array
//This array has 5 integers in it
int myNumbers[5];
 
//We can make other kinds of arrays too:
bool isAnImposter[8]; //bool array of 8 elements
char theAlphabet[26]; //char array of 26 elements
float distanceToShrine[7]; // float array of 7 elements

Whenever we make an integer variable, we are creating a single spot in memory that can hold one integer. We refer to that variable using a name, like x, nums, or ageInDogYears.

Whenever we make an integer array, we are creating SOME number of spots in memory that can hold THAT MANY integers. We refer to the array of integers using a name and an index, like myArray[5], myArray[0], or myArray[2847].

Here’s what our integer array looks like:

myArray

QUESTION

We just created an integer array called myArray above. Right after this array is created, what is the value of each element?

Now we have our array! Uh… how do we assign values to an array? And how do we access them later?

Well, we know the array’s name/identifier, same as if we’d made a single integer variable. But to access individual elements, we add a pair of square brackets on the end, with the index of the element:

//This code sets the first element of the array myArray to the value of 847
myArray[0] = 847;

Each individual element is anonymous; it doesn’t have a name. So, if we wanted to set the elements in our integer array to be multiples of 100, it’d look like this:

//This is how we declare an integer array
//This array has 5 integers in it
int myArray[5];
 
//Set the elements of the array
myArray[0] = 100; //first element, index 0
myArray[1] = 200; //second element, index 1
myArray[2] = 300;
myArray[3] = 400;
myArray[4] = 500;

We could also do this in a loop, to make it easier!

Arrays in Loops

Finish the shell of the program below, to achieve the ouput from the code block above. ONLY FILL IN THE BLANKS (do not otherwise edit the program or add more lines).

int myArray[5];
for(int i = 0; i < 5; ++i)
{
  /*PUT CODE HERE*/ = /*PUT CODE HERE*/;
}

Loops and arrays were made for each other! We can now easily write code to not only store large swaths of data, but also access/modify that data!

Warning! Boundary Checking!

Reading/Writing outside the bounds of an array is LEGAL, but completely undefined! This is a very common mistake/bug made by programers across all experience levels. But it is a particularly galling bug for new programmers.

Errors caused by out-of-bound array indexing can be tricky because the behavior really IS undefined! Your code could crash, produce an infinite loop, or present results that make no sense in the context of your program.

int main(void)
{    
	//Set the values in our new array
	int smallArray[10];
	for (int i = 0; i < 10; ++i)
    {
		smallArray[i] = i;
    }
    
	//Out of bounds!
    for (int i = 0; i < 1000; ++i)
    {
		printf("Value in smallArray:%d\n", smallArray[i]);
    }
    return 0;
}

OK, so how would we improve our Fibonacci number code, using arrays?

int num1 = 0;
int num2 = 1;
 
int fibNumbers[20];
 
for(int i = 0; i < 20; ++i)
{
	//printf("Number: %d\n", num1);
	fibNumbers[i] = num1;
 
	int answer = num1 + num2;
	num1 = num2;
	num2 = answer;
}

Copying arrays!

Arrays are special, and cannot be assigned to each other like normal variables. For example:

//This works
int x, y;
x = 5;
y = 6;
x = y; //x is now 6
 
//Create an array, set its values
int myNumbers[10];
for(int i = 0; i < 10; ++i)
{
  myNumbers[i] = 9000 + i;
}
 
//Nope, this does NOT work
int myOtherNumbers[10];
myNumbers = myOtherNumbers;