Chapter 1. Understanding Programming

Programming is nothing more than writing instructions for a computer to follow. If you've ever written down the steps for a recipe or scribbled driving directions on the back of an envelope, you've already gone through the basic steps of writing a program. The key is simply knowing what you want to accomplish and then making sure you write the correct instructions that will achieve that goal.

Although programming is theoretically simple, it's the details that can trip you up. First, you need to know exactly what you want. If you wanted a recipe for cooking chicken chow mein, following a recipe for cooking baked salmon won't do you any good.

Second, you need to write down every instruction necessary to get you from your starting point to your desired result. If you skip a step or write steps out of order, you won't get the same result. Try driving to a restaurant where your list of driving instructions omits telling you when to turn on a specific road. It doesn't matter if 99 percent of the instructions are right; if just one instruction is wrong, you won't get you to your desired goal.

The simpler your goal, the easier it will be to achieve. Writing a program that displays a calculator on the screen is far simpler than writing a program to monitor the safety systems of a nuclear power plant. The more complex your program, the more instructions you'll need to write, and the more instructions you need to write, the greater the chance you'll forget an instruction, write an instruction incorrectly, or write instructions in the wrong order.

Programming is nothing more than a way to control a computer to solve a problem, whether that computer is a laptop, mobile phone, or tablet device. Before you can start writing your own programs, you need to understand the basic principles of programming in the first place.

Programming Principles

To write a program, you have to write instructions that the computer can follow. No matter what a program does or how big it may be, every program in the world consists of nothing more than step-by-step instructions for the computer to follow, one at a time. The simplest program can consist of a single line:

PRINT "Hello, world!"

Note

The sample code in this part of the chapter uses the BASIC programming language to make programming concepts easier to understand. What you'll be learning later in this book is a different programming language called Objective-C, which is a bit harder to understand than BASIC.

Obviously, a program that consists of a single line won't be able to do much, so most programs consist of multiples lines of instructions (or code):

PRINT "Hello, world!"
PRINT "Now the program is done."

This two-line program starts with the first line, follows the instructions on the second line, and then stops. Of course, you can keep adding more instructions to a program until you have a million instructions that the computer can follow sequentially, one at a time.

Listing instructions sequentially is the basis for programming, but it's not always the best way to organize instructions. For example, if you wanted to print the same message five times, you could use the following:

PRINT "Hello, world!"
PRINT "Hello, world!"
PRINT "Hello, world!"
PRINT "Hello, world!"
PRINT "Hello, world!"

Writing the same five instructions is tedious and redundant, but it works. What happens if you wanted to print this same message 1,000 times? Then you'd have to write the same instruction 1,000 times.

Writing the same instruction multiple times is clumsy. To make programming easier, you really want to write the least number of instructions that get the most work done. One way to avoid writing the same instruction multiple times is to organize your instructions using something called a loop.

The idea behind a loop is to repeat one or more instructions multiple times, but only by writing those instructions down once. A typical loop might look like this:

FOR I = 1 TO 5
     PRINT "Hello, world!"
END FOR

The first instruction tells the computer to repeat the loop five times. The second instruction tells the computer to print the message "Hello, world!" on the screen. The third instruction just defines the end of the loop.

Now if you wanted to make the computer print a message 1,000 times, you don't need to write the same instruction 1,000 times. Instead, you just need to modify how many times the loop repeats:

FOR I = 1 TO 1000
     PRINT "Hello, world!"
END FOR

Although loops are slightly more confusing to read and understand than a sequential series of instructions, loops make it easier to repeat instructions without writing the same instructions multiple times.

Most programs don't exclusively list instructions sequentially or in loops, but they use a combination of both:

PRINT "Getting ready to print."
PRINT "Program is now starting."
FOR I = 1 TO 1000
     PRINT "Hello, world!"
END FOR

In this example, the computer follows the first two lines sequentially and then follows the last three instructions repetitively in a loop. Generally, listing instructions sequentially is fine when you need the computer to follow those instructions only once. When you need the computer to run instructions multiple times, that's when you need to use a loop.

What makes computers powerful isn't just the ability to follow instructions sequentially or in a loop, but in making decisions. Decisions mean that the computer needs to evaluate some condition and then, based on that condition, decide what to do next.

