Basic Ideas

This article will give you a good understanding of the basic concepts and practices of the C++ language, so that you will have the foundation to eventually learn these ideas in detail as you continue working with the language. It is excerpted from Ivor Horton’s Beginning ANSI C++ The Complete Language (Apress, 2004; ISBN 1590592271).

AT FIRST SIGHT, a connection between learning C++ programming and poultry would seem to be unlikely, but there is—it’s the chicken-and-egg problem. Particularly in the early stages of understanding C++, you’ll often have to make use of things in examples before you properly understand them. This chapter is intended to solve the chicken-and-egg problem by giving you an overview of the C++ language and how it hangs together, and by introducing a few of the working concepts for things that you’ll be using before you have a chance to understand them in detail.

All the concepts that you’ll read about here are covered in more detail in later chapters. Most of this information is just to set the scene before you get into the specifics of writing C++ programs. You’ll see what a simple C++ program looks like, and then you’ll pull it to pieces to get a rough idea of what the various bits do. You’ll also look at the broad concepts of programming in C++ and how you create an executable program from the source code files you’ll be writing.

Don’t try to memorize all the information in this chapter. Concentrate on getting a feel for the ideas presented here. Everything mentioned in this chapter will come up again in later chapters. Here’s an overview of what this chapter covers:

  • What the features of C++ are that make it so popular

  • What the elements of a basic C++ program are

  • How to document your program source code

  • How your source code becomes an executable program

  • How object-oriented programming differs from procedural programming

Programming Languages

You’re probably familiar with the basic ideas of programming and programming languages, but to make sure we’re on common ground, let’s do a quick survey of some of the terms you’ll encounter as you progress through the book. You can also put C++ into perspective in relation to some of the other programming languages you’ll have heard of.

There are lots of programming languages, each with its advantages and disadvantages, and its protagonists and detractors. Along with C++, other languages that you’re likely to have come across include Java, BASIC (an acronym for Beginner’s All-purpose Symbolic Instruction Code), COBOL (an acronym for Common Business-Oriented Language), FORTRAN (an acronym for formula translator), Pascal (after Blaise Pascal, a French mathematician), and C (simply because it was a successor to a language called B). All of these are referred to collectively as high-level languages, because they’re designed to make it easy for you to express what the computer is to do, and they aren’t tied to a particular computer. Each source statement in a high-level language will typically map to several native machine instructions. A low-level language is one that is close to the native machine instructions and is usually referred to as an assembler language. A given assembler language will be specific to a particular hardware design, and typically one assembler instruction will map to one native machine instruction.

A Potted History

FORTRAN was the first high-level language to be developed, and the first FORTRAN compiler was written in the late 1950s. Even though FORTRAN has been around for over 40 years, it’s still used today for scientific and engineering calculations although C++ and other languages have eroded much of its usage.

COBOL is a language exclusively for business data processing applications, and it’s almost as old as FORTRAN. Although relatively little new code is written in COBOL, there is an immense amount of code that was written years ago that’s still in use and still has to be maintained. Again, C++ has become the language of choice for many business data processing programs.

BASIC emerged in the 1970s when the idea of a personal computer was being conceived. Interestingly, the first product sold by Microsoft was a BASIC interpreter. The ease of use inherent in the language resulted in a rapid growth in its popularity that continues to this day.

Java was developed in the 1990s. Its original incarnation as a language called Oak was really intended for programming small consumer electronics devices. In 1995 Oak evolved into the Java language for embedding code in web pages and from there into what it is today. The primary reason for the success of Java is its portability. A Java program can run unchanged on any hardware platform that supports it. The syntax of the Java language has many characteristics that make it look similar to C++, but there are significant differences. Although Java gains over C++ on portability, it can’t match C++ in execution performance.

C was developed in the early 1970s as a high-level language that could be used for low-level programming, such as implementing operating systems. Most of the Unix operating system is written in C.

C++ was developed by Bjarne Stroustrup in the early 1980s as an object-oriented language based on C. Hence the name, C++, which in C++ means C incremented. Because C++ is based on C, the two languages share a common subset of syntax and functionality, and all of the capabilities in C for low-level programming are retained in C++. However, C++ is a much richer and more versatile language than its ancestor. The vastly improved memory management features and the object-oriented capabilities of C++ means that C functionality represents a very small subset of C++. C++ is still unrivaled in scope, performance, and power. For this reason, the majority of high-performance applications and systems are still written in C++ today.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=Interpreted vs. Compiled Program Execution}

Whatever the programming language, the programs that you write are made up of separate instructions or source statements that describe the actions that you want the computer to carry out. These are referred to collectively as source code and are stored on disk in a source file.A single C++ program of any size will consist of several source files.

Programming languages are designed to make it relatively easy for you to describe the actions you want a computer to carry out compared with the form of program that a computer can actually execute. Your computer can only execute programs that consist of machine instructions (also called machine code), so it can’t execute your program’s source code directly. There are basically two ways in which a program written in one of the languages I mentioned previously can get executed and, for the most part, a particular language will use one or the other. Programs written in BASIC, for example, are often interpreted—that is, another program called an interpreter inspects the BASIC source code, figures out what it’s supposed to do, and then causes that to be done. This is illustrated on the left side of Figure 1-1.


Figure 1-1.  Interpreted and compiled program execution

C++, on the other hand, is usually a compiled language. Before you can execute your C++ program, it must be converted to machine language by another program called a compiler. The compiler inspects and analyzes the C++ program and generates the machine instructions that will produce the actions specified by the source code. Of course, in reality neither interpreting nor compiling is quite as simple as I’ve described them here, but in principle that’s how they work.

With an interpreted language, execution is “indirect,” by which I mean the intent of the source code needs to be determined each time a program is executed. For this reason, execution is much slower—sometimes of the order of 100 times slower—than the equivalent program in a compiled language. The upside is that you don’t have to wait and compile a program before you run it. With an interpreted language, as soon as you’ve entered the code, you can execute the program immediately. A given language is usually either compiled or interpreted, and it’s typically the design and intended use of the language that determines which. Having described BASIC as an interpreted language, I should point out that it isn’t exclusively so; there are compilers for the BASIC language.

The question of which language is the “best” language sometimes comes up. The short answer is that there is no such thing as the “best” language—it depends on the context. Writing a program in BASIC is typically very rapid compared with most other languages, for instance, so if speed of development is important to you and obtaining the maximum execution performance isn’t, then BASIC is an excellent choice. On the other hand, if your program requires the execution performance that C++ provides, or you need the capabilities in your application that are available in C++ but not in BASIC, then C++ is obviously what you would use. If your application really must execute on a wide range of different computers and you aren’t concerned about achieving the ultimate in execution performance, then Java may be the best option.

