Programming Concepts

Here are a few basic programming concepts to help you get started. I focus on concepts which are important to C and C++ programming, because that is what I'm trying to explain. Other languages have different emphasis, or perhaps entirely different concepts.

Bits and Bytes

Computers only deal with numbers. Even though when you are programming you may be dealing with letters of the alphabet, to the computer these are all numbers which just happen to represent letters. Furthermore, a computer doesn't even understand digits from zero to nine; it only really understands one and zero.

When you write down a large number each digit represents a power of ten (ones, tens, hundreds, thousands). The computer, basically, deals with any number larger than one in the same way, with each digit representing a power of two (ones, twos, fours, eights and so on). This system, binary arithmetic, can represent any number that normal decimal arithmetic (with powers of ten) can.

Each digit (zero or one) in binary arithmetic is called a binary digit or bit. Computers often deal with these bits in groups which allow them to store a certain range of numbers:

• A byte is a group of eight bits, which can represent 256 different values (integers from 0 to 255 for example, or 256 different letters and symbols). A byte is sometimes also called an octet, usually in connection with communications systems (like the protocols used on the Internet).
• A word is a larger group of bytes. In Win32 programming a word is usually regarded as two bytes, or 16 bits (this is a holdover from the days before Win32; the 32 in Win32 stands for 32-bits to differentiate it from the old 16-bit system). A group of four bytes, or 32 bits, is called a double-word.

Representation

To a computer everything is a number. A picture is just a big list of numbers which happen to mean what colors get drawn where on a screen. A novel is just a different big list of numbers, where some of the numbers represent letters and others represent the font (shape of characters to be displayed) or things like the size of the page.

At the fundamental level, everything in a computer is a string of bits. For convenience, these strings of bits are arranged in groups (bytes or words). Furthermore, different meaning can be assigned to the same group of bits or bytes. The arrangement of bits to carry a certain meaning or value can be called the representation. For example, a single byte can represent numbers between 0 and 255. This is called the unsigned integer representation of a byte. However, a single byte can also represent numbers between -128 and 127. Because this allows numbers with a sign to be represented, this is called the signed integer representation of the byte. A single byte can also represent a letter (A, B, C... Y, Z) or symbol (#, \$, %). This is called the character representation. A collection of bytes can represent a word or sentence, and this is called a string.

A word might also represent an address in memory. A number of bytes together can represent a real number (with a decimal point, like 3.14123), called the floating point representation. There is no limit on the set of possible representations (although only a certain set of the possible representations are standard).

Memory

A computer's memory is a very large set of bytes in which it stores the numbers (and letters and so on, but they're really all just bits) that it is using at the moment. When you write a letter using a word processor for example, the computer loads the word processing program file into memory, and also keeps the letter in memory as you write it. When you have finished the letter you can save it, and exit the word processor program, which is then discarded from memory along with your letter (but the files stay on disk where you can use them to load the program again later).

I say the memory is a collection of bytes because the bytes are arranged and numbered in order from zero to some very large number (if you have 128 Mbytes of memory for example, the bytes are numbered from zero to 134,217,727). The number of each byte is called its address.

Program

This is important. The whole point of programming is to create programs, so it's important to know what a program is. A program is a list of step by step instructions telling the computer how to do something.

Computers are very stupid, so they need explicit, detailed, step-by-step instructions in order to do anything. Reading a file from a disk into memory, displaying a word on the screen, and so on are all accomplished by telling the computer exactly which signals need to be sent to the hardware (the disk drive, or the video controller) at what time. A collection of these instructions strung together to make the computer do something useful (or at least do something) is a program.

File

A file is a collection of data stored together under one name on a disk (or some other permanent media). The computer must read the data from a file into memory before it can do anything with it, and in order to save data so that it will not be lost when the computer is turned off (or the program ends), the data will usually have to be written to a file.

Variables

A variable in math is a symbol representing an arbitrary number. In programming, a variable is also a symbol (the variable name) which represents an arbitrary number (the value of the variable). However, that is pretty much where the similarity ends. In math you write and manipulate equations to prove things which are true for all possible values of a variable, or to find the set of possible values for which the equation is true. In programming a variable has a particular value at any given time, and the reason it is called a variable is because that value can be changed as the program runs. A variable can be used to store a number input by a user, or the position of the mouse (periodically updated), or the result of a calculation, and so on.

