Contents  1-5  6-11  12-16  17-21  22-27   28-33  34 - 38  39-46  Projects   MFC

   Contact
   C
   C++
   Visual Basic
   Java
   JavaScript
   DHTML
   Style Sheets
   About
   Normalization
   Active X
   TDC Binding
   PHP
   Perl and CGI
   Flash
   XML
   SQL
   Chat
   MCSE
   Linux
   Cabling   
 

   
 
    
    

.

  "I think computer viruses should count as life.  I think it says something about human nature that the only form of life we have created so far is purely destructive.  We've created life in our own image." - Stephen W. Hawking

Note: When I put these tutorials together a few years ago, I used Microsoft's Visual C++ 6.0.  I attempted to keep all the console program code in as generic a format as possible, so that you would be learning generic C++.  This way, what you learn will be applicable to Unix/Linux and the GCC compiler, Borland's compiler, and Microsoft's Visual Studio.  Since that time, Microsoft has changed several things with the .Net Development Studio, and several functions have been deprecated. However, you may still use Microsoft's Visual C++ .Net Development Environment provided that you create an "empty .Net" project from within the application, and you must change every line you see that says "#include <iostream.h>" to "#include <iostream>".  You must also add the line "using namspace std;" beneath this changed include line, else you will have to call functions and classes using two colons such as "std::cout" and "std::cin".  Rather than change these examples, I will leave them as they are for those using Visual C++ 6.0, Linux's gcc compiler, or other non-.Net compilers.  However, if you are using .Net, add these to lines to each example in these tutorials to make them compatible with .Net, replacing the single "#include <iostream.h>" line:

#include <iostream>
using namespace std;

// Rest of the program goes here,
// minus the old C++ 6.0
// "#include <iostream.h>".

If using VS 6.0, in order for the getline() function to work properly without requiring an extra "ENTER", make sure you go to \Program Files\Microsoft Visual Studio\VC98\Include, find the file "string" (NOT "string.h"), go to line 165 in notepad, and change _I.rdbuf()->snextc(); to _I.rdbuf()->sbumpc();. Microsoft never fixed the bug and shipped the compiler with it broken. Instead of .Net Studio or VS 6.0 which you have to pay for, I recommend BloodShed 5.0, which is an excellent compiler and completely free for you to download. It's based on the Linux open source gcc compiler.

A. Introduction

1. Object Oriented vs. Procedural Languages
C++, like Java, is object oriented, and it is just one tool among many for today's developers.  It's primary advantage over other languages is that it can produce software with greater power, speed, and efficiency.  It gives the developer far more control over memory management than other languages.  It's disadvantage is that it is less forgiving and more complex than other OOP languages that manage memory automatically.  This greatly increases development time.  Many projects can be developed faster in other languages, at the cost of efficiency in the finished application.  In choosing this language to develop in, one needs ample time and resources.

One of the things that sets C++ apart from C is its use of classes and structures, which provide "encapsulation", whereas procedural languages such as C or FORTRAN would use functions in a more linear fashion.  Object oriented languages attempt to emulate real world systems and structures more closely that procedural programming. In the past computers weren't as powerful and memory was very expensive.  As a result, programs were largely console or command prompt based (i.e. DOS, Unix without X Windows).  Software was written in a linear and procedural manner, to optimize efficiency when running on slow processors and to squeeze every available iota of usefulness out of limited, paltry and expensive amounts of memory.  Rich multimedia, power and vast capabilities weren't as important as simply coding something that could run on a bare minimum of hardware.

2. Moore's Law
Over time, computers exponentially increased in speed and sophistication in fulfillment of Gordon Moore's "Law of Accelerating Returns", theorized in 1965.  Moore's Law predicts that the number of transistors per integrated circuit doubles every 18 months.  Doubling transistors effectively means doubling the binary on/off calculations per second in the same amount of space using the same amount of raw material.  This miniaturization and resource efficiency both increases speed and lowers the cost of production.  Each cycle of development in technology feeds the subsequent wave, yielding an exponential increase.  To illustrate this concept, look at a brief history of technology:
 

