Extension 6: Incrementation


In the last Lesson, I used the following expression on Line 11 of the first example:

n = n + 1

This is perfectly valid code. The associativity of the equals operator (=) is right-to-left—this means that whatever is on the right of the operator is evaluated first, then the result is assigned back to the variable or identifier on the left side. So in this case, the program first determines the value of n + 1, and assigns this new value back to n. This method is fine, but there are more elegant solutions.

Operator-Equals

The following is completely equivalent to the above example:

n += 1;

What this is saying is to evaluate the result of n + 1 and assign it back to n—the identical meaning to the above example. The difference is that in this case the code is clearer, and much more concise. The following are all valid:

n += 3;    // Same as n = n + 3;
n -= 3;    // Same as n = n - 3;
n *= 3;    // Same as n = n * 3;
n /= 3;    // Same as n = n / 3;
n %=3;     // Same as n = n % 3;

In each case, the value of n operator 1 is evaluated, then the result is assigned back to n. This construct is highly recommended, and is used almost exclusively in place of the original.

++ and ––

That should be two minus signs; WordPress is over-optimizing the typography.

Returning to the concept of loops, most loops execute a specific number of times; this number is often determined by an upper limit value, and a counter is used to keep track of the increments until the maximum is reached. In these cases, the counter would be incremented by 1. In the original example, the code to do this was

n = n + 1;

As described above, n += 1; is also valid.

But incrementing (or decrementing) by 1 is such a popular thing to do in code (believe it or not) that Objective-C (and plain C) has a special construct to do just that:

n++;     // Increment by 1
n--;     // Decrement by 1 

As with the above construct, the double-plus or double-minus is used almost exclusively when the program needs to increment or decrement by 1. At the very least, it saves you typing; at best, compilers can produce more concise and efficient code when the double-plus or double-minus is used (Prata, C Primer Plus, 5th Edition, SAMS: Page 146). Note that these operators increment by exactly 1, and can only be used with integers.

One thing to note is that the increment and decrement operators have a prefix and postfix version.

Prefix versus Postfix

Compare the following statements:

int n = 4;
if (n++ < 5)     // Case 1
   NSLog(@"n is %d", n);
n = 4;           // "Reset" value of n
if (++n < 5)     // Case 2
   NSLog(@"n is %d", n);
NSLog(@"n is %d", n);     

The output is:

n is 5
n is 5 

There are three NSLogs in the code, yet only two lines of output. This reflects a subtlety in the increment/decrement operators. Why does this happen?

In Case 1, the value of n is compared with 5 first, and then incremented. n was initially set to 4; 4 is less than 5, so the initial NSLog executes. However, by that point, n had been incremented to 5.

In Case 2, the value of n is first incremented, then compared to 5. So n first becomes 5; 5 is not less than 5, and so the second NSLog does not execute. However, the final NSLog displays the value of n, which is now 5.

In the majority of cases, where only the end result is concerned, using the prefix or postfix does not matter—in either case, the end result is 5. However, for intermediate cases, such as the code within the if() statements, the choice does matter.

Finally, happy holidays to all my readers! Thanks for stopping by, and I hope you’ll come back for more. We’ll be getting into the good stuff (objects and more advanced programs) soon—probably before 2011 rolls around. Merry Hanukkah (and Kwanzaa, and whatever else is politically correct)! 😀

Extension 5: The switch Statement


The switch() statement is used in place of a chain of if()else if()else if()else if()else construct, where such a chain does not lead to very readable, follow-able code. The switch() statement is designed for this situation. Here is the general format:

switch(expression or variable)
{
     case value1:
          // Program statement
          // Program statement
          ...
          break;
     case value2:
          // Program statement
          // Program statement
          ...
          break;
     case value3:
          // Program statement
          // Program statement
          ...
          break;
     ...
     case valueN:
          // Program statement
          // Program statement
          ...
          break;
     default:
          // Program statement
          // Program statement
          ...
          break;
}