Of course, the length and steepness of the learning curve will vary among different languages. In terms of the amount of time needed to learn a language, C++ is probably at the higher end of the scale, but this shouldn’t put you off. It doesn’t mean that C++ is necessarily more difficult. It does mean that there’s a great deal more to C++ than most other languages, so it takes a little longer to learn.

As a final thought on which language you should learn, any professional programmer worth his or her salt needs to be comfortable in several programming languages. If you’re a beginner, this may sound a little daunting, but once you’ve grappled with and conquered your first two programming languages, you’ll find it gets a lot easier to pick up others. Your first programming language is almost always the hardest.

Libraries

If you had to create everything from scratch every time you wrote a program, it would be tedious indeed. The same kind of functionality is often required in many programs— for example, reading data from the keyboard, or displaying information on the screen, or sorting data records into a particular sequence. To address this, programming languages usually come supplied with considerable quantities of prewritten code that provides standard facilities such as these, so you don’t have to write the code for them yourself every time.

Standard code that’s available for you to use in any of your programs is kept in a library. The library that comes with a particular programming language is as important as the language itself, as the quality and scope of the library can have a significant effect on how long it takes you to complete a given programming task.

Why Is C++ Such a Great Language?

C++ enjoys extraordinary popularity across virtually all computing environments: personal computers, Unix workstations, and mainframe computers. This is all the more remarkable when you consider the degree to which history weighs against a new programming language, no matter how good it is. The inertia implicit in the number of programs written in previous languages inevitably slows the acceptance of a new language. Added to this, there’s always a tendency among most professional programmers to stick with what they know and are expert and productive in, rather than jump in at the deep end with something new and unfamiliar, in which it will take time to develop fluency. Of course, the fact that C++ was built on C (which itself was the language of choice in many environments before the advent of C++) helped tremendously, but there’s a great deal more to it than that. C++ provides you with a unique combination of advantages:

  • C++ is effective across an incredible range of applications. You can apply C++ to just about anything, from word processing to scientific applications, and from operating system components to computer games.

  • C++ can be used for programming down at the hardware level—for implementing device drivers, for instance.

  • C++ combines the facility for efficient procedural programming that it inherits from C with a powerful object-oriented programming capability.

  • C++ provides extensive facilities in its standard library.

  • There are many commercial libraries supporting a wide range of operating system environments and specialized applications for C++.

You’ll also find that just about any computer can be programmed in C++, so the language is pervasive across almost all computer platforms. This means that it is possible to transfer a program written in C++ from one machine to another with relatively limited effort. Of course, if this is truly going to be a straightforward process, you need to have in mind when you write the program that you intend to run it on a different machine.

The ANSI/ISO Standard for C++

The international standard for C++ is defined by the document ISO/IEC 14882, which is published by the American National Standards Institute (ANSI). You can get a copy of this standard if you wish, but remember, the standard is intended for use by compiler writers, not by students of the language. If that hasn’t discouraged you, you can download a copy for a relatively reasonable fee from http://webstore.ansi.org/ansidocstore/default.asp.

Standardization of a language is fundamental when you want to transfer a program written for one type of computer to another. The establishment of a standard makes possible a consistent implementation of the language across a variety of machines. A full set of standard facilities across all conforming programming systems means that you’ll always know exactly what you’re going to get. The ANSI standard for C++ defines not only the language, but also the standard library. Using the ANSI standard for C++ makes the migration of applications between different machines easier and eases the problems of maintaining applications that run in more than one environment.

Another benefit of the ANSI standard for C++ is that it standardizes what you need to learn in order to program in C++ in any environment. The existence of the standard itself forces conformance over time, because it provides the only definitive reference for what a C++ compiler and library should provide. It removes the license to be “flexible” that compiler writers have had in the absence of an agreed standard, so when you buy a C++ compiler that conforms to the ANSI standard, you know what language and standard library capabilities you’re going to get.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=A Simple C++ Program}

Let’s take a look at a very simple C++ program and find out what its constituents are. You don’t need to enter this code right now; it’s just here so that you can get a feel for what goes into making up a program. I don’t go into all the details at the moment either, as everything that appears here will be explored at length in later chapters. Figure 1-2 illustrates a simple C++ program.


Figure 1-2.  A simple C++ program

The program shown in Figure 1-2 displays the following message:

============================================================
The best place to start is at the beginning
============================================================

This isn’t a very useful program, but it serves to demonstrate a few points. The program consists of a single function, main(). A function is a self-contained block of code that’s referenced by a name, main in this case. There may be a lot of other code in a program, but every C++ application consists of at least the function main(). There can be only one function called main() within a program, and execution of a C++ program always starts with the first statement in main().

The first line of the function is

int main()

which identifies that this is the start of a function with the name main. The int at the beginning indicates that this function will return an integer value when it finishes executing. Because it’s the function main(), the value will be received by the operating system that calls it in the first place.

This function main() contains two executable statements, each on a separate line:

 cout << “The best place to start is at the beginning”;
 return 0;

These two statements are executed in sequence. In general, the statements in a function are always executed sequentially, unless there’s a statement that specifically alters the sequence of execution. You’ll see what sorts of statements can do that in Chapter 4.

In C++, input and output are preferably performed using streams. If you want to output something from a program, you put it into an output stream, and when you want something to be input, you get it from an input stream. A stream is thus an abstract representation of a source of data, or a data sink. When your program executes, each stream is tied to a specific device that is the source of data in the case of an input stream and the destination for data in the case of an output stream. The advantage of having an abstract representation of a source or sink for data is that the programming is the same regardless of what the stream actually represents. You can read data from a disk file in essentially the same way as you read from the keyboard, for instance. The standard output and input streams in C++ are called cout and cin, and by default they correspond to your computer’s screen and keyboard, respectively.

The first line of code in main() outputs the character string “The best place to start is at the beginning” to your screen by placing it in the output stream, cout, using the insertion operator,<<. When we come to write programs that involve input, you’ll see its partner, the extraction operator, >>.

A header contains code defining a set of standard facilities that you can include in a program source file when required. The facilities provided by the C++ standard library are stored in headers, but headers aren’t exclusively for that. You’ll create your own header files containing your own code. The name cout referred to in this program is defined in the header iostream. This is a standard header that provides the definitions necessary for you to use the standard input and output facilities in C++. If your program didn’t include the following line:

#include <iostream>

then it wouldn’t compile, because the <iostream> header contains the definition of cout, and without it the compiler can’t know what cout is. This line is an example of what is called a preprocessing directive, which you’ll investigate in depth later in the book. The effect of the #include is to insert the contents of the <iostream> header into your program source file at the point where the directive appears. This is done before your program is compiled.