1822 - Charles Babbage, "The Difference Engine"
1832 - Charles Babbage, "The Analytical Engine", 1st computer though never worked
1843 - Ada Lovelace, 1st programmer, Speculates on a computer's ability to emulate human intelligence.
1871 - Charles Babbage dies.
1877 - William Thomson (Lord Kelvin) demonstrates computers can be programmed
1927 - Heisenberg's uncertainty principle. 5 Years later Quantum Mechanics by Neils Bohr and Werner Heisenberg.
1928 - Minimax theorem, Jon Vann Neumann, used in game programs.
1928 - 1st television
1930 - 60% all houses have radio
1931 - incompleteness theorem
1931 - electron microscope
1937 - Alan Turing, Turing Machine
1937 - Turing and Church state that all problems that human can solve can be reduced to set of algorithms solved by machine
1940 - "ABC", 1st electronic non-programmable PC.
1940 - "Robinson", 1st operational computer, uses electro-mechanical relays to decode ENIGMA in WWII.
1941 - Z3, 1st programmable digital computer.
1943 - "Colossus", uses tubes 1,000 times faster than relays in "Robinson". Decodes more German code.
1944 - "Mark I", Howard Aiken, uses tubes and punch paper for programming, 1st programmable built by American.
1945 - Stored program concept published.
1946 - ENIAC, 1,000 times faster than Mark I, 1st electronic, programmable, general-purpose computer.
1946 - .02% of Americans own TV
1947 - transistor invented
1949 - EDSAC, 1st stored-program computer
1949 - George Orwell's "1984"
1950 - Alan Turing presents "Turing Test"
1950 - color TV 1st broadcast, B and W TV now trans-Atlantic
1951 - EDVAC, 1st computer to use stored-program concept
1952 - UNIVAC, owned by CBS television, successfully predicts election of Eisenhower
1952 - IBM 701, 1st computer for mass production
1953 - chemical structure of DNA
1955 - William Shockley Semiconductor laboratory founded starting silicon valley
1955 - U.S. Develops 1st design for industry robot
1955 - IPL II, 1st AI language
1956 - "The Logic Theorist", uses recursive search techniques
1956 - FORTRAN invented
1956 - MANIAC I, 1st computer to beat a human at chess
1956 - term "Artificial Intelligence" coined
1957 - General Problem Solver, uses recursive search to solve problems
1958 1st integrated circuit
1958 - LISP, AI language created
1958 - CDC 1604, Seymour Cray, builds 1st full transistor supercomputer.
1959 - computer beats humans at checkers
1959 - COBOL developed
1959 - 1st Xerox copier
1960 - 1st laser, ruby rod
1960 - 6,000 computers in operation in the US.
1956 - 72% of homes have television
1983 - 93% of homes have television

Note: You can see that technological advances increase exponentially and algorithmically.  Each advance increases the velocity of subsequent advances.  Since 1983 we have seen technology literally consume, envelop and re-define the world around us.  We can only assume that as all branches of science and technology continue to build upon the works of others, computer technology will continue to transform our lives in ways we can't even imagine, and that these changes will occur at an ever-increasing velocity.  How many of us have experienced the bitter sorrow of purchasing the fastest CPU or some ultimate piece of computer hardware, only to find that before we can carry it home and take it out of the box there's something even more powerful, compact, faster and cheaper being advertised in the evening newspaper?

3. Event-based Programming and Input
Today, most popular operating system environments employ a graphical user interface (GUI) such as are Microsoft's "Windows" and Linux's/Unix's window manager, "X Windows".  Both of these popular environments provide for "event based" input in a program.  Event based input is random and unpredictable input.  A user no longer has to follow a linear path of commands typed at a command prompt to access a particular part of a program. She or he can now, randomly and at will, access any part of a Windows or X Windows program from any other part.  Event-based input adds great power, versatility, and functionality to a program for the user.  For the programmer, it adds its own share of problems.  Unpredictable sequences of events from the user must be foreseen and accounted for in the debugging process.  Windows and X Windows graphical user interfaces, event-based input, continuous production of faster and more powerful computers that are less and less expensive, and object oriented programming have all combined to make possible the creation of software of a complexity never before imagined. 