Each variable in C or C++ has a type. The type of a variable determines its size in memory (the number of bytes it takes to store) and its representation, such as int for integer words, char for character bytes, and float for floating point numbers. There is more on variables in C and C++ in the section on Variables

Assignment and Arithmetic

Variables can be used to perform arithmetic. That is, you can add, subtract, multiply and divide using variables (as well as ordinary numbers, or constants). You have to assign the result of such arithmetic to a variable (or otherwise make use of it immediately). Thus the following statement:

x = y + 4;

This assigns the result of adding four to the current value of the variable y to the variable x. Note that this is very different from what the same set of symbols means in math. To further illustrate, the following doesn't make much sense in math:

x = x + 1;

There is no (ordinary) number which is equal to itself plus one, which is what the above would mean in math, but in programming it is perfectly ordinary and results in the variable x having a value one greater after the statement has been performed.

Functions

Again functions in programming are something like functions in math. In math a function is something that takes a number or set of numbers and produces a result (generally another number or set of numbers). A function in C programming can take a number (or any combination of variables and constants) and can return a single value. For example, a (trivial) function that adds two numbers and returns the sum could look like this:

int Add (int x, int y)
{
return (x + y);
}

The first line says that "Add is a function that takes two integer arguments, x and y, and returns an integer." The stuff (or code) inside the braces {} tells the computer how to accomplish the function. In this case, it tells the computer to add together x and y and then return the result.

Each C program starts with a single function, usually called main, from which all other functions are called.

The real reason to use functions is to structure your program so that it is easier to write, more efficient, more flexible and easier to change. Consider, for example, if you were writing a program to show a list of information about people in your electronic address book. Say you design the program to take a name and display all the entries that match the name, showing either the phone number or the address of the person. You could write this as one long main function. However, it would be much better to break it down into smaller functions. For example:

• A function to read the option settings and arguments (the name to search for, and whether it is phone numbers or addresses). If the user didn't enter the data properly this function could call another function to display some help.
• A function which takes a name and fills in a list with the data (probably a structure) for each entry matching the name. It does this by calling a function which finds the next entry matching the name repeatedly until it reaches the end of the address book.
• A function which displays a list of phone numbers from the list obtained by the function above.
• A function which displays a list of addresses from the list obtained by the function above.

If you do this then the main function could look something like this:

int main (int argc, char* argv[])
{
struct option_t options; /* A structure to hold the options settings */
struct person_t* list; /* A pointer to the first entry in the list */

/* Read the options and fill the options structure. */
if (!read_options (argc, argv, &options))
{
/* Reading options failed. Stop. */
return -1;
}

/* Get the list of people matching the name. */
if (!get_list (options.name, &list))
{
/* No matches. Stop. */
printf ("No names match!\n");
return 1;
}

/* Print the list of phone numbers or addresses */
if (options.phone_numbers_flag)
{
print_phone_numbers (list);
}
else
{
}

/* Finished, clean up and exit. */
free_list (list);
return 0;
}

Although there are a lot of details in there that probably don't make much sense right now, even a novice can see basically what is happening. Even without the comments it wouldn't be very difficult. On the other hand, if everything was in one long function it would be very difficult to figure out what the program was supposed to do. Also, if you want to change the way options are set, or the format used to print the entries, you don't have to change this function at all, only the function which reads the options or prints the report.

Flow Control

Flow control is a general term for deciding what gets done next in a program. There are a number of generally useful forms that show up in many programming languages including C. See the section on Flow Control and Statement Blocks for more detailed information.

If, then, else

Perhaps the simplest form of flow control is a statement which is performed if some condition is met. In C, for example, the following fragment of code will output (using a function called printf) the words "x is too small" if x is less than 10:

if (x < 10)
{
printf ("x is too small\n");
}

The part that gets executed if the condition is met is sometimes called the then clause. It is also possible to add statements which are executed if the condition is not met, for example:

if (x < 10)
{
printf ("x is too small\n");
}
else
{
printf ("x is ok\n");
}