TIP  Note that there are no spaces between the angled brackets and the standard header name.With many compilers, spaces are significant between the two angled brackets, < and >; if you insert any spaces here, the program may not compile.

The second and final statement in the body of the function name is

 return 0;

This ends the program and returns control to your operating system. It also returns the value zero to the operating system. Other values can be returned to indicate different end conditions for the program and can be used by the operating system to determine if the program executed successfully. Typically, zero indicates a normal end to a program, and any nonzero value indicates an abnormal end. However, whether or not a nonzero return value can be acted upon will depend on the operating system concerned.

Names

Lots of things in a C++ program have names that are used to refer to them. Such names are also referred to as identifiers. There are five kinds of things that you’ll give names to in your C++ programs:

  • Functions are self-contained, named blocks of executable code. Chapter 8 goes into detail on how to define these.

  • Variables are named areas in memory that you use to store items of data. You’ll start with these in Chapter 2.

  • Types are names for the kinds of data that you can store. The type int, for example, is used for integers (whole numbers). You’ll see something on these in Chapter 2 and more in subsequent chapters, particularly Chapter 11.

  • Labels provide a means of referring to a particular statement. These are rarely used, but you’ll look at them in action in Chapter 4.

  • Namespaces are a way of gathering a set of named items in your program under a single name. If that sounds confusing, don’t worry—I’ll say more about them shortly, and you’ll look at them again in Chapter 10.

In C++, you can construct a name using the upper- and lowercase Latin letters a to z and A to Z, the underscore character (_), and the digits 0 to 9. The ANSI standard for C++ also permits Universal Character Set (UCS) characters to be included in a name for reasons I cover in a moment.

The ANSI standard allows names to be of any length, but typically a particular compiler will impose some sort of length limit. However, this is normally sufficiently large (several thousand characters) that it doesn’t represent a serious constraint.

Whitespace is the term used in C++ to refer to spaces, vertical and horizontal tabs, and newline and form-feed characters. You must not put whitespace characters in the middle of a name. If you do, the single name won’t be seen by the compiler as such; it will be seen as two or more names, and therefore it won’t be processed correctly. Another restriction is that names may not begin with a digit.

Here are some examples of legal names:

value2  Mephistopheles  BettyMay  Earth_Weight  PI

Here are some names that aren’t legal:

8Ball   Mary-Ann   Betty+May    Earth-Weight   2PI


CAUTION
Note that names that contain a double underscore (_ _) or start with an underscore followed by an uppercase letter are reserved for use by the C++ standard library, so you shouldn’t choose such names for use in your programs.Your compiler probably won’t check for this, so you’ll only find out that you have a conflicting name when things go wrong!

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=Names Using Extended Character Sets}

As mentioned in the previous section, the C++ standard permits UCS characters to be included in a name. You can write them in the form Udddddddd or the form udddd, where d is a hexadecimal digit in the UCS code for the character.

No one really expects anyone to include characters in names like this, though. Embedding U followed by a bunch of hexadecimal digits in a name would hardly improve the readability of the code. The purpose of allowing UCS characters in a name is to allow compiler writers to accommodate names written in characters for national languages other than English, such as Greek, or Korean, or Russian, for instance.

The C++ standard allows a compiler to be implemented so that any characters can be used to specify a name. Any compiler that takes advantage of this must then translate the characters that aren’t in the basic set to the standard representation for UCS characters noted previously, before the compilation of the code begins. In the source code someone may write the name Khhra, which will be meaningful to a Russian programmer. Internally the compiler will convert this name to one of the two standardized representations of UCS characters before it compiles the code, perhaps as /u041A/u043D/u0438/u0433/u0430. Indeed, regardless of the character set used to write names in the source, it will always end up as characters from the basic set that you saw initially, plus possibly UCS characters as Udddddddd or as udddd.

You must always use the basic set of characters a to z, A to Z, 0 to 9, and the underscore in a name as explicit characters. Using the UCS codes for these characters in a name is illegal. The reason for this is that the standard doesn’t specify the encoding to be used for the basic set of characters, so this is left to the compiler. Consequently, if you were to specify any of the basic characters by its UCS code, it’s possible it will be different from the encoding used by the compiler when the character is specified explicitly with the obvious chaotic result.

Note that it isn’t a requirement that any given compiler must support the use of explicit national language characters in specifying names. If it does, they must be mapped into the UCS form before processing. A compiler that conforms to the standard must in any event support names in the basic character set plus the use of UCS characters in the somewhat unfriendly forms noted at the beginning of this section.

Namespaces

I’m sure that you noticed there was a line in the simple C++ program that I didn’t explain in the preceding discussion. To understand it, you need to know what name-spaces are, and for those to make any sense, I had to first to tell you about names. As a reminder, the line in question was

using namespace std;

Within the rules for identifiers that I discussed in the previous section, you can choose any names that you like for things in your programs. This obviously means that you might choose a name for something that’s already used for some other purpose within the standard library. Equally, if two or more programmers are working concurrently on parts of a larger project, there is potential for name collisions. Clearly, using the same name for two or more different things is bound to cause confusion, and namespaces are there to alleviate this problem.

A namespace name is a bit like a family name or a surname. Each individual within a family has his or her own name, and within most families each family member has a unique name. In the Smith family, for instance, there may be Jack, Jill, Jean, and Jonah, and among family members they’ll refer to each other using these names. However, members of other families may have the same names as members of the Smith family. Within the Jones family, for instance, there might be John, Jean, Jeremiah, and Jonah. When Jeremiah Jones refers to Jean, it’s clear that he means Jean Jones. If he wants to refer to Jean in the Smith family, he’ll use the fully qualified name: Jean Smith. If you’re not a member of either family, you can only be sure that people know whom you’re talking about if you use the full names of individuals, such as Jack Smith or Jonah Jones.

This is pretty much how namespaces work—a namespace name is analogous to a surname. Inside a namespace, you can use the individual names of things within the namespace. From outside the namespace, you can only refer to something within the namespace by a combination of the name of the particular entity and the namespace name. The purpose of a namespace is to provide a mechanism that minimizes the possibility of accidentally duplicating names in various parts of a large program and thereby creating confusion. In general, there may be several different namespaces within a program.

The entities in the C++ standard library are all defined within a namespace called std, so the names of all the entities within the standard libraries are qualified with std. The full name of cout, therefore, is actually std::cout. Those two colons together have a very fancy title: the scope resolution operator. I’ll have more to say about it later on. In this example, it serves to separate the namespace name, std, from the name of the stream, cout.

The using directive at the beginning of the simple C++ program indicates that you want to refer to any of the things defined within the namespace called std without specifying the namespace name each time. Continuing this analogy, it makes your program file a sort of honorary member of the std family, so you can refer to everyone by his or her first name alone. One effect of this is to obviate the need to refer to cout as std::cout, making the program code little simpler. If you were to omit the using directive, you would have to write the output statement as

 std::cout << “The best place to start is at the 
 beginning”;