Artificial Intelligence (AI) is not as flamboyant in reality as it has been portrayed in science-fiction, but it is already very much a part of our lives.  One can only look with wonder at the evolution of neural networks, global data structures and intelligent search engines, such as Google and AskJeeves.   AI, only a LISP fantasy thirty years ago, is infiltrating every aspect of modern software as routines and subroutines become more and more complex in our attempt to develop software that is easier to use, intuitive and forgiving of our mistakes.  AI techniques are employed in our databases and in our spreadsheet and word processing software.  They are employed in modern development environments.  They are used in all of the latest and most popular games.  AI routines are largely made possible by object oriented programming, which is well adapted to deal with the increasing complexity of AI techniques used in large, complex pieces of software composed of hundreds of thousands of lines of code. 

If It Interests You:  The fundamentals of AI will not be covered in this course.  However, it may spark your interest and be something you choose to pursue on your own out of curiosity.  It is a realm of discovery and controversy that sparks moral, ethical, scientific, and pragmatic debate among all those who pursue it.  Minds as great as the world renown physicist, Stephen Hawking, foresee AI as a threatening menace to humanity. Others, such as Bill Gates and Ray Kurzweil, see it as the ultimate destiny of mankind to merge with his technology.   Gates expresses his own ideas concerning this subject in the book, "The Road Ahead".  In Kurzweil's book, "The Age of Spiritual Machines" - 1999, Kurzweil defines 3 methods increasingly utilized, sometimes simultaneously, in creating artificially intelligent software.  Lets look at these three using the example of a chess game:

1. Recursive Algorithms - Recursion involves taking a large and complex problem and reducing it repetitively into smaller and smaller sets of tasks.  Iterations in a recursive algorithm may take the form of simple formulas that use the massive calculating potential of today's CPUs and memory (brute force).  A recursive algorithm includes itself as part of its algorithm.  It is a function that invokes itself, and an object that creates an instance of itself by its own construction.  Logistically, it says "For my next step take my next best step. If I'm done I'm done."  You can calculate the many permutations possible in a chess game by following simple rules: "Pick my next best move. If I win, I'm done".  Functions keep calling themselves in an ever-expanding TREE of moves and counter-moves that,  with enough raw computing power, can fathom all possible moves on the chess board at each step of the game.  If a move results in a win, the routine picks that move.  If a winning move is unavailable, but a tie is, then select that move.  If neither a win nor a tie is available, keep playing until the player wins or a possibility opens for a win or tie.  This technique requires an escape mechanism (perhaps a sentinel value) telling the program when to abandon recursive expansion and a clear CODING of the problem.

2. Neural Net Algorithms - Neural nets must be taught, they must learn.  Neural nets recognize patterns and relationships.  They build strong and weak associations regarding data and unexpected situations by assigning and remembering a set of values for each experience.  These values can be complex objects or numerical in nature.  A neural net is always asking itself, "On a scale of 1 to 10, based on the data and history I have acquired, how likely is this pattern to occur?  How dangerous is this situation?"  It then answers itself, "7 times out of 10, this is what occurs."  These algorithms are built on the premise that, sometimes the easiest and most efficient way to learn the right way of doing something, is to do it the wrong way a few times.  They make associations over time.  This involves "layers" and "training" the neural net.  As with human beings, the amount of time spent learning and training directly affects the performance of neural net AI.  It mimics a human being's sense of intuition and wisdom, acquired through interaction and experience with its environment.  Though elementary today, neural nets, when combined with recursion, show great promise in the future.  In our chess game, the neural net algorithm will start off much as a child would - helpless against the player.  But after each subsequent game it plays, it stores with flawless memory each move of each player.  It categorizes and analyzes each move that led to a win, a tie or a loss.  The moves that lead to wins are given stronger values, the moves that lead to losses are given weaker values.  It will then select the moves given stronger values for each subsequent game.  It thus learns from every opponent that plays it, eventually selecting moves that allow it to win. 

