lightatdawn
#include <stdio.h> //for printf #include <string.h> //for strcpy //------------------------------------------ // ARRAYS: What really goes on //------------------------------------------ //------------------------------------------ // Example #1: Storing text in an array //------------------------------------------ void Example1() { /* First, lets look at arrays in a common use. In this scenario, many new programmers dont realise that they are using an array, or what exactly it is thats happening behind the scenes. */ char String[13]; strcpy(String, "Hello World!"); printf("Array Contains: %s\n", String); /* So what happened there? Well, on the first line we declared our variable. Its an array of type char with 13 elements. Each element of the array is going to hold one character of the string we want to print. The next line copies our string into that variable. Visualizing the array: ----------------------------------------------------- Element# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| ----------------------------------------------------- Value | H | e | l | l | o | | W | o | r | l | d | ! | | ----------------------------------------------------- Notice that the first element is _not_ number 1, its 0. Thats because an array is always mapped from 0 to n-1. This means that the thirteenth element of our array is #12. Another question you're probably asking in this situation is: Whats that blank space at the end? Well, since we're using this array for text, and we want to be able to perform actions like strcmp, strcpy, and the like, we need to have some way to tell those functions where the end of the text is. Without any marker, the function would keep reading the array long past its last element, which could cause all sorts of unpredictable behavior, but would most likely crash your program. Thats where the NULL Terminating Character comes into the picture. Though we cant see it happening, the text "Hello World!" contains this magical NULL character at the end. Our compiler automcatically does this for us when it reaches the "Hello World!" string. Then, when its copied with strcpy into the String array, there has to be room for it. If we try to strcpy to an array that isnt big enough to hold it, strcpy tells us this: "No overflow checking is performed when strings are copied or appended." Thats bad. We must make sure that we never ever use memory that doesnt belong to us. */ } //------------------------------------------ // Example #2: Using an array as a lookup table //------------------------------------------ void Example2() { /* Now, lets look at using arrays for simple data storage. This is a very important and helpful use of arrays. */ int AgeOfFamily[4] = {0,0,0,0}; int i; //for the for loop counter AgeOfFamily[0] = 35; AgeOfFamily[1] = 33; AgeOfFamily[2] = 6; AgeOfFamily[3] = 4; for(i = 0; i < 4; i ++) { printf("Age of family member %i is: %i\n", i, AgeOfFamily[i]); } /* So what happened there? Well, on the first line we declared our variable. Its an array of type int, with 4 elements. Each element is going to hold the age of one of the members of a family. Notice I initialise all values to 0. Thats this part: "= {0,0,0,0}". Even though we're setting all 4 values of AgeOfFamily directly afterwards, its a good idea to have a default initialisation. In larger programs its easy to get confused and wind up using a variable that has never been set. This can lead to all kinds of confusing results and is often very hard to debug. Next we're going to set each element of the array: AgeOfFamily[0] = 35; Whats happening here is fairly obvious. 0 is the first element, and we're assigning it a value of 35. Simple. Just like any normal variable. We do the same thing for the rest of the elements, and assign different values for each. Visualising: ----------------- Element# | 0 | 1 | 2 | 3 | ----------------- Value |35 |33 | 6 | 4 | ----------------- NOTE: We have to be careful that we never do something like this: AgeOfFamily[4] = 2; That could be catastrophic. Since arrays are indexed from 0 to n-1, saying [4] is actually accessing the fifth element, or more specifically, the section of memory after the fourth element. Since there is no fifth element (barring the movie starring Bruce Willis, which I enjoyed quite a bit, and actually _does_ exist), we're accessing memory that we dont own. As I've said many times before, and will continue to say: This is something that should never be done. Bad things will happen. The worst part being that bad things will not _always_ happen every time. That means that your program might run fine when you test it, but crash later on. That makes it really hard to debug, since you may already have moved on long ago. Next up: We use a "for" loop to cycle through each element of the array and display its contents. This demonstrates how useful it is to use arrays in this instance (and so many others). Without the array, we would need a variable for each family member, and we would need to deal with each one separatly. Thats not too horrible with 4 family members... but imagine you were cataloging all the childrens ages in an elementary school! */ } //------------------------------------------ // Example #3: Multi-Dimensional Arrays //------------------------------------------ void Example3() { /* Getting more complicated... and more useful. We now look at 2D arrays and their uses. */ int Grid[3][3] = {16,32,64, 10,11,12, 99,98,97}; int x, y; //for the for loop counters for(y = 0; y < 3; y ++) { for(x = 0; x < 3; x ++) { printf("x%i y%i: %i ", x, y, Grid[y][x]); } //Every time we reach the end of a row, move down one space printf("\n"); } /* So what happened there? Well, on the first line we declared our variable. Its an array of type int, with a total of 9 elements; 3 rows x 3 coloumns = 9 elements in all. This array works just like the previous example except that we now how two dimensions to work in. This is a little more complicated to visualise, but lets try: ---------------- |x0y0|x1y0|x2y0| ---------------- |x0y1|x1y1|x2y1| ---------------- |x0y2|x1y2|x2y2| ---------------- Just like always, we still have to be careful not to access either dimension of the array outside its bounds. "Grid[2][3] = 0;" is _not_ an okay thing to do. Remember: arrays index from 0 to n-1, so our 3x3 arrays third (and last) element in both directions is 2. And then, just like in our previous example, we loop through the array and display its contents. Since this array has two dimensions, we have to loop through both of them. First we loop through each coloum in the first row. When a row is done, we move to the next row and repeat. */ } //------------------------------------------ // MAIN //------------------------------------------ int main(void) { printf("*** Example # 1 ***\n\n"); Example1(); printf("\n\n*** Example # 2 ***\n\n"); Example2(); printf("\n\n*** Example # 3 ***\n\n"); Example3(); /* ARRAYS: Technical Overview (for the ambitious) An array is simply a continuous section of memory equal to the size of the variable type times the number of elements in the array. i.e. a char array with 5 elements is 40 bits long. a char is 8 bits x 5 elements = 40 bits. You will find that in certain circumstances, a sizeof operation on the array will tell you that it is larger than you expected. This has to do with variable padding and is specific to the OS. You shouldnt worry about this _right now_, as it all goes on well behind the scenes. This doesnt specifically relate to arrays, but to any variable. I'm convering here to clear up possible misunderstandings in the future. Though the first example shows the use of a char array to hold text, there is no actual letters or characters stored. What happens instead is that there is a _value_ assigned to each character on your keyboard (as well as many others). These are refered to as ASCII values. The array actually contains a number whos value corresponds with the letter/symbol/number in your string. If we actually looked in the array we'd see these values: ----------------------------------------------------- Element# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| ----------------------------------------------------- Value | 72|101|108|108|111| 32| 87|111|114|108|100| 33| 0| ----------------------------------------------------- Those numbers are the ASCII values of the characters they correspond to. Notice that the apparent space between "Hello" and "World" is not actually a space at all? 32 is the ASCII value for a space. Notice the 0 at the end? Thats our NULL terminating character. You see, even though we thought of char String[13] as a string, it really isnt. Its just an array of values, the same as the rest. If we said "printf("%i\n", String[0]);" after the strcpy, our output would be "72". */ return 0; }