Of course, although this does make the code look a little more complicated, it’s really a much safer and therefore better way to write the code. The effect of the using directive is to allow you to refer any name in the namespace without qualifying it with the namespace name. This implies that you could do so accidentally. By explicitly qualifying cout with its namespace name, you avoid the need to make all the names in the namespace accessible in your program. This means that there’s no possibility of clashes between names that you choose for things you might define in your program and names that are defined in the namespace.

The program code for this example is therefore somewhat better if you write it as follows:

// Program 1.1 A simple C++ program
#include <iostream>
int main() {
  std::cout << “The best place to start is at the 
beginning”;
  return 0;
}

However, although this is much safer code, if you had a lot more references to std::cout in the code it might begin to look very cluttered. You also have the irritation of repeatedly typing std:: in many places throughout the program. In this case, you can use a form of the using directive that just introduces a single name from a  namespace into your program source file. For instance, you can introduce the name cout from the std namespace into your program file with the following directive:

using std::cout;

With this directive, you can get the best of both worlds. You can use the name cout from the std namespace in its unqualified form, and you protect yourself from accidental conflicts in your code with other names in the std namespace because they’re simply not accessible without using the std qualifier. The program now looks like this:

// Program 1.1A A simple C++ program
#include <iostream>
using std::cout;
int main() {
  cout << “The best place to start is at the beginning”;
  return 0;
}

Of course, you can introduce just some names from the std namespace into your program file by means of a using directive for each name. You might do this for names that you refer to frequently in your code. You can then access other names from std that you refer to relatively rarely by their fully qualified names.

There’s much more to namespaces and using directives than you’ve seen here. You’ll explore them in depth in Chapter 10.

Keywords

There are reserved words in C++, called keywords, that have special significance within the language. The words return and namespace that you saw earlier are examples of keywords.

You’ll see many more keywords as you progress through the book. You must ensure that the names that you choose for entities in your program aren’t the same as any of the keywords in C++. You’ll find a list of all the keywords that are used in C++ in Appendix B.


NOTE
Keywords are case sensitive, as are the identifiers that you choose in your program.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=C++ Statements and Statement Blocks}

Statements are the basic units for specifying what your program is to do and the data elements it acts upon. Most C++ statements end with a semicolon (;). There are quite a few different sorts of statements, but perhaps the most fundamental is a statement that introduces a name into your program source file.

A statement that introduces a name into a source file is called a declaration. A declaration just introduces the name and specifies what kind of thing the name refers to, as opposed to a definition, which results in allocation of some memory to accommodate whatever the name refers to. As it happens, most declarations are also definitions.

A variable is a place in memory in which you can store an item of data. Here’s an example of a statement that declares a name for a variable, and defines and initializes the variable itself:

double result = 0.0;

This statement declares the name result will be used to refer to a variable of type double (declaration), causes memory to be allocated to accommodate the variable (definition), and sets its initial value to 0.0 (initialization).

Here’s an example of another kind of statement called a selection statement:

if (length > 25)
  boxLength = size + 2;

This statement tests the condition “Is the value of length greater than 25?” and then executes the statement on the second line if that condition is true. The statement on the second line adds 2 to the value stored in the variable size and stores the result in the variable boxLength. If the condition tested isn’t true, then the second line won’t be executed, and the program will continue on its merry way by executing whatever comes next in the program.

You can enclose several statements between a pair of curly braces, { }, in which case they’re referred to as a statement block. The body of a function is an example of a block, as you saw in the first example program where the statements in the body of the main() function appear between curly braces. A statement block is also referred to as a compound statement, because in many circumstances it can be considered as a single statement, as you’ll see when we look at C++’s decision-making capabilities in Chapter 4. In fact, wherever you can put a single statement in C++, you can equally well put a block of statements between braces. As a consequence, blocks can be placed inside other blocks—this concept is called nesting.In fact, blocks can be nested, one within another, to any depth you need.

A statement block also has important effects on the variables that you use to store data items, but I defer discussion of this until Chapter 3, where I cover variable scope.

Code Presentation Style

The way in which you arrange your code visually can have a significant effect on how easy it is to understand. There are two basic aspects to this. First, you can use tabs and/or spaces to indent program statements in a manner that provides visual cues to their logic, and you can arrange matching braces that define program blocks in a consistent way so that the relationships between the blocks are apparent. Second, you can spread a single statement over two or more lines when that will improve the readability of your program. A particular convention for arranging matching braces and indenting statements is a presentation style.

There are a number of different presentation styles in use. The following code shows three examples of how the same code might look in three commonly used styles:

namespace mine { namespace mine namespace mine {
int test() { int test()
{ int test() {
if(isGood) { { if(isGood) {
good(); if(isGood) good();
return 0; good(); return 0;
} else return 0; } else
return 1; } else return 1;
} return 1; }
} } }
}

In this book I have used the style shown on the right for all the examples. I chose this because I think it is clear without being too extravagant on space. It doesn’t matter much which style you use as long as you are consistent.

Program Structure

Each of your C++ programs will consist of one or more files. By convention, there are two kinds of file that you can use to hold your source code: header files and source files. You use header files to contain code that describes the data types that your program needs, as well as some other sorts of declarations. These files are referred to as header files because you usually include them at the beginning (the “head”) of your other source files. Your header files are usually distinguished by having the filename extension .h, although this is not mandatory, and other extensions, such as .hxx, are used to identify header files in some systems.

Your source files, which have the filename extension .cpp, contain function defintions—the executable code for your program. These will usually refer to declarations or definitions for data types that you have defined in your own header files. The compiler will need to know about these when it compiles your code so you specify the .h files that are needed in a .cpp file by means of #include directives at the beginning of the file. An #include directive is an instruction to the compiler to insert the contents of a particular header file into your code. You’ll also need to add #include directives for any standard library header files that your code requires.

Figure 1-3 shows a program in which the source code is contained in two .cpp files and three header files. The first .cpp file uses the information from the first two header files, and the second .cpp file requires the contents of the last two header files. You’ll learn more about the #include directives that do this in Chapter 10.


Figure 1-3.  Source files in a C++ program

A number of standard headers are supplied with your compiler and contain declarations that you need in order to use the standard library facilities. They include, for example, declarations for the available standard library functions. The first .cpp file in Figure 1-3 includes the <iostream> header, which you met in the example C++ program. As you may have noticed, in this instance the name for the header has no extension. In fact, to distinguish them from other header files that you may use, the standard header names for C++ have no extension. The standard headers are often referred to as standard header files because that’s how they’re usually implemented. However, the C++ standard doesn’t require that the headers be files, so they may not be in some implementations.