3. Evolutionary Algorithms - Evolutionary algorithms create massive amounts of small programs, functions or objects focused on a certain specified task.  They are allowed to change and adapt, in much the same way that modern computer viruses and worms (Melissa.vbs, Lion, Happy.exe, etc.) adapt when released.  They enhance themselves and multiply when successful through adaptation, they eliminate themselves when unsuccessful.  These techniques utilize aspects of Chaos Theory, recursion and fractalization.   The randomness in the environment becomes fodder for change.  You can find a good deal of information on virus and antivirus routines online at websites such as Astalavista.com.  You may watch their evolution taking place before your eyes.   A word of caution - programmer beware!  Evolutionary algorithms can be unpredictable, especially in the form of computer viruses, and the experimenter may get more than he or she bargains for.  Principles to follow are, "Do no harm", and one must think in terms of containment.  What one person considers a harmless practical joke or an experiment can be considered by others as a threat to society or even an act of terrorism, and many careers have been ruined by one single careless act of poor judgment.  In this third example, many chess routines of different algorithms would be written and allowed to compete against players and one another.  They would include within their instruction set implicit functions providing for random adaptation to their environment.  As the routines are allowed to run, some would become successful whereas others would fail miserably.  The ones that played most competitively would be allowed to continue and adapt further, starting the process over.  The ones that were unsuccessful would be retired.


B. Basic Concepts

1. Pillars of object oriented development

1. Encapsulation - doing one well-defined thing completely. This began with functions and methods, but C++ encapsulates more completely by combining methods and data members into self-contained CLASSES.  Components should be built that have specific properties - a developer should be able to plug them into his or her program as needed.  This treats data and procedures that act upon the data as a single "object" - a self-contained entity with an identity and certain characteristics of its own.

2. Data Hiding - The inner workings of classes should be hidden. The prevailing philosophy for developing complex software is that you don't need to know how all the library and foundation classes and precompiled code work, simply how to use them.  This enables adding complex functions and routines to code without having to "re-invent the wheel", so to speak.  It speeds up development time through the use of encapsulated libraries of code, functions and classes that each perform a specific task and snap together in a "Lego-like" fashion. They are then used in constructing larger and more complex bodies of code that incorporate these functions and the whole becomes more than the sum of its parts.  Data Hiding also provides greater security and flexibility by making it possible to examine relevant portions of source code without seeing the source in its entirety.  Entire classes and libraries can be utilized by parts of a program through passing arguments and parameters to accessor methods.

3. Inheritance - Reuse, reuse, reuse!  Don't reinvent the wheel.  A new type can be declared as an extension of an old type, a sub class of an existing class, or derived types and classes from base classes.  In this way, methods and attributes can be incorporated into derived objects without having to be repeated.

4. Polymorphism - different objects do the right things through function polymorphism and object polymorphism.  It is multiple inheritance, derivatives of the same object branching off into many forms.  This most closely models the "has-a" and "is-a" relationship of the real world.

2. The Process of Compiling Source Code

compiler - produces an object file.
linker - turns object file into executable program.
LIBRARY = a collection of linkable files that were created, inherent in an OS or purchased.
FUNCTION = a block of code that performs a service, one or more actions (adding 2 numbers or printing to the screen).
CLASS = a collection of data and related functions.
DEBUG = edit source code, recompile, re-link and rerun

Most compilers, such as Microsoft's Visual C++ Compiler combine the functions and processes of building, compiling and linking along with a set of standard library classes and functions into a single piece of software. Design a program thoroughly before writing it. Begin by asking "What problem do I need to solve?". Can this be accomplished without writing custom software? There are many relevant libraries and source code available for sale, many more are available for free. These may save you countless heartache in your projects. Again, don't reinvent the wheel. A prevailing philosophy in the Linux open source movement is to stand on the shoulders of those who have gone before you, and allow those who come after you to stand on your shoulders. There are large amounts of source code on-line and libraries available that will perform specific aspects of a program that you can simply add to your projects. This can save lots of money and months of costly development time.

