01: A Program Is a Series of Instructions

Introduction

If you learn how to drive a car, you have to learn to handle several things in one go. You must know both about the clutch, and the gas and the brake pedals. Programming also requires you to keep a lot of things in mind, or your program will crash. While you were familiar with the interior of a car before you started how to learn to drive, you don't have that advantage when learning how to program using Xcode. In order not to overwhelm you, we leave the actual programming environment for a later chapter. First, we are going to make you comfortable with some Objective-C code, by starting with some basic math you are very familiar with.

In primary school you had to do calculations, filling in the dots:

2 + 6 = ...
... = 3 * 4 (the star * is the standard way to represent multiplication on computer keyboards)

In secondary school, dots were out of fashion and variables called x and y (and a new fancy word, "algebra") were all the hype. Looking back, you may wonder why people felt so intimidated by this very small change in notation.

2 + 6 = x
y = 3 * 4

Variables

Objective-C uses variables too. Variables are nothing more than convenient names to refer to a specific piece of data, such as a number. Here is an Objective-C statement, i.e. a line of code, where a variable is given a particular value.

//[1]
x = 4;

The semicolon

The variable named x is given a value of 4. You will note there is a semi-colon at the end of the statement. That is because the semi-colon is required at the end of every statement. Why? Well, the code snippet of example [1] may look geeky to you, but a computer does not know what to do with it at all. A special program, called a compiler, is necessary to convert the text you typed into the necessary zeros and ones your Mac understands. Reading and understanding the text a human typed is very hard for a compiler, so you need to give it certain clues, for example where a particular statement ends. Which is what you do by using the semi-colon.

If you forget a single semi-colon in your code, the code cannot be compiled, that is, it cannot be turned into a program your Mac can execute. Don't worry too much about that, because the compiler will complain if it can't compile your code. As we will see in a future chapter, it will try to help you find out what is wrong.

Naming variables

While variable names themselves have no special meaning to the compiler, descriptive variable names can make a program much easier for humans to read and hence easier to understand. That is a big bonus if you need to track down an error in your code.

Errors in programs are traditionally called bugs. Finding and fixing them is called debugging.

Hence, in real code we avoid using non-descriptive variable names like x. For example, the variable name for the width of a picture could be called pictureWidth [2].

//[2]
pictureWidth = 8;

From the big issue a compiler makes out of forgetting a semi-colon, you will understand that programming is all about details. One of those details to pay attention to is the fact that code is case-sensitive. That is, it matters whether you use capitals or not. The variable name pictureWidth is not the same as pictureWIDTH, or PictureWidth. In accordance with general conventions, I make my variable names up by fusing several words, the first without capital, and all other words making up the variable name starting with a capital, just as you can see in example [2]. This style is often called camelCase. By sticking to this scheme, I reduce the chance of programming mistakes due to case-sensitivity tremendously.

Please note that a variable name always consists of a single word (or single character, at a pinch).

While you have plenty freedom choosing variable names, there are several rules which a variable name has to conform with. While I could spell them all out, that would be boring at this point. The prime rule you must obey is that your variable name may not be a reserved word of Objective-C (i.e., a word that have a special meaning to Objective-C). By composing a variable name as contracted words, like pictureWidth, you are always safe. To keep the variable name readable, the use of capitals within the variable name is recommended. If you stick to this scheme, you'll have fewer bugs in your programs.

If you insist on learning a couple of rules, finish this paragraph. Apart from letters, the use of digits is allowed, but a variable name is not allowed to start with a digit. Also allowed is the underscore character: "_". Here are a few examples of variable names.

    Good variable names:

  • door8k
  • do8or
  • do_or
    Not allowed:

  • door 8 (contains a space)
  • 8door (starts with digit)
    Not recommended:

  • Door8 (starts with capital)

Using variables in calculation

Now we know how to give a variable a value, we can perform calculations. Let's take a look at the code for the calculation of the surface area of a picture. Here is the code [3] that does just that.

//[3]
pictureWidth=8;
pictureHeight=6;
pictureSurfaceArea=pictureWidth*pictureHeight;

Surprisingly, the compiler doesn't nitpick about spaces (except within variable names, keywords etc.!). To make the code easier on the eyes, we can use spaces.

//[4]
pictureWidth = 8;
pictureHeight = 6;
pictureSurfaceArea = pictureWidth * pictureHeight;

Integers and floats

Now, take a look at example [5], and in particular the first two statements.

//[5]
pictureWidth = 8;
pictureHeight = 4.5;
pictureSurfaceArea = pictureWidth * pictureHeight;

Numbers in general can be distinguished into two types: integers (whole numbers) and fractional numbers. You can see an example of each in the statements [5.1] and [5.2], respectively. Integers are used for counting, which is something we will do when we have to repeat a series of instructions a specified number of times (see chapter 7). You know fractional or floating-point numbers, for example, from baseball hitting averages.

The code of example [5] will not work. The problem is that the compiler wants you to tell it in advance what variable names you are going to use in your program, and what type of data they are referring to, i.e. integers or floating point numbers. In geek-speak, this is called "to declare a variable".

//[6]
int pictureWidth;
float pictureHeight, pictureSurfaceArea;
pictureWidth = 8;
pictureHeight = 4.5;
pictureSurfaceArea = pictureWidth * pictureHeight;

In line [6.1], int indicates that the variable pictureWidth is an integer. In the next line, we declare two variables in one go, by separating the variable names with a comma. More specifically, statement [6.2] says that both variables are of type float, i.e. numbers that contain fractional parts. In this case it is a bit silly that pictureWidth is of a different type than the other two variables. But what you can see is that if you multiply an int with a float, the result of the calculation is a float, which is why you should declare the variable pictureSurfaceArea as a float [6.2].