NOTE  Appendix C provides details on the ANSI/ISO standard library headers.

Your compiler system may have a whole range of other header files, providing the definitions necessary to use operating system functions, or other goodies to save you programming effort. This example shows just a few header files in use, but in most serious C++ applications many more will be involved.

Program Functions and Execution

As already noted, a C++ program consists of at least one function that will be called main(), but typically a program consists of many other functions—some that you will have written and others from the standard library. Your program functions will be stored in a number of source files that will typically have filenames with the extension .cpp, although other extensions such as .cxx and .cc are common.

Figure 1-4 shows an example of the sequence of execution in a program that consists of several functions. Execution of main() starts when it’s invoked by the operating system. All the other functions in your program are invoked by main() or by some other function in the set. You invoke a function by calling it. When you call a function, you can pass items of data to it for use while it’s executing. The data items that you want to pass to a function are placed between parentheses following the function name in the call operation. When a function finishes executing, execution control returns to the point at which it was called in the calling function.


Figure 1-4.  How program functions execute

A function can also return a value to the calling point when it finishes executing. The value returned can be stored for use later or it can participate in a calculation of some kind—in an arithmetic expression, for example. You’ll have to wait until Chapter 8 to learn how you can create your own functions, but you’ll use functions from the standard library early in the next chapter.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=Creating an Executable from Your Source Files}

Creating a program module that you can execute from your C++ source code is essentially a two-step process. In the first step, your compiler converts each .cpp file to an object file that contains the machine code equivalent of the source file contents. In the second step, the linker combines the object files produced by the compiler into a file containing the complete executable program.

Figure 1-5 shows three source files being compiled to produce three corresponding object files. The filename extension that’s used to identify object files varies between different machine environments, so it isn’t shown here. The source files that make up your program may be compiled independently in separate compiler runs, or most compilers will allow you to compile them in a single run. Either way, the compiler treats each source file as a separate entity and produces one object file for each .cpp file. The link step then combines the object files for a program, along with any library functions that are necessary, into a single executable file.


Figure 1-5.  The compile and link process

In practice, compilation is an iterative process, as you’re almost certain to have made typographical and other errors in the source code. Once you’ve eliminated these from each source file, you can progress to the link step, where you may find that yet more errors surface! Even when the link step produces an executable module, your program may still contain logical errors; that is, it doesn’t produce the results you expect. To fix these, you must go back and modify the source code and start trying to get it to compile once more. You continue this process until your program works as you think it should. As soon as you declare to the world at large than your program works, someone will discover a number of obvious errors that you should have found. It hasn’t been proven beyond doubt so far as I know, but it’s widely believed that if a program is sufficiently large, it will always contain errors. It’s best not to dwell on this thought when flying.

Let’s take a closer look at what happens during the two basic steps, compiling and linking, because there are some interesting things going on under the covers.

Compiling

The compilation process for a source file has two main stages, as illustrated in Figure 1-6, but the transition between them is automatic. The first stage is the preprocessing phase, which is carried out before the compilation phase proper. The preprocessing phase modifies the contents of the source file according to the preprocessing directives that you have placed in the file. The #include directive, which adds the contents of a header file to a .cpp file, is an example of a preprocessing directive, but there are many others (as you’ll see in Chapter 10).


Figure 1-6.  Details of the compilation process

This facility for modifying the source file before it is compiled provides you with a lot of flexibility in accommodating the constraints of different computers and operating system environments. The code you need in one environment may be different from that required for another because of variations in the available hardware or the operating system. In many situations, you can put the code for several environments in the same file and arrange for the code to be tailored to the current environment during the preprocessor phase.

Although preprocessing is shown in Figure 1-6 as a distinct operation, you don’t execute it independent of the compiler. Invoking the compiler will perform preprocessing automatically, before compiling your code.

Linking

Although the output from the compiler for a given source file is machine code, it’s quite a long way from being executable. For one thing, there will be no connection established between one object file and another. The object file corresponding to a particular source file will contain references to functions or other named items that are defined in other source files, and these will still be unresolved. Similarly, links to library functions will not yet be established; indeed, the code for these functions will not yet be part of the file. Dealing with all these things is the job of the linker (sometimes called the linkage editor).

As Figure 1-7 illustrates, the linker combines the machine code from all of the object files and resolves any cross-references between them. It also integrates the code for any library functions that the object modules use. This is actually a simplified representation of what the linker does, as we’re assuming that all the links between modules are established statically within the executable module. It’s also possible for some links to be dynamic; that is, they’re established only when the program executes.


Figure 1-7.  Details of the linking process

As I said, the linker establishes links to functions statically—that is, before the program executes. This is done for all the functions contained in the source files that make up the program. Functions linked to dynamically—that is, during program execution— are compiled and linked separately to create a different kind of executable module called a dynamic link library (DLL).A link to a function in a DLL is established when the executable module for your program calls the function, and not before.

DLLs present several important advantages. A primary one is that the functions in the DLL can be shared between several programs that are executing concurrently. This saves using up memory with duplicates of the same function when more than one program is executing that requires the services provided by the functions in the DLL. Another advantage is that the DLL won’t be loaded into memory until one of the functions it contains is called. This implies that if you don’t use a function from a given DLL, it won’t occupy space in memory. DLLs are a system capability that ties in closely with your operating system, so I don’t discuss them further in this book.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=C++ Source Characters}

You write C++ statements using a basic source character set. This is simply the set of characters that you’re allowed to use explicitly in a C++ source file. Obviously, the character set that you can use to define a name is going to be a subset of this. Of course, the basic source character set in no way constrains the character data that you work with in your code. Your program can create strings consisting of characters outside this set in various ways, as you’ll see. The basic source character set consists of the following characters:

  • The letters a to z and A to Z

  • The digits 0 to 9

  • The control characters representing horizontal tab, vertical tab, form-feed, and newline

  • The characters _ {}[]#()<>%:;.?*+-/^&|~!=,”‘

This is easy and straightforward. You have 96 characters that you can use, and it’s likely that these will accommodate your needs most of the time.

This definition of the characters that you can use in C++ does not say how the characters are encoded. Your particular compiler will determine how the characters that you use to write your C++ source code are represented in the computer. On a PC, these characters will typically be represented in the machine by an American Standard Code for Information Interchange (ASCII) code such as ISO Latin-1, but other ways of encoding characters may be used.

Most of the time the basic source character set will be adequate, but occasionally you’ll need characters that aren’t included in the basic set. You saw earlier that you can include UCS characters in a name. You can also include UCS characters in other parts of your program, such as when you specify character data. In the next section I elaborate a little on what UCS is all about.

The Universal Character Set