After source code is compiled an object file is produced (usually named *.obj). Run your linker to create an executable program. C++ programs are created by linking together 1 or more object files with 1 or more library files. In Microsoft's Visual C++ 6.0, all of these processes are integrated for you.

C. Your First C++ Program

Let's create our first C++ program. This will be a "Console Program". We will use a simple color code in this example. Red is for source code that is typed into the compiler and compiled. Blue is for output rendered upon executing the compiled source code. Since the traditional "first program" of any programming language is one that outputs the phrase "Hello World", let's create a short program in C++ that will render the output of "Hello World" to the display. Follow these 14 steps:

1. Open Microsoft's Visual C++ 6.0.
2. Click "File" then "New".
3. Click "Win32 Consol Application".
4. Type "HelloWorld" in the field titled "Project Name". Click "Ok".
5. Under "What Kind of Application Do You Want to Create?" Check the "An Empty Project" radio button.
6. Click "Finish". A an alert box will pop up indicating your selections. Click "OK".
7. Click "File" again and "New".
8. Make sure the "Files" tab is selected and click "C++ Source File".
9. In the field "File Name" type "HelloWorld". Click "OK".
10. Type the following source code, exactly as shown, into the text window:

#include <iostream.h>
int main()
{
     cout << "Hello World!\n";
     return 0;
}

Note: The compiler will color code what you type by syntax as it recognizes each part of your program.

After typing in the source, we need to compile it.  So now follow these steps:

11. From the top menu, select "Build" and then "Compile Helloworld.cpp". Notice the display at the bottom. When the compiler is finished you should receive the message "Compiling... HelloWorld.obj - 0 error(s), 0 warning(s)". If not, check your source code to make sure there are no typographical errors.
12. Now that the program is compiled into object code, let's build and link it. Do this by again selecting "Build" and then "Build HelloWorld.exe". You should receive the message "Linking... HelloWorld2.exe - 0 error(s), 0 warning(s)" if all goes well.
13. Having done all this without errors, click "Build" again and then select "Execute HelloWorld.exe". You can also click the red exclamation mark on your tool bar as a short cut to execute your programs. Your display should render this message:

Hello World!

14. Congratulations! You have written your first program in C++. After doing this, let's go over a few basic concepts of syntax and grammar.
 

D. Syntax and Grammar

1. # = This symbol triggers the preprocessor.
2.
#include = Every time it sees the # sign it modifies and inserts the source code contained in the specified file in the <> brackets..
                    It is this code that is fed to the compiler, not the actual "
#include" statement.
3.
iostream.h = a common header file provided by most compilers in the standard library. It contains source code needed for basic
                        I/O (input/output) operations. Without specifying that source code from this file be included in the program, basic
                        functions like
cout << and cin >> would not be defined or understood by the compiler.
4.
int main() = a special function, starts automatically when program executed. Like all functions it must state what kind of value it
                      will return. It will always return int (an integer) or void. It is invoked by the operating system to start the program. All
                      calls to outside source will be contained in the main() function.
5. function - a block of code that performs one or more actions. It is invoked or called. Functions always begin with a { and end with a
                    }. Opening and closing parenthesis - ( and ), are used to pass parameters to the function from other parts of the
                    program. These parameters can be hard coded values, integers, variables, array elements or other functions. A function
                    must include a return type. While this will be expanded later, in the case of "
main" function, the return type will always
                    either be "
int" or "void".
6. cout = Used to output information to the display. It is contained in the included header file "iostream.h" that we added with the
              preprocessor.
7.
<< = direction of data stream. It is "<<" for cout when outputting data to the display. It moves the opposite direction for user
           input, becoming "
>>", when using cin.
8.
"Hello World\n"; = Whatever is placed in quotation marks is sent to the display.
9.
\n = inserts a carriage return/end of line after displaying "Hello World".
10.
; = Terminates a statement, cout << "Hello World!\n"; is a statement that must be terminated with a semicolon.
11.
return 0; = ends the main() function, thus ending the program.


©2004 C. Germany