Why does the compiler want to know whether a variable represents an integer or a number with a fractional part? Well, a computer program needs part of the computer's memory. The compiler reserves memory (bytes) for each variable it encounters. Because different types of data, in this case int and float, require different amounts of memory and a different representation, the compiler needs to reserve the correct amount of memory and to use the correct representation.

What if we are working with very big numbers or very high precision decimal numbers? They wouldn't fit in the few bytes reserved by the compiler, would they? That's right. There are two answers to this: first, both int and float have counterparts that can store bigger numbers (or numbers with higher precision). On most systems they are long long and double, respectively. But even these can fill up, which bring us to the second answer: as a programmer, it will be your job to be on the watch for problems. In any case, it is not a problem to be discussed in the first chapter of an introductory book.

By the way, both integers and decimal numbers can be negative, as you know for example from your bank account. If you know that the value of a variable is never negative, you can stretch the range of values that fit in the bytes available.

//[7]
unsigned int chocolateBarsInStock;

There is no such thing as a negative number of chocolate bars in stock, so an unsigned int could be used here. The unsigned int type represents whole numbers greater than or equal to zero.

Declaring a variable

It is possible to declare a variable and assign it a value in one go [8].

//[8]
int x = 10;
float y= 3.5, z = 42;

It does save you some typing.

Data Types

As we have just seen, the data stored in a variable can be one of several specific types, for example an int or a float.

In Objective-C, simple data types such as these are also known as scalar data. Here is a list of the common scalar data types available in Objective-C:

Name Type Example
void Void Nothing
int Integer ...-1, 0, 1, 2...
unsigned Unsigned integer 0, 1, 2...
float Floating point number -0.333, 0.5, 1.223, 202.85556
double Double precision floating point number 0.52525252333234093890324592793021
char Character hello
BOOL Boolean 0, 1; TRUE, FALSE; YES, NO.

Mathematical operations

In the previous examples, we performed a multiplication operation. Use the following symbols, officially known as operators, for doing basic mathematical calculations.

+  for addition
-   for subtraction
/  for division
*  for multiplication

Using the operators, we can perform a wide range of calculations. If you take a look at the code of professional Objective-C programmers, you will come across a couple of peculiarities, probably because they're lazy typists.

Instead of writing x = x + 1; programmers often resort to something else like [9] or [10]

//[9]
x++;

//[10]
++x;

In either case this means: increase x by one. Under some circumstances it is important whether the ++ is before or after the variable name. Check out the following examples [11] and [12].

//[11]
x = 10;
y = 2 * (x++);
// x is now 11 AFTER the preceding line was calculated
// y is 20

//[12]
x = 10;
y = 2 * (++x);
// x is also now 11 and was BEFORE the preceding line was calculated
// y is 22

In example [11], when all is said and done, y is set to 20 and x is now set to 11. In contrast, in statement [12.2], x is incremented by one before the multiplication by 2 takes place. So, in the end, x is set to 11 and y is set to 22. The code of example [12] is equivalent with example [13].

//[13]
x = 10;
x++;
y = 2 * x;
// actually ++x or x++ would be interchangeable at line [13.2] in this instance

So, the programmer has actually merged two statements into one. Personally, I think this makes a program harder to read. If you take the shortcut that is fine but be aware that a bug may be lurking there.

Parentheses

It will be old hat for you if you managed to pass high school, but parentheses can be used to determine the order in which operations are performed. Ordinarily * and / take precedence over + and -. So 2 * 3 + 4 equals 10. By using parenthesis, you can force the lowly addition to be performed first: 2 * (3 + 4) equals 14.

Division

The division operator deserves some special attention, because it makes quite a difference whether it is used with integers or floats. Take a look at the following examples [14, 15].

//[14]
int x = 5, y = 12, ratio;
ratio =  y / x;

//[15]
float x = 5, y = 12, ratio;
ratio =  y / x;

In the first case [14], the result is 2. Only in the second case [15], the result is what you'd probably expect: 2.4.

Booleans

A Boolean is a simple logical true or false value. 1 and 0 stand for true and false are often used interchangably, and can be considered equivalent:

True False
1 0

They are frequently used in evaluating whether to perfom some action depending upon the boolean value of some variable or function.

Modulus

An operator you're probably unfamiliar with is % (modulus). It doesn't work as you might expect: the modulus operator is not a percentage calculation. The result of the % operator is the remainder from the integer division of the first operand by the second (if the value of the second operand is zero, the behavior of % is undefined).

//[16]
int x = 13, y = 5, remainder;
remainder =  x % y;

Because 5 goes into 13 fully only 2 times (5 * 2 = 10), the remaining 3 (13 - 10 = 3) is the result.

Here are a few more examples of modulus:

21 % 7 is equal to 0
22 % 7 is equal to 1
23 % 7 is equal to 2
24 % 7 is equal to 3
27 % 7 is equal to 6
30 % 2 is equal to 0
31 % 2 is equal to 1
32 % 2 is equal to 0
33 % 2 is equal to 1
34 % 2 is equal to 0
50 % 9 is equal to 5
60 % 29 is equal to 2

It can come in handy at times, but note that it only works with integers.

One common use for modulus is to determine if an integer is odd or even. If it is even, then a modulus of two will equal zero. Otherwise it will equal another value. For example:

//[17]
int anInt;
//Some code that sets the value of anInt
if ((anInt % 2) == 0)
{
NSLog(@"anInt is even");
}
else
{
NSLog(@"anInt is odd");
}