Computers as data processors
Now that you know what programmers do, we can start to consider what a computer is and what makes it so special.
Machines and computers and us
The human race is a race of toolmakers. We invent things to make our lives easier, and we’ve been doing it for thousands of years. We started with mechanical devices, like the plough, which made farming more efficient, but in the last century we’ve moved into electronic devices. Figure 2-2 offers a quick summary.
Figure 2-2 Machines that do things for us.
Machines usually involve something going into them, or inputs, and they produce things or events that we want as outputs. A plough, with human effort and steering as inputs, provides a field that will grow more crops. Given coal and a track to follow, a train takes us where we want to go. A computer is given power, a program to tell it what to do, and some data to work on. It then outputs data that is useful.
As computers became smaller and cheaper, they found their way into things around us, and many devices—the mobile phone, for example—are possible only because we can put a computer inside to make them work. But we need to remember what the computer actually does; it automates operations that used to need brain power. There’s nothing particularly clever about a computer; it simply follows the instructions that it’s given. In this respect, a computer has a lot in common with a plough—it’s not conscious in any way. It is simply something that we can use to make our lives easier.
A computer works on data in the same way that a sausage machine works on meat: something is put in one end, some processing is performed, and something comes out the other end. You can think of a computer program as similar to the instructions that a coach gives to a football or soccer team before a play. The coach will say something like, “If they attack on the left, I want Jerry and Chris to run back, but if they kick the ball down the field, I want Jerry to chase the ball.” Then, when the game unfolds, the team will respond to events in a way that should let them outplay their opponents.
However, there is one important distinction between a computer program and the way a team might behave in a football game. A football player would know that some instructions make no sense. If the coach says, “If they attack on the left, I want Jerry to sing the first verse of the national anthem and then run as fast as he can toward the exit,” the player would raise an objection.
Unfortunately, a program is unaware of the sensibility of the data it is processing, in the same way that a sausage machine is unaware of what meat is. Put a bicycle into a sausage machine, and the machine will try to make sausage out of it. Put meaningless data into a computer, and it will do meaningless things with it. As far as computers are concerned, data is just a pattern of signals coming in that has to be manipulated in some way to produce another pattern of signals. A computer program is the sequence of instructions that tell a computer what to do with the data coming in and what form the data sent out will have.
Examples of typical data-processing applications include the following (and are shown in Figure 2-3):
Mobile phone A microcomputer in your phone takes signals from a radio and converts them into sound. At the same time, it takes signals from a microphone and makes them into patterns of bits that will be sent out from the radio.
Car A microcomputer in the engine takes information from sensors telling it the current engine speed, road speed, oxygen content of the air, setting of the accelerator, and so on and produces voltages that control the setting of the carburetor, the timing of the spark plugs, and other things to optimize the performance of the engine.
Game console A computer takes instructions from the controllers and uses them to manage the artificial world that it is creating for the person playing the game.
Figure 2-3 Many different devices use computers.
Most reasonably complex devices created today contain data-processing components to optimize their performance, and some exist only because we can build in such capabilities. It is into this world that you, as a beginning programmer, are moving. It is important to think of data processing as much more than working out the company payroll—calculating numbers and printing out results (the traditional uses of computers). As a software engineer, you will inevitably spend a great deal of your time fitting data-processing components into other devices to drive them. These embedded systems mean many people will be using computers even if they’re not even aware of it!
Making programs work
Inside every computer is hardware—physical machinery, that is—that actually does the data processing I’ve been describing. This hardware is called the central processing unit, or CPU. The programs that directly control the CPU, telling it what to do, are called machine code. Different kinds of CPUs have different designs of machine code, in the same way that humans communicate by using many different languages.
Machine code contains the individual steps that tell the CPU what to do. Simple operations—for example, adding one number to another—are performed by a sequence of machine-code instructions. To write machine code, you have to know exactly how the hardware works and the particular instructions that it understands. To understand what this means, take a look at Figure 2-4, which shows part of a program that totals up what a customer buys at a supermarket. This program adds the price of an item to the customer’s total bill.
Figure 2-4 A single step in a high-level program is broken down by a low-level program.
The instructions on the right are the lower-level instructions that the computer is actually able to perform. These describe the individual steps that the computer has to go through to perform the action, adding the price of an item to a bill. Writing low-level programs is rather tedious because an action, as you can see, needs to be broken down into a number of smaller ones.
The good news, however, is that programmers over the years have thought about this and invented new languages that can be used to tell a CPU what to do. These languages are “higher level” than machine code. A program written in a high-level language doesn’t provide the individual machine-code steps required to perform a particular action. It just contains an instruction such as, “Add this number to another.” A special program called a compiler takes this high-level program and generates the machine code required for the computer to be able to perform the task. After you have written your high-level program (in C#, for example), it will be compiled to produce the machine code that runs inside the computer.
A useful side effect of using a high-level language is that by changing the compiler you can generate machine-code programs for different hardware platforms. The C# programs you are going to write over the course of this book can be made to work on Windows, Android, and Apple devices because compilers are available that will convert the high-level statements into machine code for those devices. If anyone asks you which type of computer you are learning to program, you can correctly reply “All of them.”
Programs as data processors
Figure 2-5 shows what every computer does. Data goes into the computer, which does something with it, and then data comes out of the computer. What form the data takes and what the output means is entirely up to us, as is what the program does.
Figure 2-5 A computer as a data processor.
As I quickly mentioned earlier, another way to think of a program is as a recipe, which is illustrated in Figure 2-6.
Figure 2-6 Recipes and programs.
In this example, the cook plays the role of the computer and the recipe is the program that controls what the cook does with the ingredients. A recipe can work with lots of different ingredients, and a program can work with lots of different inputs, too. For example, a program might take your age and the name of the movie you want to see and provide an output that determines whether you can go see that particular movie.
When you do this, you find the following program code:
For now, don’t worry too much about the curly brackets and the different colored words in the program text; just consider the elements that have been called out. You can see that the code has some form of test (performed by an if construction, which you’ll learn more about in Chapter 5) and a statement that appears to double a value by adding it to itself.
If you want to guard against faults in your programs, you have to take a look at the actual program code. Programmers call this form of program evaluation white-box testing or code review. Instead of looking at the outputs produced by the program in response to particular inputs, you look at the actions that are called for by the code and make sure that these match the behaviors that you want. You do this by pretending to be a computer and working through the program statements to see what happens.