For example, you might write a program that locks someone out of a computer until that person types the correct password. If the person types the correct password, then the program needs to give that person access. However, if the person types an incorrect password, then the program needs to block access to the computer. An example of this type of decision making might look like this:

ASK "Enter the password:", Password
IF Password = "OPEN" THEN
     Grant access to the computer
ELSE
     Block access to the computer

In this example, the computer asks for a password, and when the user types a password, the computer checks to see whether it matches the word OPEN. If the user typed OPEN, then the computer grants that person access to the computer. If the user did not type OPEN, then the computer blocks access.

Making decisions is what makes programming flexible. If you write a sequential series of instructions, the computer will follow those lists of instructions exactly the same way, every time. However, if you include decision-making instructions, also known as branching instructions, then the computer can respond according to what the user does.

Consider a video game. No video game could be written entirely with instructions organized sequentially because then the game would play exactly the same way every time. Instead, a video game needs to adapt to the player's actions at all times. If the player moves an object to the left, the video game needs to respond differently than if the player moves an object to the right or gets killed. Using branching instructions gives computers the ability to react differently so the program never runs exactly the same.

To write a computer program, you need to organize instructions in one of the following three ways, as shown in Figure 1-1:

Sequentially: The computer follows instructions one after another.

Loop: The computer repetitively follows one or more instructions.

Branching: The computer chooses to follow one or more groups of instructions based on outside data.

The three basic building blocks of programming

Figure 1-1. The three basic building blocks of programming

Although simple programs may organize instructions only sequentially, every large program organizes instructions sequentially, in loops, and in branches. What makes programming more of an art and less of a science is that there is no single best way to write a program. In fact, it's perfectly possible to write two different programs that behave the same.

Because there is no single "right" way to write a program, there are only guidelines to help you write programs easily. Ultimately what matters is only that you write a program that works.

When writing any program, there are two, often mutually exclusive, goals. First, programmers strive to write programs that are easy to read, understand, and modify. This often means writing multiple instructions that clearly define the steps needed to solve a particular problem.

Second, programmers try to write programs that perform tasks efficiently, making the program run as fast as possible. This often means condensing multiple instructions as much as possible, using tricks, or exploiting little known features that are difficult to understand and confusing even to most other programmers.

In the beginning, strive toward making your programs as clear, logical, and understandable as possible, even if you have to write more instructions or type longer instructions to do it. Later, as you gain more experience in programming, you can work on creating the smallest, fastest, most efficient programs possible, but remember that your ultimate goal is to write programs that just work.

Dividing Programs into Parts

Since small programs have fewer instructions, they are much easier to read, understand, and modify. Unfortunately, small programs can solve only small problems. To solve complicated problems, you need to write bigger programs with more instructions. The more instructions you type, the greater the chance you'll make a mistake (called a bug). Even worse is that the larger a program gets, the harder it can be to understand how it works in order to modify it later.

To avoid writing a single, massive program, programmers simply divide a large program into smaller parts called subprograms. The idea is that each subprogram solves a single problem. Connect all of these subprograms together, and you can create a single large program, as shown in Figure 1-2. This is like building a house out of bricks rather than trying to carve an entire house out of one massive rock.

Dividing a large program into multiple subprograms

Figure 1-2. Dividing a large program into multiple subprograms

Dividing a large program into smaller parts provides several benefits. First, writing smaller subprograms is fast and easy, and small subprograms make it easy to read, understand, and modify the instructions.

Second, subprograms act like building blocks that work together, so multiple programmers can work on different subprograms and then combine their separate subprograms to create a large program.

Third, if you want to modify a large program, you just need to yank out, rewrite, and replace one or more subprograms. Without subprograms, modifying a large program means wading through all the instructions stored in a large program and trying to find which instructions you need to change.

A fourth benefit of subprograms is that if you write a useful subprogram, you can plug that subprogram into other programs, thereby reducing the need to write everything from scratch.

When you divide a large program into multiple subprograms, you have a choice. You can store all your programs in a single file, or you can store each subprogram in a separate file, as shown in Figure 1-3.

