Article | Talk | Edit | History  

CE - Intro to programming/Programming concepts/overview

From the World Wide Wiki

"When the law breaks in, how you gonna go? Shot down on the pavement, or waiting in death row?" - The Clash

Jump to: navigation, search
Computer Engineering
Index of articles in the Computer Engineering Curriculum
Prereqs
*Science prereqs
*Calc I - derivatives and intergrals
* Electrostatics
100 level
*Intro to computer engineering
*Intro to programming
*Intro to electricty
*Calc II - limits and series
200 level
*Linear circuits
*Intro to digital logic
*Intro to Object Oriented Programming with Java
300 level
*Computer architecture
*Intro to electronic devices
*Programming in C and C++
400 level
*Embedded systems
*Networks
*Programming Data Structures and Algorithms
*Signal processing
Electives
*Additional topics in computer programming

This article is part of a series of articles intending to offer a curriculum of Computer Engineering. For information, please see Category:Computer engineering curriculum.

As mentioned, programming is basically just the creation of a list of instructions for the computer to perform. When we execute our program, the computer starts with the first instruction, performs it, and moves on to the next. This is called sequential execution.

But what are these instructions? Well, you can't exactly just tell the computer to go make your bed, or do the dishes, or something like that. They're much simpler, much more fundamental. The purpose of programming is to try to combine these fundamental instructions in sequences that do something useful.

Contents

Values and variables

The bulk of the instructions you give to a computer involve manipulating values. For a computer, all values are represented by numbers, which are stored in the hardware as a sequence of "ones and zeros"[1] using the binary number system. Generally speaking, these numbers can represent actual numerical values, characters (like letters, digits, punctuation, etc.), or memory addresses (i.e., a specific location in the computer's memory). Additionally, these values can be sent to external hardware (external to the processor, not necessarily external to the computer) where they can be used to create actual electrical signals. This is how serial ports, sound cards, video cards, and pretty much every other peripheral on the computer works.

To manipulate values, we perform operations on them. Some of the basic operations are just like the ones we perform in mathematics: add, subtract, multiple, divide. We'll get into the rest of the operations a bit later.

When the computer performs an operation, it takes input values we specify, performs the specified operation on those values, and produces a resulting value. The resulting value can in turn be used as input to other operations, just like in mathematics.

In addition to performing operations on them, we can also store values in place holders called variables, which are basically just buckets we can use to carry values around in. For instance, after we perform an operation, we can store the resulting value into a variable so we can use that value again later. This is called assigning the value to the variable. When we're writing our code, anytime we want to use a value, we can use a variable instead, which just serves as a place holder for the value stored in that variable.

Variables are more than just a label for a specific value, though. Variables can be reassigned, so the value in them can change. When we use a variable in place of a value in our code, that variable place holder stays in there until the code is actually executed. When that specific instruction is executed, the value currently stored in that variable is used in it's place. This allows us to do things with values without actually having to know what they are when we're writing our code. For instance, a value might come from the user through the keyboard, or be read from a file. By storing the value in a variable, we can write code to perform operations "on the variable", without actually knowing what value is stored there. The computer will figure it out when it's time.


Flow control

Above, we mentioned sequential execution, where the computer just executes each instruction in order, one after the other. I'll tell you right now, programs would be pretty boring and not nearly as powerful if that's all they could do. Think about it, when you use an application, do you do the same things with it every time? Of course not, there are different work flows you use for different purposes, and so the code needs to be able to support that.

This is where flow control comes into the picture. Flow control allows us to tell the computer to jump to a different point in the program (the instruction list), and continue executing from there. For this to be useful, it needs to be done conditionally, meaning it may or may not jump depending on some value. For instance if the user clicks on the save button, then the code needs to jump to the code that performs a save.

There's nothing magical about flow control, you achieve it the same way you achieve everything else in programming, with instructions. In this case, instead of instructing the computer to assign a value to a variable, or perform an operation, you're telling it (conditionally) jump to a different location in code.

If blocks

One of the simplest forms of flow control is an if block. An if block is a group of instructions which only get executed if a certain value, called the test value, evaluates to true (the definition of true varies from language to language, we'll get into more details later), and skipped entirely if it is not true (i.e., if it's false). For instance, most languages, including C++ have a comparison operation. The comparison operation checks to see if two values are equal. If they are, the resulting value is true, if they aren't, the resulting value is false.

Else-if and Else blocks

Along with if blocks, most languages provide an else-if block. An else-if block immediately follows either an if block or another else-if block, and it has it's own test value, just like the if block. If none of the preceding if and else-if blocks get executed (because their test values all evaluate to false), and if the else-if blocks test value evaluates to true, then the code inside the else-if block gets executed, otherwise it is skipped like the others.

Any chain of if/else-if blocks (even if there aren't actually any else-if blocks) can be followed by an else block. And else block gets executed if and only if none of the preceeding if or else-if blocks get executed. Else blocks don't have a test value of their own, they're more like a catch all.

Loops

Another form of flow control is called "looping". Looping is essentially done by creating an if block which jumps back to the beginning of the block when it's done. The key to preventing a loop from looping forever is to use a variable for your test value, then you can change the value of the test variable inside the loop. Of course, the value assigned to your test variable inside the loop can be done conditionally inside another loop, or inside an if block, for instance, so you can exert maximum control over how many times you loop.

Most languages offer a number of variations on looping, including loops which automatically perform a certain operation on your test variable at the end of each iteration, and loops which don't check your test value until the end of the loop (garaunteeing that it will be executed at least once). All of these variations are just useful constructs provided by the language to make your life as a programmer a little easier. Ultimately, any loop can be made to act like any other loop, and all loops are really just if blocks with an execution jump at the end.

Jumping to Functions, Procedures, and Sub-Routines

By far the simplest form of flow control is to simply jump to a different place in code. In order to do this, we need to have some way of telling the computer where we want it to jump to. In other words, we need a way of applying a label to a certain point in the code[2]. Some languages use line numbers for this purpose, but that's basically a nightmare (imagine what happens when you add one line of code, and have to change line numbers through the entire program). Instead, most programs give you a way to name a certain block of code, and then you can tell the computer where to go simply by giving it the name of the block. Named blocks of code go by lots of different names depending on what language you're using and what background you have. Common ones are functions, procedures, sub-routines, and methods. In C++, we usually call them functions (until we get into Object Oriented programming, at which point we'll make a subtle distinction between functions and methods), but all the names are basically synonymous.

What functions (or whatever you want to call them) allow us to do is to isolate a certain bit of code that we might want to use more than once. This is called reusability. The idea is, instead of typing the same code multiple times, we just type it once in a function, and then we can jump into that function to run that code whenever we need to. Jumping into a function is called calling, or invoking, the function. Not only does this save us typing initially, it also make modifications easier because you only have to change it once instead of in every place you use it.

For this to be useful, however, we need a way of getting back to the code we came from, regardless of where that might be. This is called returning from a function. When we first call a function, the computer will do some work behind the scenes to remember where we currently are in the code. At the end of the function, we simply use the return instruction, and the computer takes care of getting us back to where we came from.


Notes

</references>