The expression value in the parentheses at the beginning of the statement is compared to each of the values, and when one of them matches, the following code (note the colon, and the lack of braces around each case), the code below is executed. It then breaks out of the rest of the switch, to avoid executing the rest of it (“overflowing” into the code for the next condition). This can sometimes be used intentionally, but for most of the time make sure to use the break; statement.

If none of the conditions match (the else of an if()else block), the code under the default condition is executed.

The following is an example of a switch() statement and the equivalent if()else block:

// This is an example of a switch statement.
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *operator = [[NSString alloc] init];     // We will talk in depth about NSString later on down the road.
	// Assume operator has been initialized to a valid value
	// Valid values for operator are @"+", @"-", @"*", and @"/"

	switch (operator) {
		case @"+":
			NSLog(@"Operator is for addition.");
			break;
		case @"-":
			NSLog(@"Operator is for subtraction.");
			break;
		case @"*":
			NSLog(@"Operator is for multiplication.");
			break;
		case @"/":
			NSLog(@"Operator is for division.");
			break;
		default:
			NSLog(@"Unknown operator.");
			break;
	}

    [pool drain];
    return 0;
}

This code should be rather self-explanatory; operator is compared to the values after each case, and if one of them matches, the executes the corresponding NSLog and breaks out of the switch. If none of them match, then it hits the default statement.

The equivalent if()else block follows:

// This is an example of a switch statement.
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *operator = [[NSString alloc] init];
	// Assume operator has been initialized to a valid value
	// Valid values for operator are @"+", @"-", @"*", and @"/"

	/* Note that NSString actually has a comparison method, and that
	   this method of comparison is not guaranteed to work. We are
	   overlooking that at the moment for the sake of education. */
	if (operator == @"+")
		NSLog(@"Operator is for addition.");
	else if (operator == @"-")
		NSLog(@"Operator is for subtraction.");
	else if (operator == @"*")
		NSLog(@"Operator is for multiplication.");
	else if (operator == @"/")
		NSLog(@"Operator is for division.");
	else
		NSLog(@"Unknown operator.");    [pool drain];
    return 0;
}

This code does the same thing as the switch statement above (bar the comment in bold).

The switch() statement is makes more logical sense, but some people find it annoying. It all comes down to a matter of personal preference. No big deal.

BTW less than a month after the previous milestone we are at 2000 views! Thanks to everyone who stopped by, and I hope to see you back!

Postscript: Wikipedia has a nice article on controlling program flow. It is a bit dense, but for anyone who is interested, go check it out! And while you’re there, you might as well see the article on the switch statement as well.

Objective-C Lesson 4: if() statements and Booleans


As mentioned before, boolean values are simply true-or-false. In Objective-C, unlike many other languages, they are represented as YES or NO:

BOOL trueOrFalse = YES;
BOOL gameOver = NO;

Internally, however, they are stored as zero and one.

if() Statements

The if() statement is used to check for conditions. Just like we use if in normal English, if() in code is used to test for a condition—they test for the value of a boolean (or any int—in this case, a zero is considered false; any non-zero value is true).

Here is a simple example of booleans:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	BOOL trueOrFalse = YES;
	if (trueOrFalse)
		NSLog(@"trueOrFalse is true.");
	if (1)
		NSLog(@"1 is considered to be true.");
    [pool drain];
    return 0;
}

The output is:

trueOrFalse is true.
1 is considered to be true.

Simple enough, and quite logical.

Obviously, if the condition was false, the statements following would not be executed. The following example demonstrates:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	BOOL trueOrFalse = YES;
	if (trueOrFalse)
		NSLog(@"trueOrFalse is true.");
	if (1)
		NSLog(@"1 is considered to be true.");	// If false, statement following is not executed
	trueOrFalse = NO;
	if (trueOrFalse)
		NSLog(@"I lied. trueOrFalse is not true.");
	if (0)
		NSLog(@"This line should not appear.");
    [pool drain];
    return 0;
}