You can store subprograms in one file or in multiple files.

Figure 1-3. You can store subprograms in one file or in multiple files.

Storing all your subprograms in a single file makes it easy to find and modify any part of your program. However, the larger your program, the more instructions you'll need to write, which can make searching through a single large file as clumsy as flipping through the pages of a dictionary.

Storing all your subprograms in separate files means you need to keep track of which files contain which subprogram. However, the benefit is that modifying a subprogram is much easier because once you open the correct file, you see the instructions for only a single subprogram, not for a dozen or more other subprograms.

To write any program, most programmers divide a large program into subprograms and store those subprograms in separate files.

Event-Driven Programming

In the early days of computers, most programs forced people to use a program by typing one command at a time. For example, if you had a program that calculated the trajectory of a rocket, the program might first ask you the destination followed by the rocket's size, weight, and position from the target. If you wanted to type in the rocket's weight before typing in the rocket's height, the program wouldn't let you because such programs tightly controlled how the computer behaved at any given time.

All of this changed when computers started displaying windows and pull-down menus so users could choose what to do at any given time. Suddenly every program had to wait for the user to do something such as selecting one of many available menu commands. Since the user could do multiple actions such as typing or clicking the mouse, programs had to constantly wait for the user to do something before reacting.

Every time the user did something, that was considered an event. If the user clicked the left mouse button, that was a completely different event than if the user clicked the right mouse button. Instead of dictating what the user could do at any given time, programs now had to respond to different events that the user did. Such programs came to be known as event-driven programming.

Instead of following instructions from start to finish, event-driven programs divided a large program into multiple subprograms where each subprogram responded to a different event. If the user clicked the left mouse, the subprogram that handled left mouse clicks would run its instructions. If the user clicked the right mouse, the subprogram that handled right mouse clicks would run its instructions.

With event-driven programming, a large program might be divided into multiple subprograms where some of those subprograms contained instructions that ran only when a certain event occurred, as shown in Figure 1-4.

Programs can be divided into subprograms that respond to specific events.

Figure 1-4. Programs can be divided into subprograms that respond to specific events.

Object-Oriented Programming

Dividing a large program into multiple subprograms made it easy to create and modify a program. However, trying to understand how such a large program worked often proved confusing since there was no simple way to determine which subprograms worked together or what overall task they were meant to solve.

To solve this problem, programmers grouped related subprograms and data in a single location. By using this grouped collection of subprograms and data, programmers could create objects, which represent a single element of the problem you're trying to solve.

Instead of focusing on different tasks, object-oriented programming often focuses on mimicking objects in the real world. An object-oriented video game program might divide a program into objects such as monsters, the player character, and other moving items such as falling boulders.

Each object would contain subprograms for manipulating that object along with data that defines the characteristics of that object, such as its location on the screen or the color of the item to display on the screen.

One idea behind object-oriented programming is to divide a large program into logical objects that mimic the physical problem you're trying to solve. So rather than write a bunch of subprograms that break a problem into individual tasks, object-oriented programming divides a problem into physical parts.

Suppose you need to write a program for controlling a robot. Dividing this problem into tasks, you might create one subprogram to move the robot, a second subprogram to tell the robot how to see nearby obstacles, and a third subprogram to calculate the best path to follow.

Dividing this same robot program into objects might create a Legs object (for moving the robot), an Eye object for seeing nearby obstacles, and a Brain object (for calculating the best path to avoid obstacles), as shown in Figure 1-5.

A second idea behind object-oriented programming is to make it easy to reuse and modify a large program. Suppose we replace our robot's legs with treads. Now we'd have to modify the subprogram for moving the robot since treads behave differently than legs. Next, we'd have to modify the subprogram for calculating the best path around obstacles since treads force a robot to go around obstacles, while legs allow a robot to walk over small obstacles and go around larger obstacles.

If you wanted to replace a robot's legs with treads, object-oriented programming would simply allow you to yank out the Legs object and replace it with a new Treads object, without affecting or needing to modify any additional objects.

How subprograms and objects might divide a program into parts

Figure 1-5. How subprograms and objects might divide a program into parts

