| INFORMATION FROM DR. EBRAHIMI'S C++ PROGRAMING EASY WAYS |
CHAPTER 1
THE EVOLUTION OF COMPUTER PROGRAMMING AND LANGUAGES: AN OVERVIEW OF C AND C++
It is important to familiarize yourself with the fundamentals of computer programming, computer languages, and their evolution. It may not be apparent to you at this time how this knowledge is going to help you to program in C/C++. It should, however, be noted that within the past fifty years, a multitude of programming concepts and methods has been introduced, and many different languages have been designed. Yet, they all still depend on a foundation that has remained relatively the same.
In this chapter, you are going to encounter unfamiliar terminology. What I would like you to do is to skim through this chapter and grasp as much as you can, without attempting to understand everything fully. By examining the history of computer programming, it is hoped that you will be able to better understand the way programming and languages are shaped, and have an idea as to what to expect for the future of computer programming and languages.
In order to give you a picture of computer programming and its abilities, I will introduce you to a very important program that is known as a search, written in both C and C++. You will then experience what I call the magic of programming, where the knowledge of building one program will lead you to build other programs without much effort. For example, you will see how a Telephone Operator Search Program can also act as a language translator, a dictionary, and can also easily become a bank or supermarket retrieval system.
I will conclude the chapter by giving examples of pitfalls in C/C++ programming that may cause misconceptions and delay learning. These pitfalls, which are the result of hidden notions and unknown rules, are contributing factors to what I call the mystery of C/C++ programming. You should be aware that the problems these pitfalls cause have nothing to do with your intelligence, and that you will learn to solve them.
By going through the foundations of programming and languages you will find it easier to build programs from scratch using C/C++ in the chapters that follow.
WHY PROGRAM?
Historically, the sole purpose of computers was to serve the scientific communities. Later on, computers progressed rapidly into business and education. Now, they are around us everywhere, and there is hardly an industry that does not need them. Whether in business or in the home, computers have come to maintain a dominant role in many people’s lives. What was once done manually, mechanically or electrically has been replaced, or will be replaced, with computers.
Although computers play a critical role in our society, most people are unaware that a set of instructions, known as a “program”, governs and operates the computers. A computer demonstrates its intelligence through the execution of a program, and without programs a computer is just a useless box. A computer becomes friendlier, easier to use, and more efficient in direct proportion to the quality of the programs it runs. Programs can be regarded as the “mind” of the computer, and without them a computer cannot function. Programs can be created, modified, expanded, enhanced, and/or customized to one's needs. You might want to know what a program is and what it looks like even before you learn how to program.
Let’s first discuss what a computer is. A computer can be considered a machine with three main components: 1) a central processing unit (CPU), where the activities are initiated, coordinated, and performed; 2) memory, where information (program and data) is stored and retrieved; and 3) input and output devices, where information is entered and displayed. The CPU and the memory perform together, just like the cerebral cortex of our brains, while the input/output devices are analogous to our sensory organs. When the three components work together, a task is initiated, retrieved, analyzed, performed, ultimately stored, and/or displayed.
I cannot emphasize enough how important it is to learn programming, but I would also like to point out that teaching and learning programming is still considered a difficult task for many people. At least there is no discrimination when it comes to learning programming for it can be done literally at any age, almost as soon as you are able to read.
ARE WE PROGRAMMED?
For a moment, let’s put computer programming aside and think about ourselves. After all, aren't we all programmed genetically, psychologically, and socially? Don't we follow a set of instructions that consist of a sequence of events, then making decisions, and repeating this process over and over again? These sets of instructions are known as programs, which can be presented by a natural language, such as English. What is your program today? Can you identify a sequence of events? Did you make any decisions? Did you repeat any event, or will you repeat the same set of events tomorrow?
IS EVERYTHING PROGRAMMED?
Before you begin to learn how to program, it is important for you to know that the internal hardware (chips) of the computer is programmed. When you turn on the computer, the environment and interface is programmed. Examples of the user interface and operating systems are DOS, Windows, and Unix. In addition, C/C++, the programming language that you are going to use, is already programmed. Moreover, games, word processors, ATM machines, communication systems, movie special effects, and almost all things else are programmed. Now it is your turn to program, from business applications to game design and hardware controls.
COMPUTER PROGRAMS AS PRE-AGREED RULES
Try to imagine the old days, when cavemen had to communicate with each other without any sophisticated language skills. Whether they communicated through sound or signs, they had to come to some kind of agreement and understanding amongst themselves.
Suppose you want to communicate with a partner not with sound or signs, but by turning a series of light bulbs on and off according to the following rule:
|
Let there be eight light bulbs situated on a desk, and let any communication between the two of you be achieved by turning these bulbs on or off at a given time. |
How could effective communication be achieved? There would have to be some sort of pre-existing agreement about how any eight possible combinations of lights switched on and off could represent the alphabet, numbers, special signs, words, or actions. For example, you may agree that when the first two light bulbs and the last light bulb are on it will represent the letter A. Similarly you may agree to represent the letter B with some other combination of on and off. This trend can go on to represent other letters, digits, and special signs.
To make it simple, we are going to show lights on as 1 and lights off as 0. We will call each light a bit. 1 will represent a lit bulb, and 0 will represent an unlit bulb. These 1s and 0s are referred to as binary numbers. For instance, the letter A is represented as an eight-bit combination of 11000001. The letter B is agreed upon as 11000010, and the number ‘0’ is 00110100. These eight-bit combinations are known as a byte. We have enough combinations of on and off (1's and 0's) to represent the entire alphabet, digits, and any other signs. Now that you know how to represent each digit and each letter with zeros and ones, you would be able to place each digit representation next to each other to form a number. It would be like placing each letter next to each other to form a word. Can you imagine how your name can be represented using this kind of agreement?
Computer Standard Code: ASCII
To represent computer characters (keyboard keys, symbols, etc.) several codes have been developed in the past. IBM created its own code sets, while other computer companies produced codes that were quite different. To standardize this coding system, a committee known as American Standard Code for Information Interchange, or simply ASCII, was commissioned to form a standard code. Today, ASCII (pronounced askey) is widely accepted and used in most computers. In ASCII, each character is given a unique number (code). Surprisingly, lower-case letters have different ASCII codes than the upper-case letters. For example, the ASCII code for lower-case ‘a’ is 97 while the upper- case ‘A’ is 65. Even the blank space has an ASCII code represented by the value of 32. Just keep in mind that when you save the letter A in your computer’s memory it is not the shape of A that is stored. The letter is stored as a series of 1’s and 0’s that represent the letter A. It is important to remember that what you see on the computer monitor or on the printer is a projection of those zeros and ones. You can associate this concept with the mechanism of the traditional typewriter; to type the letter A, you simply press the ‘A’ key and the typewriter’s handle with the engraved A is then hammered onto the paper.
Furthermore, to cover international languages and other symbols, a uniform code known as Unicode was developed.
Binary States
Today it is not necessary to use light bulbs or vacuum tubes to represent the states of on and off. Other means, such as electrical currents or magnetic fields, are commonly used to represent these two states, which we call binary states. You may be wondering why there are two states instead of three or more? One answer would be that it is easier to manipulate and work with binary representation. If it were not in the state of 1, then it would be in the state of 0. You may then ask why use only zeros and ones instead of other numbers, such as 1, 2, and 3. Well, you can represent characters that way too, but using zeros and ones makes it much easier. Some other possible binary state representations can be that if there is a current or not, magnet or no magnet, light or no light, hole or no hole. Perhaps future computers can use biological entities, such as a cell's DNA sequences for binary state representation. As switches have on and off states, the cell also can have two active and inactive states under certain circumstances. Now, imagine millions of microscopic spots (binary states) on a piece of board that can be grouped to form characters, words, and sentences, which thus comprises “information”.
Machine Language and Assembly Language
Now that we have a representation for letters, digits, and other symbols, how can computer functions, such as addition or subtraction, be represented? Do they adopt a similar type of representation? Yes, they do. Each computer operation, the place where the operation occurs, and the result of the operation have a unique code representation. For example, the addition operation will add the contents of two memory locations, and place the result in another memory location. This kind of operation that instructs the computer to perform a task is known as an instruction. We will need an agreement to represent addition, and an agreement to represent different ways to access the memory locations (addresses), as well as the tasks associated with these memories, which means that there is always a finite number of rules and words that tell the computer what to do. Such agreements comprise a language that is known as machine language. The codes used in this language are also composed of zeros and ones.
The use of symbols or mnemonics to replace groups of binary numbers led to the development of assembly language. Obviously, assembly language has its own rules and regulations, but they are closely tied to machine language. Some of the common representations, known as instructions in machine and assembly languages, are Load, Store, Subtract, Jump, and Test. A program is created when these instructions are arranged in a certain order.
Several other languages have been derived from the machine and assembly languages. Each has its own rules and agreements that serve specific tasks. You should think of C/C++ as one level or one layer above assembly language and machine language.
NATURAL LANGUAGES VERSUS COMPUTER LANGUAGES
We use natural languages to communicate and describe events. Each language is composed of sentences and combining words, in conjunction with rules and symbols that form each sentence. Each word has its own meaning. In natural languages there are words or sentences that are ambiguous because they may have more than one interpretation. For example, the sentence “Time flies like an arrow” can be interpreted differently. Moreover, natural languages are a function of time and place, and therefore are dynamic. A word can lose its original meaning or can become obsolete due to lack of use.
To communicate with a computer, a language is required as well. Just like a natural language, computer rules and regulations restrict computer languages. Computer or programming languages consists of finite sets of predefined words, rules, and symbols with no ambiguity. This makes computer languages easy to create and work with, while producing concrete results. Don't be surprised when you only need a few words and rules to begin programming (the number may be as few as your ten fingers). Use it to your advantage and allow your ideas to move forth your imagination into reality.
THE EVOLUTION OF PROGRAMMING LANGUAGES
Programming and human languages have both evolved similarly. Through time, new terms are added or elaborated upon, while others fall out of use and are discarded. Some programming languages continue to exist, while others became obsolete. Among the languages that have survived, there are some that became popular and are used by a majority of users, while certain companies or institutions use others.
Low-Level Languages (LLL)
Originally, machine language was the only language of the computer. Working with a bunch of 0's and 1's is tedious and error-prone. Small mistakes, such as altering a 0 to a 1 or vice versa, will change the meaning completely. When programming in machine language, the programmer has to know about the internal hardware, including the different methods of storing and accessing information, as well as the ways in which the CPU's registers (memory) function and interact with other components. An improvement to the machine language was to replace a group of 0's and 1's with symbols (mnemonics). This symbolic language is called an assembly language. The problem is that assembly language may make the job of programming easier but still machine-dependent, which means that it depends on the computer hardware. It is simply just a one-to-one correspondence of machine language. Due to the fact that both machine and assembly languages are close to the machine level, both are known as Low-Level Languages (LLL). Another problem with these languages is that they vary from machine to machine. Almost every computer chip (CPU) manufacturer such as Intel, Motorola, IBM, and DEC has its own machine language and, as a result, it’s own assembly language. Interestingly, some companies do not standardize the machines that they manufacture. For example, IBM has developed an array of machine languages to serve specific purposes and to be compatible with hardware architecture design within the company. Because the instructions vary from machine to machine, this makes the job of a programmer much more difficult since the same program must be written differently.
Since the computer only understands machine language, assembly language must be converted to machine language in order to be executed. The program that does this conversion is known as an assembler or a translator.
High-Level Languages (HLL)
Although assembly language is one level higher than machine language, it is still unfriendly to humans. To facilitate programming, languages had to move away from the machine level and get closer to natural language. Several new languages were designed after assembly language to serve this purpose, and became known as High-Level Languages (HLL).
Some of the well-known HLL’s are FORTRAN, Lisp, PL1, Pascal, COBOL, BASIC, C/C++, and Java. Each language was developed for a particular design purpose and to facilitate programming for a particular field. However, in order for the computer to understand these high-level languages, they need to be translated into machine language so that the computer can understand them, thereby enabling the program to be executed. There are two types of translators: the Compiler and the Interpreter. The Compiler immediately converts the entire program to LLL, so that it can be executed later, while the Interpreter converts each statement and executes that statement. Each translator has it’s own advantages and disadvantages, which we won't go into further detail for now.
Let us look at how these high-level languages have evolved. We can start with FORTRAN (FORmula TRANslator) and ALGOL (ALGOrithmic Language), which were the first two popular High-Level Languages designed in the mid-1950's. FORTRAN and ALGOL were designed to solve mathematical and scientific problems. ALGOL was used mostly in Europe, while FORTRAN was popular in the US. Although ALGOL was rich in theory and more structured in comparison to other languages, it still did not survive despite several extensions that were made to make this language more useful. It should be mentioned that although ALGOL became obsolete and FORTRAN lost its popularity, both languages have given significant contribution to the design of most other languages.
The design of COBOL (COmmon Business-Oriented Language) was aimed to serve the needs of the business community. Both FORTRAN and COBOL have survived up to now, but they have lost their popularity. At one time almost all mathematical and scientific programs were written in FORTRAN; as a result, huge libraries and packages that had been created to eliminate re-programming throughout the years could not be easily disposed. Similarly, almost all businesses have invested in COBOL, and millions of programming codes were written during those years. These codes cannot be easily substituted, and the cost of transferring these codes to other languages of choice would be astronomical. Therefore, FORTRAN and COBOL are still being used because of their previous domination. ALGOL, COBOL, and FORTRAN may no longer be viewed as the best programming languages any more, but they nevertheless are the basis of many other languages in use today. Another language, Lisp (List Processing) was designed to fulfill the need of researchers in the field of artificial intelligence. Lisp is known as a symbolic language with a structure that is quite different from other languages.
C and C++ as High and Low-Level LANGUAGES
C and C++ have features and characteristics of high-level languages, but can also manage low-level features such as binary operations on bits (bit wise operation) and memory address manipulation. The C language was developed during the 1970's at Bell Labs to challenge the domination of assembly language in system programming. It was tested successfully by way of a powerful operating system known as UNIX. Ever since then, the C language has become a language of choice with scientific and business applications. In academic institutions, C replaced Pascal as the teaching language, not because it is an easy language to learn but because of its popularity and market demand. In the 1980's, a superset of C called C++ was designed at AT&T Bell Labs to incorporate the already demanding features of object-oriented programming (OOP) into the C language, so it can fulfill the needs of software developers and the marketplace.
Turbo C/C++, Microsoft C/C++, Think C/C++ are dialects of C/C++ in the world of personal computers. The latest, Java, is a mixture of good features from C/C++ and other existing languages like Smalltalk, and even incorporates some features from Lisp.
If you are wondering how similar and different programming languages are, here is an example. The task is to add two numbers, the numbers are placed in two memory locations and the result should be stored in another memory location. Examples follow:
Machine Language: 1111001110000
0001000011110
1000001000000
Assembly Language: mov a, R1
add b, R1
mov R1, c
FORTRAN: c = a + b
ALGOL: c := a + b
COBOL: add a to b giving c
APL: c ¬ a + b
Lisp: (set! c (+ a b) )
Most of the other languages such as BASIC, PLI, C/C++, and Java use the statement
c = a + b, which is the same statement that FORTRAN uses.
PROGRAMMING EVOLUTION
You may want to know how programming concepts started. One can look back to the early stages of human evolution when thoughts and plans were put together to perform a necessary task. If you raise the question as to whether programming concepts or programming languages were introduced first, you can compare it to the age-old question of which came first, the chicken or the egg. One thing we can say is that the evolution of programming concepts and programming languages is correlated. Just like programming languages, programming concepts have gone through many different stages since their beginnings.
Let us discuss what programming is, and how different people view it. It has been said that programming is a technique, a strategy, and involves a lot of thinking. Some suggested that programming requires intuition. Many people associate programming with math, science, and/or engineering. Since it is a human activity, it has been argued that programming is an art or even a social or psychological subject. There were and still are people who associate programming with religion, in the sense that at some stage you must just believe in it. Some people argue that the definition of programming depends on what you want it to do and how you want to do it. In truth, programming is a combination of some or all of the above.
If I had to find an analogy between programming and other activities, I would use painting as an example because both involve planning, technique, style, and use of tools, skill, and even intuition.