Unsurprisingly, the results are the same as above.

One important point to make here: if you only have one statement after the if(), you can just leave it like it is above. But if you have more than one statement after the if(), you must enclose them within braces:

if (trueOrFalse) {
	NSLog(@"trueOrFalse is true.");
	NSLog(@"This second line must be within the braces.");
}

Otherwise, the second (or additional) statements will be executed, regardless of if the condition was true or not.

Extending the if() Statement

In real life though, there are often alternatives: if something is true, do “action1“; else, do “action2“. Objective-C lets you model that quite simply:

trueOrFalse = YES;
if (trueOrFalse == YES)          // The double-equals sign is a comparison; versus a single equals, which is an assignment. More on this in the next Extension.
	NSLog(@"If true, print this");     // This gets printed
else
	NSLog(@"Else, print this");        // This does not get printed
trueOrFalse = NO;
if (trueOrFalse)
	NSLog(@"If true, print this");    // This does not get printed
else
	NSLog(@"Else, print this");       // This gets printed
 

Output is:

If true, print this
Else, print this

This makes logical sense.

You can also extend this by using else if(). This is easier to explain with code:

int value = 5;
	if (value > 0)
		NSLog(@"value is greater than zero.");
	else if (value == 0)
		NSLog(@"value is equal to zero.");
	else
		NSLog(@"value is less than zero.");

Output is:

value is greater than zero.

You can have as many else if()s as you want; they simply follow each other:

int value = 5;
if (value == 6)
	NSLog(@"value is equal to 6.");
else if (value == 0)
	NSLog(@"value is equal to 0.");
else if (value == 2)
	NSLog(@"value is equal to 2.");
else if (value == 10)
	NSLog(@"value is equal to 10.");
else
	NSLog(@"value does not equal 6, 0, 2, or 10");     // This line is the output.

Pitfalls

There are a few issues that may arise with if()statements.

  • Forgetting braces: If you have more than one statement that you want to execute given a certain condition, you must enclose them within curly braces.
  • Using too many instances of if(): If you want to have a collection of related paths (if…else if…else), you must remember to use else if(). Using a chain of if()s is a completely different thing, logically. Think about it.
  • Forgetting the last else: The final else is a “catchall” statement that is executed if none of the previous if() or else if() statements are true. Don’t forget the else; otherwise, you may never get any output. For example, in the last code example, the last else statement was needed; otherwise, it might have appeared that the code was broken.

Conclusion

As you can see, the if() statement is quite simple, but very powerful—it defines “paths” down which your code can travel, based on the value of a condition. In the next Extension, we will be looking at what these conditions can be.

Oddities: Conditional Operator


The conditional operator is rather strange, but is very useful. (By the way, an operator is something that acts upon two or more values, such as the addition ‘+’ operator.) In many cases (or at least frequent enough for them to make up a new operator), programmers have had to determine the largest or the smallest of two values, and use the corresponding (largest or smallest) value. Normally, the code would be like this:

if (number1 > number2)
     return number1;
else
     return number2;

This became cumbersome. Introducing, the conditional operator:

return (number1 > number2) ? number1 : number2;

This does the same thing as the code above. The parts in bold are the required syntax; any valid expression, constant, or variable can be placed in between.

There are three parts to the conditional operator: the condition, and the two “paths”.

The condition is a boolean condition, one that would otherwise trigger an if-statement. If that is true, number1 is returned; otherwise number2 is returned.

That’s all there is to it.

Extension 3: ASCII, Booleans, Characters


Type char

A variable of type char is used to store a single character. It is denoted as a character, flanked by two single quotes. (Be careful—single quotes are used for characters, double quotes signify a string.) ‘a’, ‘;’, and ‘8’ all represent character types. The first is simply the letter a. The second is the semicolon symbol; it is not the same as the one used to mark the end of a line. The last example is the character 8, not the integer 8.