The Brain object wouldn't need to change since it needs to tell the Treads object only where to move, not how to move. Since most programs are constantly modified to fix bugs or add new features, object-oriented programming allows you to create a large program out of separate building blocks (objects) and modify a program by modifying only a single object.

The key to object-oriented programming is to isolate parts of a program and promote reusability through three features known as encapsulation, inheritance, and polymorphism.

Encapsulation

The biggest problem with dividing a large program into subprograms is that one subprogram can often access and change data that another subprogram uses. If this happens, then the entire program might not work, and trying to track down the source of the problem can be nearly impossible because you have to exhaustively examine all your subprograms.

To avoid this problem, object-oriented programming encapsulates, or hides, data inside an object. Each object contains both the data it needs and the subprograms allowed to manipulate that data, as shown in Figure 1-6.

Objects group related subprograms and data together.

Figure 1-6. Objects group related subprograms and data together.

Encapsulation simply eliminates the risk that an unrelated part of a program can change data used by another subprogram.

Polymorphism

When you divide a large program into subprograms, each subprogram needs a unique name. Normally this won't cause any problems, but sometimes you may need to create subprograms that perform similar tasks.

For example, suppose you're creating a video game where the player controls a car and the computer controls a monster throwing rocks at the car. To make the car, monster, and rocks move on the screen, you might want to create a subprogram named Move.

Unfortunately, a car needs to move differently on the screen than a monster or a thrown rock. You could create three subprograms and name them MoveCar, MoveMonster, and MoveRock. However, a simpler solution is to just give all three subprograms the same name such as Move.

In traditional programming, you can never give the same name to two or more subprograms since the computer would never know which subprogram you want to run. However, in object-oriented programming, you can use duplicate subprogram names because of polymorphism.

The reason why polymorphism works is because each Move subprogram gets stored in a separate object such as one object that represents the car, a second object that represents the monster, and a third object that represents a thrown rock. To run each Move subprogram, you must identify the object that contains the Move subprogram you want to use:

Car.Move
Monster.Move
Rock.Move

By identifying both the object that you want to manipulate and the subprogram that you want to use, object-oriented programming can correctly identify which set of instructions to run even though a subprogram has the identical name to another subprogram.

Essentially, polymorphism lets you create descriptive subprogram names and reuse that descriptive name as often as you like.

Inheritance

If you create a particularly useful subprogram, you might want to reuse that subprogram again. The simple answer is to make a copy of a subprogram and modify this copy.

The problem with copying subprograms is that you now have two or more identical copies of the same subprogram stored in different locations. Such duplication not only wastes space but, more importantly, can cause problems if you need to modify the original subprogram.

Suppose you create a useful subprogram and then make five different copies to use in other parts of your program, with minor modifications made to each additional subprogram copy. Now what happens if you find an error in your original subprogram? Fixing that one subprogram will be fairly straightforward, but now you have to fix that same error five more times in each of the five additional copies you made earlier.

Inheritance eliminates this problem because instead of forcing a programmer to create duplicate, physical copies of a subprogram, inheritance creates virtual copies of a subprogram. The original instructions remain in one physical location, but multiple objects can now access those instructions whenever they need them.

Think of inheritance like the difference between text in a printed book and text on a web page. Only one person can read a printed book at a time. If multiple people want to read that same book, you'll need to make physical copies.

However, text on a web page can be accessed by multiple people, even though there's only one copy of that text stored on a single computer.

The main idea behind inheritance is to make it easy to reuse parts of your program without creating duplicate copies.

Understanding Programming Languages

Once you understand how programming has gradually evolved and how Mac programming requires understanding all of these different programming techniques, you're almost ready to start programming. Next, you need to know that giving instructions to a computer involves writing commands using a programming language.

There are thousands of different programming languages with names like FORTH, Ada, BASIC, C#, Prolog, and Modula-3. However, the programming language you'll be learning in this book is called Objective-C.

Currently, one of the most popular programming language is C. Two huge advantages of C are its efficiency and its portability. Efficiency means that programs written in C are extremely small and run fast. Portability means that almost every computer in the world understands C. As a result, you can write a program in C and copy it to a different operating system, such as taking a C program for Windows and copying it to a Macintosh. You'll need to rewrite the C code to create a user interface that's unique to each operating system, but a large portion of your program's C code can remain intact with little or no modifications at all.