UCS is specified by the standard ISO/IEC 10646, and it defines codes for characters used in all the national languages that are current and many more besides. The ISO/IEC 10646 standard defines several character-encoding forms. The simplest is UCS-2, which represents characters as 16-bit codes, so it can accommodate 65,536 different character codes that can be written as four hexadecimal digits, dddd. This encoding is described as the basic multilingual plane because it accommodates all of the languages in current use, and the likelihood of you ever wanting more than this is remote. UCS-4 is another encoding within the ISO/IEC 10646 standard that represents characters as 32-bit codes that you can express as eight hexadecimal digits, dddddddd. With more than 4 billion different codes, UCS-4 provides the capacity for accommodating all the character sets that you might ever need.

This isn’t all there is to UCS, though. For example, there’s another 16-bit encoding called UTF-16 (UTF stands for Unicode Transformation Format) that is different from UCS-2 in that it accommodates more than 65,535 characters by encoding characters outside of the first 65,536 by what are referred to as surrogate pairs of 16-bit code values. There are other character encodings with UCS too. Generally, a given character will have a code with the same value in any UCS encoding that you choose. The values of codes in US_ASCII are the same as those in UCS character encodings.

Regardless of whether a compiler supports an extended character set for writing source statements, you can include characters from the UCS in your source code by specifying them in the form of a hexadecimal representation of their codes, either as udddd or Udddddddd, where d is a hexadecimal digit. Note the lowercase u in the first case and the uppercase U in the second. However, you must not specify any of the characters in the basic source character set in this way. This is because the codes for these characters will be determined by the compiler, and they may not be consistent with the UCS codes.

If your compiler supports an extended character set with characters outside the base source character set, you’ll be able to use these characters in your source code and the compiler will translate the characters to the internal representation before compilation begins.


NOTE  The character codes defined by the UCS standard are identical to codes defined by Unicode, so Unicode is essentially UCS by another name. If you are keen to explore the delights of UCS and Unicode in detail, http://www.unicode.org is a good place to start.

Trigraph Sequences

You’re unlikely to see this in use very often—if ever—but the C++ standard allows you to specify certain characters as trigraph sequences. A trigraph sequence is a sequence of three characters that’s used to identify another character. This was necessary way back in the dark ages of computing to accommodate characters that were missing from some keyboards. Table 1-1 shows the characters that may be specified in this way in C++.

Table 1-1. Trigraph Sequence Characters

Character Trigraph Sequence
# ??=
[ ??(
] ??)
??/
{ ??<
} ??>
^ ??’
| ??!
~ ??

The compiler will replace all trigraph sequences with their equivalent characters before any other processing of the source code.

Escape Sequences

When you want to use character constants in a program, certain characters can be problematic. A character constant is a data item that your program will use in some way, and it can be either a single character or a character string such as the one in the earlier simple example. Obviously, you can’t enter characters such as newline or tab directly as character constants, as they’ll just do what they’re supposed to do: go to a new line or tab to the next tab position in your source code file. What you want in a character constant is the appropriate code for the character.

You can enter control characters as constants by means of an escape sequence. An escape sequence is an indirect way of specifying a character, and it always begins with a backslash (). Table 1-2 shows the escape sequences that represent control characters.

Table 1-2. Escape Sequences That Represent Control Characters

Escape Sequence Control Character
n Newline
t Horizontal tab
v Vertical tab
b Backspace
r Carriage return
f Form feed
a Alert/bell


There are some other characters that are a problem to represent directly. Clearly, the backslash character itself is difficult, because it signals the start of an escape sequence, and there are others with special significance too. Table 1-3 shows the “problem” characters you can specify with an escape sequence.

Table 1-3. Escape Sequences That Represent “Problem” Characters

Escape Sequence “Problem” Character
\ Backslash
Single quote
Double quote
? Question mark


Because the backslash signals the start of an escape sequence, the only way to enter a backslash as a character constant is by using two successive backslashes (\).

Escape sequences also provide a general way of representing characters such as those in languages other than the one your keyboard supports, because you can use a hexadecimal (base 16) or octal (base 8) number after the backslash to specify the code for a character. Because you’re using a numeric code, you can specify any character in this way. In C++, hexadecimal numbers start with x or X, so x99A and XE3 are examples of escape sequences in this format.

You can also specify a character by using up to three octal digits after the backslash—165, for example. The absence of x or X determines that the code will be interpreted as an octal number.


Try It Out: Using Escape Sequences

You can produce an example of a program that uses escape sequences to specify a message to be displayed on the screen. To see the results, you’ll need to enter, compile, link, and execute the following program.

As I explained in the Introduction, exactly how you perform these steps will depend on your compiler, and you’ll need to consult your compiler’s documentation for more information. If you look up “edit”, “compile”, and “link” (and, with some compilers, “build”), you should be able to find out what you need to do.

// Program 1.2 Using escape sequences
#include <iostream>
using std::cout;
int main() {
  cout << “n”Least saidnttsoonest mended.”na”;
  return 0;
}

When you do manage to compile, link, and run this program, you should see the following output displayed:

============================================================
“Least said
                soonest mended.”
============================================================

You should also hear a beep or some equivalent noise from whatever sound output facility your computer has.

HOW IT WORKS

The output you get is determined by what’s between the outermost double quotes in the statement

 cout << “n”Least saidnttsoonest mended.”na”;

In principle, everything between the outer double quotes in the preceding statement gets sent to cout.A string of characters between a pair of double quotes is called a string literal. The double quote characters just identify the beginning and end of the string literal; they aren’t part of the string. I said “in principle” because any escape sequence in the string literal would have been converted by the compiler to the character it represents, so the character will be sent to cout, not the escape sequence itself. A backslash in a string literal always indicates the start of an escape sequence, so the first character that’s sent to cout is a newline character. This positions the screen cursor at the beginning of the next line.

The next character in the string is specified by another escape sequence,, so a double quote will be sent to cout and displayed on the screen, followed by the characters Least said. Next is another newline character corresponding to n, so the cursor will move to the beginning of the next line. You then send two tab characters to cout with tt, so the cursor will be moved two tab positions to the right. The characters soonest mended. will then be displayed from that point on, followed by another double quote from the escape sequence “. Lastly, you have another newline character, which will move the cursor to the start of the next line, followed by the character equivalent of the a escape sequence that will cause the beep to sound.

The double quote characters that are interior to the string aren’t interpreted as marking the end of the string literal because each of them is preceded by a backslash and is therefore recognized as an escape sequence. If you didn’t have the escape sequence,, available, you would have no way of outputting a double quote because it would otherwise be interpreted as indicating the end of the string.