This Photograph is created using only the ASCI...

ASCII Art—Image via Wikipedia

Escape sequences, when enclosed in single quotes, are also considered to be char, even though they are composed of more than one symbol.

To print a character or escape sequence through NSLog, use %c.

ASCII Values

In C, chars are represented as 8-bit ASCII values. Internally, characters are stored as numbers, with a range from 0-127. This makes for interesting uses, including the following simple cypher program:

#import 

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    // A simple cypher program
    NSLog(@"Hello");	// Original message
	NSLog(@"%c%c%c%c%c", ('H' + 1), ('e' + 1), ('l' + 1), ('l' + 1), ('o' + 1));		// Cypher 1
	NSLog(@"%c%c%c%c%c", (('H' * 2) % 127), (('e' * 2) % 127), (('l' * 2) % 127), (('l' * 2) % 127), (('o' * 2) % 127));	 /* Cypher 2...
																															 note the use of the modulus operator
																															 to limit the domain */
	[pool drain];
    return 0;
}

The output of this program is:


Hello
Ifmmp
 KYY_

One thing to note before we analyze this program—the last output only displays four characters because the ASCII value of capital H is 72. The operation results in an ASCII value of 17, which is a “special”, non-printing character (see Wikipedia link above).

Code, Demystified

The first important line prints out the NSString constant @”Hello”. Not much to it. The next line prints out five characters, as represented by the escape sequences. Looking at the arguments to NSLog, we see that we are simply taking the characters in @”Hello” and adding one to their ASCII values. If you check the output, you’ll find that Ifmmp are just the letters of Hello, but shifted “over” by one. Note that ASCII values define all capitals before lowercase, not all letters in alphabetical order; the letters A-Z come numerically before a-z.

We do the same thing on the Cypher 2 line, except that this time there is a little bit more involved. We take the ASCII value and multiply it by 2. To keep our code neat and prevent warnings, we use the modulus operator to limit the range of the result—in this case, the result can only be between 0 and 127, exactly the range of ASCII. This is another practical use of the modulus operator—to limit the range of a result to a specific set of numbers.

Note that when you write chars in your code, you must delineate them with single quotes. Those quotes do not get printed in the final output.

Type BOOL

Boolean values are very simple—they are literally a YES or NO. In other languages, including Java and plain C, they are represented as true or false. Although initially the latter may seem more reasonable, in usage the former makes more grammatical sense. For example, in the following method call,

[self presentModalViewController:mvc animated:YES];

using the value YES makes much more sense from a reader’s perspective than true.

Booleans are simple true or false values; they are usually used to determine if a condition is true or not, and used to determine whether some code should be executed (for() statements). In Objective-C, the integer values 0 and 1 are synonymous, and can be used interchangeably (with a few exceptions). Their usage will be detailed in the next Lesson.

Extension 2: Floating-Point Operations


Not all numbers are integers. Therefore, Objective-C lets you define floating-point values—numbers with a fractional portion. There are two basic types—float and double.

Floating-point values do not follow the rules of integer division—that is, dividing by floating-point values produces floating-point results.

Type float

In certain programming languages (Java comes to mind) the float type is almost never used. In Objective-C, it is the more commonly used of the two—both for practical and memory reasons.

A floating point number must contain a decimal portion, but you can omit digits before or after the decimal point—obviously, not both. The entire number ca be prefixed by a negative sign. Therefore, 3., 1.8, .295, and -.59 are all valid floating point numbers. To display floats in an NSLog call, use %f.

Scientific Notation

As you may recall from a high-school math class, scientific notation is a method of writing absurdly large or small numbers. It takes the form 5.925×102, where the general notation is of a floating-point value followed by a multiplication, a number (generally a power of 10), and an exponent. This number is written in code with the form 5.925e4. The e, formally known as the mantissa, can be written as a capital or lowercase. The mantissa can be either positive or negative; a negative value, such as 2.25e-3, would correspond to a value of 2.25×10-3, or 0.00225.