Since C is an old programming language, it lacks object-oriented programming features, which makes C unsuitable for creating and maintaining large programs. One popular variation of C is called C++, which adds object-oriented programming features. Although C++ is popular, Objective-C also offers object-oriented features and is much simpler and thus easier to learn.

To write Mac programs, you can use any programming langauge, although the most popular ones are C, C++, and Objective-C. However, Apple has officially endorsed Objective-C as the main programming language for the Mac, so if you're going to learn how to program the Mac, your best choice is to learn and use Objective-C.

Note

If you already know C or C++, you'll find that Objective-C is similar enough that you can learn it quickly. If you don't know any programming language at all, Objective-C may look a bit cryptic at first, but after you use it for a while, you'll soon understand how it works.

The Building Blocks of Programming Languages

Every programming language consists of special commands that are part of the language. These commands tell the computer to do something:

PRINT

In this example, PRINT represents a command that tells the computer to print something on the screen. By themselves, commands usually won't do anything interesting, so you have to combine commands with additional data to create a single instruction or a statement. A statement simply tells the computer to do something useful:

PRINT "This is a message from your computer"

Learning a programming language means learning the right commands so you can tell the computer what to do, such as print a message on the screen or add two numbers together.

To make programming as easy as possible, many programming languages use commands that look like ordinary English words such as PRINT, Writeln, or printf. However, many programming languages also use symbols that represent different features.

Sometimes a symbol represents a command to make the computer do something. Common symbols are mathematical symbols for addition (+), subtraction (-), multiplication (*), and division (/).

Other times symbols are meant to define the beginning or end of something:

int age;

or

[super init]

Some programming languages rely almost exclusively on commands to make the instructions more readable:

BEGIN
    Writeln ('This is a message'),
END;

Other programming languages, such as Objective-C, tend to rely more on symbols to make writing a program faster, but with the drawback that the statements tend to look more cryptic:

{
    printf ("This is a message");
}

Unlike human languages where you can misspell a word or forget to end a sentence with a period and people can still understand what you're saying, programming languages are not so forgiving. With a programming language, every command must be spelled correctly, and every symbol must be used where needed. Misspell a single command, use the wrong symbol, or put the right symbol in the wrong place, and your entire program will fail to work.

ProgrammingFrameworks

Commands (and symbols) let you give a computer instructions, but no programming language can provide every possible command you might need to create all types of programs. To provide additional commands, programmers can create subprograms that perform a specific task.

Programmers can even create bigger subprograms out of commands and smaller subprograms. By creating subprograms, you can create your own commands needed to make the computer do exactly what you need.

Programmers often create subprograms unique to their particular program. However, many programmers have also created useful subprograms that provide features that other programmers might find useful. As a result, many programming languages include libraries of these other subprograms. Now when you write a program, you can use the programming language's commands and any subprograms stored in libraries.

One library might contain subprograms for displaying graphics. Another library might contain subprograms for saving data to a disk and retrieving it again. Still another library might contain subprograms for calculating mathematical formulas. By using commands to create subprograms, programmers can create an endless variety of additional building blocks for making any type of program.

To make programming the Mac, iPhone, and iPad easier, Apple has created libraries or frameworks of useful subprograms that you can use in your own programs.

There are two reasons for reusing an existing framework. First, reusing a framework keeps you from having to write your own instructions to accomplish a task that somebody else has already solved. Not only does a framework provide a ready-made solution, but a framework has also been tested by others, so you can just use the framework and be assured that it will work correctly.

A second reason to use an existing framework is for consistency. Apple provides frameworks for defining the appearance of a program on the screen, known as the user interface. This defines how a program should behave, from displaying windows on the screen to letting you resize or close a window by clicking the mouse.

It's perfectly possible to write your own instructions for displaying windows on the screen, but chances are good that writing your own instructions would take time to create and test, and the end result would be windows that may not look or behave identically as other Mac programs.

However, by reusing an existing framework, you can create your own program quickly and ensure that your program behaves the same way that other programs behave. Although programming the Mac might sound complicated, Apple provides dozens of different frameworks that help you create programs quickly and easily. All you have to do is write the custom instructions that make your program solve a specific, unique problem.

