You can see an index of all the posts in this series: go to index,
If you want to review where I got to by this point, here are the starter files from the end of the previous post: a first program.
In the previous post, I began constructing the first C program by using printf to display information to the user. So far I’ve just been showing static information. In this program though, I also need to create and store information dynamically. For example, I will need somewhere to store the words that I choose from each list.
I can do this in C using variables. A variable is a little chunk of memory that’s been set aside to store a value. Unlike the static information I’ve been looking at so far, the value stored in a variable can, as the name suggests, vary. So how do I know which bit of memory to put my variables in? Well fortunately I don’t have to worry about that level of detail – I just give each variable a unique name to identify it and C takes care of the rest.
Think of C’s role in variable management as being somewhat like a cloakroom or coat check attendant. When I hand over my coat, I neither know nor care which rail or hanger my coat is stored on – that’s the attendant’s job. All I want to be sure of is that, when I hand over the ticket, I get back my coat and not some random coat left by another person.
In C, the area of memory that variables are stored in (which is known as the stack) is like the cloakroom, the information I store there is like my coat and the name I give to the variable so it can be identified is like the ticket. So let’s say I want to store the number 73, I might say to C: “Please hang this number up somewhere safe and give it the name ‘score’. ” Later on when I want to add some points to my score, I’ll say: “I’d like the number I left you with the name ‘score’ please”. C then hands it back to me so I can add some points to it, then I hand it back over until I need it again.
Now, in many cloakrooms I can leave different types of items, such as coats, umbrellas, hats and bags. The attendant needs to know which type of item I want to leave because there is a different charge for each item type. Well the same is true when storing variables with C. I need to tell C what type of information I am storing – for example is it a whole number, a number with a fractional part, some text etc.? And just like the cloakroom attendant needs to know the type so he knows what to charge, C needs to know the type because each type requires a different amount of memory and is used in a different way.
So how does this work in practice? Well let’s take my score example. I know I only want to store whole numbers, so I would create this variable with the following statement:
int score;
This is called a variable declaration. The int bit tells C that I want to store a whole number. Int is short for integer, which is the mathematical term for a number without a fractional part, e.g. 73. I’d use a different type here if I wanted to store a different sort of number, for example float for a floating point number (a number with a fractional part). The second part, score, is the name I want to use to identify the variable. Notice that I haven’t given C a value to put in this variable yet. So what’s in there? What would I get if I asked for it? Well, I’ll try it.
I opened the Buzzword program in my editor. I amended my program so it looked like the following (lines 13 and 14 are new):
/******* * Buzzword * * A program to create amusing fake jargon *******/ #include <stdio.h> int main(int argc, const char * argv[]) { printf("Buzzword Generator\nBased on a program from Creative Computing, Morristown, New Jersey\n\n\nThis program prints highly acceptable phrases in 'educator-speak' that you can work into reports and speeches. Whenever a question mark is printed, type a 'Y' for another phrase or 'N' to quit.\n\n\nHere's the first phrase:\n"); int score; printf("\nScore contains: %i\n", score); return 0; }
You can see I am using printf in a slightly different way here. Previously I’ve just used printf to display static information, but it has a few more tricks up its sleeve. The f in printf stands for “formatted”, because it also accepts things called conversion specifiers. These work in a similar way to the escape sequences I used in the previous post. What a conversion specifier does is tells C, “I’d like to insert this type of information at this point please.”
Conversion specifiers always start with %, which is followed by a single conversion character code representing the type of information I want to show. In this case I’ve used i (for integer – but note that I could also use %d used for an integer – either is fine, as long as I’m consistent). I also have to tell C what information to show at this point, so for each conversion specifier I include, I must also add a comma after the closing quote mark and a variable or some information of the correct type. In this example I want to show the score, so I’ve added my score variable.
When I saved, compiled and ran this, I saw this:
You’d be forgiven for looking at this and making the assumption that C always sets new int variables to 0. But wait! Here’s exactly the same program running on Windows 10:
Woah! Where has that number come from? Depending on the computer, and the compiler, I might see a completely different number, or I might see 0. The main thing to remember is that when I declare variables in this way, they contain garbage. I shouldn’t rely on them having any particular value until I set one. This is known as initialisation, and, once I’ve declared a variable, I can do it like this:
score = 73;
I can also declare a variable and initialise it in a single step, like this:
int score = 73;
I’ll try this now. I changed the current variable declaration in my program so it looked like the line above and then tried saving, compiling and running again. This is what I saw:
So that’s great – I can store a number in a variable, and get it back again when I need it. But if this was a real score in a real game, I’d probably expect it to go up every now and then as the player accumulated points. C allows me to manipulate variables using operators. Operators perform common arithmetic operations such as adding, subtracting, multiplying and dividing. So, if my player had just won 10 points, I could add these to their score with a statement like this:
score = score + 10;
I can also use other variables in the equation. So if I had another variable called penalty, that contained the number of points to be subtracted if the player incurs a penalty, I’d remove those points with:
score = score - penalty;
If I wanted to multiply the points by a bonus factor stored in the variable called bonus, I’d use:
score = score * bonus;
Note that I use an asterisk (*), not an x for multiplication.
If I wanted to divide the points by the time taken, which I’d stored in a variable called time, I’d use:
score = score / time;
Again, notice that I use a forward slash (/) and not ÷ for division.
I can also combine operators in a single expression, e.g.:
score = score * bonus / time;
If score was 1000 and bonus was 2 and time was 20, this expression would first calculate score * bonus, which equals 2000, and then divide that by time, giving 100.
However, consider this expression:
score = score - penalty * bonus;
If score was 1000, penalty was 50 and bonus was 2, you might expect this expression would first calculate score – penalty, which equals 950, and then multiply that by bonus, giving 1900. But the number that would actually be put into score would be 900! Why is this?
Operators in C have what is known as an order of precedence. The order in which operators are applied within an expression depends on their order of precedence. You can find a table showing this order here: Operators in C and C++. You need to be looking at the table half way down the page in the Operator Precedence section, not the one at the top. This is a big table with lots of operators I haven’t used yet – I’ll introduce more of them in future posts. Where operators have the same precedence, e.g. * and /, they are applied in order of associativity, which you can see in the final column of the table. In the case of * and /, this is from left to right.
As you can see from the table, multiplication and division have a higher precedence than addition and subtraction, so what is actually happening in my expression above is that C is first calculating penalty * bonus, which is equal to 100 and then subtracting that from score, giving 900. If I wanted the subtraction to be evaluated first, I can use parentheses, like this:
score = (score - penalty) * bonus;
Parentheses will take precedence over other operators. So, in this case, the part of the expression in parentheses will be evaluated first, giving me the desired result of 1900.
OK, that’s all good, but in my Buzzword program I am much more concerned with letters than numbers. Well fortunately there’s a variable type that stores letters too. In my program I changed the variable declaration/initialisation, and the printf line that follows it to:
char letter = 'a'; printf("\nLetter contains: %c\n", letter);
Here I’ve changed the type of my variable to char, which is short for character. Note that when I initialise char type variables, the initial value is placed within single quote marks. I’ve also changed the conversion character to c (for char).
When I built and ran this, this was the output:
OK great, but it’s going to be a bit long-winded if I have to do this for every letter of every word in my program. Fortunately C has a way of dealing with collections of variables. Instead of declaring and initialising lots of individual variables, each with their own name, I can create a group of variables and give them a single name. This structure is known as an array.
For example, let’s say rather than recording just a single score, I wanted to keep track of the last five scores that a player had achieved. I could declare an array like this:
int scores[5];
This looks similar to the way I declared a single int variable, but now I’ve added square brackets with a number at the end of the declaration. This tells C, “I don’t want a single variable, I want a group of five of them, and I want the group to be called scores”.
So, now that I have my array, how do I access the individual scores within it? The answer is that I use the square brackets again, but this time the number inside them refers to a particular variable in the array, like this:
scores[0] = 73;
This tells C, “please store the number 73 in the first variable of the group called scores”. Each variable within an array is called an element. Note that the first element of an array is numbered 0. That means the last element is always one less than the size of the array. In this case, to initialise the last element of scores I would use an index number of 4:
scores[4] = 99;
If I try to do this:
scores[5] = 321;
I will get an error, because that element doesn’t exist.
Here’s an example of how I could declare my array and initialise all the elements:
int scores[5]; scores[0] = 73; scores[1] = 22; scores[2] = 101; scores[3] = 40; scores[4] = 99;
You’ll recall though, that there was a way I could declare and initialise single variables with a single statement. The same is also true of arrays. I do it like this:
int scores[] = {73, 22, 101, 40, 99};
This does exactly the same as the six statements in the previous example. Note that when I declare an array like this, I don’t have to include the number of elements between the square brackets because C can work this out based on the number of elements I’ve included in the initialisation list.
When I want to create a group of chars rather than ints I could do this:
char word[] = {'h','e','l','l','o'};
I could now get the value of an individual element in this array, like this:
printf("\nThe third letter is %c\n", word[2]);
The number in square brackets that I use to reference a particular element is called an index or subscript. Remember that array elements are numbered from 0, so to get the nth element of the array, I would use the index n-1.
This is all well and good, but in C the reason I often want to group a set of characters together, is because I want to treat them as a single word or phrase. C provides me with a handy shortcut for doing this:
char word[] = "hello";
Note that this also results in an array of chars, but it is not quite the same as the char array I created earlier. This type of character array is called a string, because it is a string of characters. When I declare a char array like this, C adds an additional hidden element at the end. This is a special value called the null character, which I can also enter manually using the escape sequence \0. When C encounters this value it knows that it has reached the end of the string.
I’ve already been using strings, when I create a printf statement like:
printf("\nGood morning\n");
The phrase between the quotes is known as a string literal because it is a string that is embedded within the program code. I’ve used other literals when I’ve embedded other types of data directly in my program. For example, the 73 in this statement is an integer literal:
int score = 73;
I want to see strings at work. I replaced the current variable declaration/initialisation and the following printf statement with these statements:
char word[] = "hello"; printf("\nThe third letter of %s is %c\n", word, word[2]);
When I saved, compiled and ran the program I saw the following output:
This has introduced another conversion specifier, s (for string). You can see from this example, that once I have declared and initialised a string, I can work with the whole string or with individual characters (elements of the array).
In the next part of this series you’ll see how I can use arrays to generate the lists of words I need for Buzzword. In the meantime, here’s something to think about. How could I remove the two lines of code I just added and replace them with code that does the following:
- Display the phrase: “10 green bottles hanging on the wall”. To make this a little bit more challenging, I will try to create the phrase so that the number at the beginning and the word ‘green’ are stored in variables.
- When I have managed to get the phrase to display successfully, I will try to change it to “9 blue bottles hanging on the wall” by changing the values I use to initialise the two variables.
I’ll show the solution I came up with in the next post in this series.
Be First to Comment