To display scientific notation, use %e. Alternatively, you can use %g to have NSLog decide whether to display the usual value or the scientific notation—if the exponent is less than -4 or greater than 5, the scientific notation is used; otherwise, the standard floating point notation is used.

Type double

A double value is a more precise float value—the former stores twice as many digits, and on most systems it uses 64 bits.

Like Java, all floating point constants in Objective-C are double. To force a float, append either f or F to the end of the floating point value. Unlike Java, however, floats are used as a general data type for floating-point variables, due to the fact that they require less memory. The distinction is that of constants versus that of variables.

The same format specifiers apply to doubles, as well as scientific notation.

Extension 1: Integer Operations


Extensions provide a more in-depth overview of various topics. Here, I present a more in-depth discussion behind primitive data types.

Type int

As mentioned before, integers consist of individual digits. You can prefix it with a minus sign (a hyphen) to make it negative. You cannot put spaces, commas, or periods inside ints.

When dividing an integer by another, integer division occurs. In this case, the remainder of the division is dropped. Therefore, the result of 8/5 is 1, not 1.6. A practical use of this is as follows:

int number = 1234;
int thousands = number / 1000;
NSLog ("@The thousands place of %d is %d.", number, thousands);

The output of the code above is

The thousands place of 1234 is 1.

In contrast, the modulus operator (%) is used to derive the exact remainder of integer division. Therefore, 8 % 5 = 3.

Extending the above example,

int number = 1234;
int thousands = number / 1000;
NSLog ("@The thousands place of %d is %d.", number, thousands);
int hundreds = (number % 1000) / 100;
NSLog ("@The hundreds place of %d is %d.", number, hundreds);
int tens = ((number % 1000) % 100) / 10;
NSLog (@"The tens place of %d is %d.", number, tens);
int ones = (((number % 1000) % 100) % 10);
NSLog (@"The ones place of %d is %d.", number, ones);

The output of the code is

The thousands place of 1234 is 1.
The hundreds place of 1234 is 2.
The tens place of 1234 is 3.
The ones place of 1234 is 4.

The code above is rather involved, but try to figure it out. Remember, the modulus operator extracts the remainder of the division that could have been placed in its place.

Shameless Self-Promotion


To get the word out, I’d generally rely on search engines. And I can’t afford to pay Google to get listed (and most of those ads aren’t exactly reputable anyway). So, here’s some shameless self promotion. I promise I won’t really do this much more. Feel free to not read this. You may want to entertain yourself elsewhere (I’d recommend Uncyclopedia).


Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa Cups of Cocoa

iPhone App Development iPhone App Development iPhone App Development iPhone App Development

iPhone Application Development iPhone Application Development iPhone Application Development

Programming for iOS Programming for iOS Programming for iOS Programming for iOS Programming for iOS

iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App iPhone App

iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps iPhone Apps

Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps Creating iPhone Apps

iPhone Programming iPhone Programming iPhone Programming iPhone Programming iPhone Programming iPhone Programming

Developer Developer Developer Developer Developer Developer Developer Developer Developer Developer Developer

iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS iOS

App Store App Store App Store App Store App Store App Store App Store App Store App Store App Store App Store

Programming Programming Programming Programming Programming Programming Programming

iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone iPhone

iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch iPod Touch

iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad iPad

Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode Xcode

Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C Objective-C

Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple Apple

Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa Cocoa

iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK iPhone SDK

Software Software Software Software Software Software Software Software Software Software Software

Object-Oriented Programming Object-Oriented Programming Object-Oriented Programming Object-Oriented Programming


😀

Objective-C Lesson 2: Basic Variables


In almost all programs, values may change; these values are stored in variables, which, as the name implies, are designed to have varying contents as the program is used. We’ll dive right in with a sample program.

Program 2.1