The name endl is defined in the <iostream> header, and its effect when you use it in an output statement is to write a single newline character so you can use endl instead of n. n and endl aren’t exactly equivalent, though, because using endl will result in the output buffer being flushed so any characters still in memory will be written to the output device. This won’t be the case with n. Obviously, you can’t include endl in a string literal because it would be interpreted as simply four letters, e, n, d, and l.


CAUTION  Be aware that the final character of endl is the letter l, not the number 1.It can sometimes be difficult to tell the two apart.

Using endl, the statement in the preceding code to output the string could be written as follows:

cout << endl
     << “”Least said”
     << endl
     << “ttsoonest mended.”a”
     << endl;

This statement sends five separate things in sequence to cout: endl, “”Least said”, endl, “ttsoonest mended.”a”, and endl. This will produce exactly the same output as the original statement. Of course, for this statement to compile as written, you would need to add another using directive at the beginning of the program:

using std::endl;

You don’t have to choose between using either endl or the escape sequence for newline. They aren’t mutually exclusive, so you can mix them to suit yourself. For example, you could produce the same result as the original again with this statement:

cout << endl
      << “”Least saidnttsoonest mended.”a”
      << endl;

Here you’ve just used endl for the first and last newline characters. The one in the middle is still produced by an escape sequence. Of course, each instance of endl in the output will result in the output buffer being flushed after writing a newline character to the stream.


This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=Whitespace in Statements}

As you learned earlier, whitespace is the term used in C++ to describe spaces, horizontal and vertical tabs, newline, and form-feed characters. In many instances, whitespace separates one part of a statement from another and enables the compiler to identify where one element in a statement ends and the next element begins. For example, look at the following line of code:

int fruit;

This statement involves int, which is a type name, and fruit, which is the name of a variable. There must be at least one whitespace character (usually a space) between int and fruit for the compiler to be able to distinguish them. This is because intfruit would be a perfectly acceptable name for a variable or indeed anything else, and the compiler would interpret it as such.

On the other hand, consider this statement:

fruit = apples + oranges;

No whitespace characters are necessary between fruit and =, or between = and apples, although you’re free to include some if you wish. This is because the equals sign (=) isn’t alphabetic or numeric, so the compiler can separate it from its surroundings. Similarly, no whitespace characters are necessary on either side of the plus sign (+). In fact, you’re free to include as little or as much whitespace as you like, so you could write the previous statement as follows:

fruit
=
apples
+
oranges;

If you do this, it’s unlikely you’ll be congratulated for good programming style, but the compiler won’t mind.

Apart from its use as a separator between elements in a statement, or when it appears in a string between quotes, the compiler ignores whitespace. You can, therefore, include as much whitespace as you like to make your program more readable. In some programming languages, the end of a statement is at the end of the line, but in C++ the end of a statement is wherever the semicolon occurs. This enables you to spread a statement over several lines if you wish, so you can write a statement like this:

std::cout << std::endl << “”Least said” << std::endl
                              << “ttsoonest mended.”a” << std::endl;

or like this:

std::cout << std::endl
          << “”Least said”
          << std::endl
          << “ttsoonest mended.”a”
          << std::endl;

Documenting Your Programs

Documenting your program code is extremely important. Code that seems crystal clear when you write it can look extraordinarily obscure when you’ve been away from it for a month. You can document your code using comments, of which there are two sorts in C++: single-line comments and multiline comments (that is, comments that can span several lines).