If the value of the variable x is greater or equal to ten, "x is ok" is output. The set of statements executed when the condition is not met is called, appropriately enough, the else clause.

Loops

A loop is a block of code that can be executed more than once. In C there are three types of loop, but probably the easiest one to understand is the 'while' loop. It looks like this:

c = getchar();          /* Read a single character */
while (c != EOF)        /* If not End Of File then... */
{
printf ("%02x ", c);  /* Print the value of the character */
c = getchar();        /* Get another character */
}

This loop starts after the function getchar has been used to read a character into the variable c. If the character 'read' was a special end-of-file character then the loop doesn't get executed, and the program will continue after the final '}', otherwise printf is used to display the value of the character (in hexadecimal, just to make it interesting) and another character is read. At that point the loop checks the condition "c != EOF" again and, if c is not EOF, does the loop again. It will keep running the loop until the condition "c != EOF" is false, that is, until the special EOF character is returned by getchar.

Pointers

Pointers are very important in C, and still pretty important in C++, but they are often very difficult for new programmers to understand and use. Recall that the computer has a memory divided into bytes, and that each byte of that memory has an address. Each variable in your program is stored somewhere in the computer's memory, and therefore there is an address for that variable. A pointer is a variable which stores an address, so it can point to another variable.

Below is a simple example of pointers and the operators '&' ("address of"), and '*' ("the variable pointed to by"). Don't worry if it doesn't make perfect sense. I'll try to explain in more detail in the section on pointers.

int  x = 10;         /* Initialize an integer variable x with the value 10 */
int* px;             /* Declare a variable px with the type "pointer to integer" */

px = &x;             /* Assign the address of x to px */
printf ("%d\n", x);  /* Prints the value of x, "10" */
*px = 5;             /* Assign 5 to the variable pointed to by px (that is, x) */
printf ("%d\n", x);  /* Print the value of x again, now its "5"! */

The above example is pretty pointless, but in practice pointers make it possible to do some very useful things because they allow your code to choose which variables it works with at run time (that is, while the program is running and probably based on some sort of input one way or another). In addition to memory allocation (which allows you to create arbitrary new variables at run time) this is essential for almost any program.

C++ insulates the programmer from some of the more mundane uses of pointers (for example, using pointers to create variable length lists and such), but you will still run into them with great regularity.

Data Structures

C and C++ offer certain basic types for variables which correspond to some different representations. However, sometimes you want to group together a set of data for some reason. For example, in the address book example above (under functions) we wanted to group together various pieces of information associated with a person, such as the name, address and phone number. For this you can use a structure. A structure is a set of variables grouped together, and structures themselves can be treated as variables. For the address book, say that each person has a name, address, telephone number, sex and age. We could define a structure like this:

struct person_t
{
char             name;  /* A 64-character array for the name */
int              telephone; /* The telephone number, stored as an integer */
char             sex;       /* The sex, stored as a single character ('M' or 'F') */
unsigned int     age;       /* The age, stored as an unsigned integer. */
};

That is not really a great structure, but it would do the job. Notice that a structure can contain other structures, like the address structure above (that would have to be defined as well, but I haven't shown the definition).

Then we could define variables of the "person" type and use them for various things. For example, we could write a function which read in the data for a person input by the user and then another function which searched for the 'best match' for that person.

struct person_t search_for, found;

get_person_from_user (&search_for);
find_match (&search_for, &found);
display_person (&found);

Classes

In C++ there is a type of structure called a class (or, from a C++ perspective, a structure is just a kind of class). A class is a way of representing an abstract object. Like a structure, a class contains data about the object it represents. However, a class also has functions. For example, if we defined a person class corresponding to the structure defined in the example above (under data structures), it could have member functions which performed tasks related to the object, such as filling it with user input data, or displaying the contents:

class cPerson
{
// Declarations of various data members go here...

public:
void Display ();
void GetFromUser ();
};

Then the code fragment to get a person's data from the user and then search for a match could look like this:

cPerson search_for, found;

search_for.GetFromUser();
Match (&search_for, &found);
found.Display();

For more on why this can be a good thing (and the other things that classes can do), read Stroustrup's book, or any number of other books on object oriented programming.