// Introducing variables

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	int i;
	i = 1;
	NSLog (@"The variable i has a value of %d", i);

	i = 2;
	NSLog (@"The variable i now has a value of %d", i);

    [pool drain];
    return 0;
}

The output of this simple program is as follows:

The variable i has a value of 1
The variable i has a value of 2

Code, Demystified

Program 2.1 contains the same “boilerplate” code in the template that Xcode provides for you. It is still not necessary for now, so explanation will be deferred.
The first “real” line of the program introduces the concept of a variable.

int i;

This variable is declared to be of type int and with the name i. Before we talk about the variable type, we have to take about the choice of the variable’s name.

Variable Names

In C, all variable names (in fact, almost all names in general) must be made of lowercase and uppercase letters, digits, and the underscore character (_). The first character of the name must be a letter or underscore. Because Objective-C is a strict superset of C, the same rules apply.

Note that C and Objective-C are case-sensitive. A lowercase letter is not the same as a capital letter. Therefore, fraction, Fraction, FRACTION, and fractioN are considered four completely different names. As a result, programmers often use camel case to declare variable names of multiple words. Examples include aPairOfDice, lotsOfMoney, and someAddress.

Because of the wide variety of options available to you, make sure to choose descriptive variable names, such as taxRate instead of t. You can only thank yourself later on.

Reserved Names

The Objective-C language reservescertain words, so that you cannot use them as a name; in fact, some are reserved by C itself. For a complete list, check out this post.

Data Types

In program 2.1, the variable i was declared to be of type int. This means that i can only hold a whole-number value, without a decimal point—an integer. Integer values are one of four basic data types. The others are floating-point values, characters, and boolean values. Floating-point values are simply numbers that include a fractional portion, represented as a decimal, such as 5.2 and 10.0. Characters are any single character that you can type on your keyboard, such as ‘A’ and ‘@’ and few others. Boolean values are either true or false; in Objective-C they represented as YES and NO.

Beyond the basics, C also defines three “adjectives” to modify the size of variables. These are short, long, and unsigned. An integer declared to be short will take up less memory than a standard int, and a long will take up more space. You can also use the specifier long long to indicate even larger values, but in OS X and iOS the additional long makes no difference. unsigned is used for values that will never be negative; this effectively doubles the maximum (positive) value of a variable without doubling its storage requirement (because every single negative value can now be “mapped” to a larger positive value).

short and long cannot be used in conjunction with each other in the same variable, but unsigned, or its optional counterpart signed, may be used on any variable, short, regular, or long.

Initialization

After declaring a variable, you have to initialize it with a value; otherwise, the variable would be useless. You can do this in a single statement, along with the declaration:

int variable = 1;

Alternatively, you can declare the variable, and then initialize it sometime later (it does not have to be the next statement):

int variable;
// Some code
variable = 1;

Printing Variables

Program 2.1 introduces a few new concepts in the NSLog statements.

NSLog (@"The variable i has a value of %d", i);

The real magic happens with the %d. This is a format specifier, and tells NSLog that it should expect a variable of a certain data type, and to print the value of that variable. In this case, the type %d tells NSLog to expect an integer value, and it does receive i as an argument, which is an integer value. Therefore, NSLog looks for the value of i, and prints the integer value. This explains the output:

The variable i has a value of 1

In the next few lines, we set i to the value 2, and then use NSLog to print it.

Note that the specifier %i is also used to print integer values.

Program 2.2

// Arithmetic operations with variables
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int result;
	result = 10 + 20;
	NSLog(@"The sum of 10 and 20 is %i", result);

	result = 25 - 30;
	NSLog(@"The difference between 25 and 30 is %i", result);

	result = 8 * 9;
	NSLog(@"The product of 8 and 9 is %i", result);

	NSLog(@"The quotient of 8 and 5 is %i", (8 / 5));
	NSLog(@"The quotient of 8.0 and 5.0 is %.1f", (8.0 / 5.0));	[pool drain];
    return 0;
}