You begin a single-line comment with a double slash (//), for example

// Program to forecast stock market prices

The compiler will ignore everything on the line following the double slash, but that doesn’t mean the comment has to fill the whole line. You can use this style of comment to explain a statement:

length = shrink(length, temperature);    // Compensate for wash shrinkage

You can also temporarily remove a line of code from your program just by adding a double slash to the beginning of the line:

// length = shrink(length, temperature);  // Compensate for wash shrinkage

This converts the statement to a comment, which is something you might want to do during the testing of a program, for example. Everything from the first // in a line to the end of the line is ignored, including any further occurrences of //.

The multiline comment is sometimes used for writing more verbose, general descriptive material—explaining the algorithm used within a function, for example. Such a comment begins with /*, ends with */, and everything between these two is ignored. This enables you to embellish multiline comments to highlight them, for example

/***************************************************
* This function predicts future stock prices     *
* using advanced tea leaf simulation techniques. * ***************************************************/

You can also use this comment style for temporarily disabling a block of code. Just put /* at the beginning of the block and */ at the end. However, you must take particular care not to nest /* … */ comments; you’ll cause error messages from your compiler if you do. This is because the closing */ of the inner nested comment will match the opening /* of the outer comment:

// You must not nest multiline comments
/* This starts an outer comment
/* This is an inner comment, but the start will not be recognized
   because of the outer comment.
   Instead, the end of the inner comment will be interpreted as the end
   of the outer comment. */
   This will cause the compiler to try to compile this part of the
   outer comment as C++ code. */

The last part of the outer comment is left “dangling,” and the compiler will try to compile it, which will inevitably result in failure. For this reason, the // form of comment is the most widely used in C++ programs.


NOTE  You may also hear multiline comments being described as “C-style” comments. This is because the /* */ syntax is the only one available for creating comments in the C language.

The Standard Library

The standard library contains a substantial number of functions and other things that support, augment, and extend the basic language capabilities of C++. The contents of the standard library are just as much a part of C++ as the syntax and semantics of the language itself. The standard for C++ defines both, and so every compiler that conforms to the standard will supply the complete standard library.

Bearing this in mind, the scope of the standard library is extraordinary. You get a vast range of capability, from essential elements such as basic language support, input and output functions, and exception handling (an exception is an unusual occurrence during program execution—often an error of some kind) to utility functions, mathematical routines, and a wide range of prewritten and tested facilities that you can use to store and manage data during execution of your program.

To use C++ most effectively, you should make sure that you have a good familiarity with the contents of the standard library. You’ll be introduced to many of the capabilities of the standard library as you learn the C++ language in this book, but the degree of coverage within the book will inevitably be incomplete. It would take another book comparable with the size of this one to cover the capability and use of the standard library comprehensively.

The definitions and declarations necessary to use standard library facilities appear in the standard headers touched upon earlier. There are a few cases in which the standard headers will be included in your program files by default, but in most instances you must add an #include directive for the appropriate header for the library facilities that you want to use. You’ll find a comprehensive list of the standard headers in Appendix C, with a brief description of what sort of functionality each one supports.

Almost everything in the C++ standard library is defined within the namespace std. This means that all the names that you’ll use from the library are prefixed with std. As you saw at the beginning of the chapter, when you reference something from the standard library, you can prefix the name with std, as in the following statement:

 std::cout << “The best place to start is at the beginning”;

Alternatively, you can put a using directive at the beginning of your source file:

 using std::cout;

This allows you to use the name cout without its std prefix so you can write that statement as follows:

 cout << “The best place to start is at the beginning”;

You also saw earlier that you have a blanket capability for introducing names from the std namespace into a program file:

 using namespace std;

This allows you to omit the std prefix for any standard library names that are defined in the headers you’ve included in your program. However, it has the serious disadvantage that it allows potential clashes between names you’ve defined and identical names in the standard library headers that you’ve included.

In this book I always include the std namespace prefix where necessary in code fragments. In complete working programs, you’ll generally add using statements for standard library names that you use repeatedly in code. Names that you use once or twice you’ll just qualify with the namespace name.

Programming in C++

Because C++ inherits and enhances the power and flexibility of the original C language, you have a comprehensive capability for handling time-critical, low-level programming tasks and for dealing with problems for which a traditional procedural approach may be preferable. The major strengths of C++, though, are its powerful and extensive object-oriented features. These provide the potential for writing programs that are less error-prone, less time-consuming to maintain, simpler to extend, and easier to understand than their equivalent procedural solutions.

There are fundamental differences between these two programming methodologies, so let’s contrast them to highlight just how they’re different and see some of the reasons why an object-oriented approach can be so attractive.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

{mospagebreak title=Procedural and Object-Oriented Programming}

Historically, procedural programming is the way almost all programs have been written. To create a procedural programming solution to a problem, you focus on the process that your program must implement to solve the problem. A rough outline of what you do, once the requirements have been defined precisely, is as follows:

  • You create a clear, high-level definition of the overall process that your program will implement.

  • You segment the overall process into workable units of computation that are, as much as possible, self-contained. These will usually correspond to functions.

  • You break down the logic and the work that each unit of computation is to do into a detailed sequence of actions. This is likely to be down to a level corresponding to programming language statements.

  • You code the functions in terms of processing basic types of data: numerical data, single characters, and character strings.

Apart from the common requirement of starting out with a clear specification of what the problem is, the object-oriented approach to solving the same problem is quite different:

  • From the problem specification, you determine what types of objects the problem is concerned with. For example, if your program deals with baseball players, you’re likely to identify BaseballPlayer as one of the types of data your program will work with. If your program is an accounting package, you may well want to define objects of type Account and type Transaction. You also identify the set of operations that the program will need to carry out on each type of object. This will result in a set of application-specific data types that you will use in writing your program.

  • You produce a detailed design for each of the new data types that your problem requires, including the operations that can be carried out with each object type.

  • You express the logic of the program in terms of the new data types you’ve defined and the kinds of operations they allow.

The program code for an object-oriented solution to a problem will be completely unlike that for a procedural solution and almost certainly easier to understand. It will certainly be a lot easier to maintain. The amount of design time required for an object-oriented solution tends to be greater than for a procedural solution. However, the coding and testing phase of an object-oriented program tends to be shorter and less troublesome, so the overall development time is likely to be roughly the same in either case.

Let’s try to get an inkling of what an objected-oriented approach implies. Suppose that you’re implementing a program that deals with boxes of various kinds. A feasible requirement of such a program would be to package several smaller boxes inside another, larger box. In a procedural program, you would need to store the length, width, and height of each box in a separate group of variables. The dimensions of a new box that could contain several other boxes would need to be calculated explicitly in terms of the dimensions of each of the contained boxes, according to whatever rules you had defined for packaging a set of boxes.

An object-oriented solution might involve first defining a Box data type. This would enable you to create variables that can reference objects of type Box and, of course, create Box objects. You could then define an operation that would add two Box objects together and produce a new Box object that could contain the first two. Using this operation, you could write statements like this:

bigBox = box1 + box2 + box3;

In this context the + operation means much more than simple addition. The + operator applied to numerical values will work exactly as before, but for Box objects it has a special meaning. Each of the variables in this statement is of type Box. The preceding statement would create a new Box object big enough to contain box1, as well as box2 and box3.

Being able to write statements like this is clearly much easier than having to deal with all the box dimensions separately, and the more complex the operations on boxes you take on, the greater the advantage is going to be. This is a trivial illustration, though, and there’s a great deal more to the power of objects than that you can see here. The purpose of this discussion is just to give you an idea of how readily problems solved using an object-oriented approach can be understood. Object-oriented programming is essentially about solving problems in terms of the entities to which the problems relates rather than in terms of the entities that computers are happy with— numbers and characters. You’ll explore object-oriented programming in C++ fully starting in Chapter 11.

Summary

This chapter’s content has been broad-brush to give you a feel for some of the general concepts of C++. You’ll encounter everything discussed in this chapter again, and in much more detail, in subsequent chapters. However, some of the basics that this chapter covered are as follows:

  • A program in C++ consists of at least one function, which is called main().

  • The executable part of a function is made up of statements contained between a pair of braces.

  • A pair of curly braces is used to enclose a statement block.

  • In C++, a statement is terminated by a semicolon.

  • Keywords are a set of reserved words that have specific meanings in C++. No entity in your program can have a name that coincides with any of the keywords in the language.

  • A C++ program will be contained in one or more files.

  • The code defining functions is usually stored in files with the extension .cpp.

  • The code that defines your own data types is usually kept in header files with the extension .h.

  • The C++ standard library provides an extensive range of capabilities that supports and extends the C++ language.

  • Input and output in C++ are performed using streams and involve the use of the insertion and extraction operators, << and >>.

  • Object-oriented programming involves defining new data types specific to your problem. Once you’ve defined the data types that you need, a program can be written in terms of the new data types.

Exercises

The following exercises enable you to try out what you’ve learned in this chapter. If you get stuck, look back over the chapter for help. If you’re still stuck after that, you can download the solutions from the Apress website (http://www.apress.com/book/ download.html), but that really should be a last resort.

Exercise 1-1. Create a program that will display the text “Hello World” on your screen.

Exercise 1-2. Change your program so that it uses the hexadecimal values of the characters to spell out the phrase. If you’re working on a computer that uses ASCII to encode its characters, you’ll find a table of the values you need in Appendix A. (Hint: When you’re using hexadecimal ASCII values, “He” can be displayed by the statement std::cout << “x48x65″;.)

Exercise 1-3. The following program produces several compiler errors. Find these errors and correct them so the program can compile cleanly and run.

 #include <iostream>>
 using namespace std;
 int main() {
  cout << endl
       << “Hello World”
       << endl
 return0;
)

Exercise 1-4. What will happen if you remove the using directive from the program in Exercise 1-3? Apart from restoring the using directive, how else could you fix the problem that occurs? Why is your solution better that restoring the original using directive?


NOTE 
You’ll find model answers to all exercises in this book in the Downloads section of the Apress website at http://www.apress.com/book/download.html.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

Google+ Comments

Google+ Comments