Mac Programming Today

Almost every program consists of three parts: a user interface, a controller, and a model. The user interface displays windows and menus to show information and let the user choose commands. The model contains instructions for accepting data, manipulating it somehow, and calculating a new result. The controller takes data from the user interface and feeds it into the model. Then it takes the newly calculated result from the model and sends it back to the user interface, as shown in Figure 1-7.

The three parts of a typical program

Figure 1-7. The three parts of a typical program

Here's the hard way to write a Mac program. First, use the commands in Objective-C to create your user interface. After you spend time writing multiple instructions to create your user interface, you need to test it to make sure it works.

Second, use Objective-C commands to create the model for accepting data, manipulating it somehow, and calculating a new result. Now spend more time testing these instructions to make sure they work.

Third, use Objective-C commands to create the controller to link the user interface to the model. Now spend more time making sure the controller works correctly with the user interface and the model.

In the old-fashioned way of programming, you had to write three separate chunks of instructions to create the user interface, controller, and model, and then you'd test each chunk separately to make sure they worked. Finally, you had to put all three chunks of instructions together and test everything again to make sure it all worked together.

Such a process is obviously tedious, error-prone, and slow. Since you have to create everything from scratch using Objective-C commands, this can feel like trying to build a wall by pasting together individual granules of sand.

Here's the faster way to write a Mac program, which is what you'll be learning in this book. Instead of creating everything from scratch, you'll just need to focus on writing instructions that calculate a useful result. By focusing on writing instructions to create the model portion of your program, you're essentially simplifying the amount of programming work you need to do.

First, every time you create a new program, you'll get to choose from a template. A template provides the basic skeleton of a user interface that can display windows and pull-down menus found in most programs.

Since the template already provides the Objective-C commands for creating a user interface, you can spend your time customizing this user interface. Ordinarily, customizing the user interface would mean writing Objective-C instructions, but Apple provides a special tool that lets you design your user interface by dragging and dropping items on the screen such as buttons and text fields.

By eliminating the need to write a separate set of instructions for designing your user interface, you'll only need to write instructions to make your program do something useful. Even better, you won't have to waste time testing your user interface because there are no Objective-C instructions to examine since everything just works, so your program looks and behaves exactly like other Mac programs.

To create the controller and model portions of your program, you'll need to write instructions in Objective-C. Rather than rely on commands alone, you can save time by using subprograms stored in frameworks provided by Apple. By using these frameworks, you can use subprograms that have already been tested for accomplishing a variety of complicated tasks such as saving a file.

To respond to the actions of the user, you'll need to organize your instructions into subprograms that run only when certain events occur, such as when the user clicks the mouse. To further help you organize your program, you can create objects using Objective-C's object-oriented features.

The end result is that writing a Mac program eliminates as much of the tedious part of programming as possible, freeing you to focus only on the creative part that makes your program unique.

Although this may sound like a lot of information to master just to write a Mac program, don't worry. From program templates to drag-and-drop user interface designs to frameworks, Apple streamlines the programming process so you can create a fully functioning program with a minimum of effort.

Summary

To learn how to write programs for the Mac, you need to learn three separate skills. First, you need to understand the basic principles of programming. That includes organizing instructions in sequences, loops, or branches.

Second, you need to learn a specific programming language. For the Mac, you'll be learning Objective-C. Objective-C is designed more for program efficiency and less for human readability, which means that writing and reading Objective-C instructions can look cryptic at times.

Third, you need to know how to use Apple's programming tools for writing Objective-C instructions and how to use Apple's frameworks so you can focus solely on writing instructions that make your program work (which you'll learn more about in Chapter 2).

Once you learn how to program the Mac, you can easily use your skill to write programs for the iPhone, iPod touch, and iPad as well. Whether you want to write your own software to sell or you want to sell your programming skills to create custom software for others, you'll find that programming is a skill anyone can learn.

Programming is nothing more than problem solving using a particular programming language. By knowing how to solve problems using Objective-C, you can create your own programs for the Mac much easier and far faster than you might think.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.54.75