The output is:

The sum of 10 and 20 is 30
The difference between 25 and 30 is -5
The product of 8 and 9 is 72
The quotient of 8 and 5 is 1
The quotient of 8.0 and 5.0 is 1.6

Program 2.2 presents some interesting situations. To begin, we define an integer value, and name it result. We set result equal to 10 + 20. Then we have the NSLog statement print out the value of the variable result, and we use the integer specifier because the result is an integer. The next few lines does the same, but note that negative values are supported. Multiplication works as expected, but the last two NSLogs deserve some attention.

The first thing to note is that you can specify an expression as an argument to NSLog, not simply a variable. As long as the result is of the proper type, NSLog doesn’t care whether you specify an expression or a variable.

Next, note that the first division results in a value of 1. Obviously, 8 ÷ 5 ≠ 1, but this is not a mathematical error. Remember that the format specifier %i is responsible for printing integers. Also note that the values 8 and 5 are both integers. This is an example of integer division. Through integer division, only the whole-number portion of the result is reported—any fractional portions are discarded.

To get the accurate result, we have to use floating-point numbers. These numbers are only syntactically different from ints in that they include a .0 portion at the end—as in 8.0 and 5.0. To print a floating-point value, we use the format specifier %f. The .1 portion of the specifier tells NSLog to only print the first decimal point, and disregard any others that may follow. Here, we can see that the result is indeed 1.6.

How Programming Languages Work—A Brief Overview


Warning: Extremely technical information follows. Feel free to skip this section for now, but make sure you do read it sometime. It’s important enough to know, but not vital for you to begin programming.

A computer only understands a string of commands in a very basic format—machine language. At the lowest level, a computer can only process 0s and 1s—off, or on. In effect, computer is just a huge collection of billions of switches, rapidly turning on and off. A typical command that the computer understands may look like this:

00101011 11110111 10000100 01010110 00000110 10001001

Of course, having to program like this would not be very easy, and it is easy to loose track of what you’re doing. To fix this, chip makers created what is called assembly language—a language that chips understand, and will get translated to machine language, independently of the programmer. A typical command in assembly might look like this:

l_objc_msgSend_fixup_alloc:
.quad	_objc_msgSend_fixup
.ascii "long int"
.byte	0x4
.byte	0x8
.byte	0x7
.byte	0x2
.byte	0x1
.byte	0x6
.ascii "char"

Better than machine language, but still not too useful. In addition, the programmer is still interacting directly with the hardware, which increases the chances of mistakes.

Both machine language and assembly are specific to the hardware. Different hardware involves different machine and assembly code.

Higher-level languages were invented to solve of these problems. The “height” of these languages varies, but they all involve English-like syntax, and are hardware-independent. Objective-C is one such language.

The majority of these languages are passed through a compiler—a program that converts the code into assembly. Compilers are usually provided with a system; Xcode, Apple’s native development program, includes gcc, one of the most prominent compilers, as well as LLVM, an Apple-developed compiler that offers many benefits over gcc, all of which are beyond the scope of this book.

Higher-level languages allow programmers to focus on their task, and not on writing obscure code.

For anyone who’s interested in learning more, an even more technical and low-level approach will be coming. When? I don’t know.

  • Welcome

    My goal is to make CupsOfCocoa into a beautiful source for beginners to the iPhone platform to get started. Subscribe below for more, and stay tuned!

  • Contact Me

    If you need to contact me for any reason, feel free to send me an email.
  • The Giving Spirit

    If you've found this site helpful, would you consider donating a little sum? Any amount is appreciated...Thanks so much!

  • Roadmap

  • Enter your email address to follow this blog and receive notifications of new posts by email.

    Join 220 other followers

  • Back to the Past

    May 2020
    S M T W T F S
     12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31  
  • Time Machine

  • You count!

    • 622,649 views
  • Worldwide Stats

    free counters
%d bloggers like this: