Appendix 1, Section 1
C++ Programming Fundamentals
WHEN I DECIDED TO TEACH COMPUTER SCIENCE 124 with Java rather than C++, it was with the knowledge that most students would still have to learn C++ eventually. This is because C++ is still the major programming language for professional programmers. In addition, it has a number of language features that Java lacks and that computer science students should be familiar with. However, it was my feeling that Java would be a superior language for an introductory course, and that in any case much of what could be covered in an introductory Java programming course would also apply to C++. After two years of teaching Java and teaching C++ to students who had studied Java as their first programming language, I think I can say that my experience has confirmed or even exceeded expectations. I might even go so far as to advise someone whose only goal is to learn C++ to start with Java.
Before beginning, I should note that recently, after eight years of work, a new standard version of C++ has been released. This new version makes several important changes to the language. It also adds a large, standard collection of classes called the Standard Template Library. In this chapter, I am talking about the older version of C++. For example, I say below that C++ has no standard String class. However, in the new version, the Standard Template Library does provide such a class. (Of course, until everyone actually makes the switch to the new version, the C++ String class is still not really standardized.)
But before discussing C++, let me mention some of the things that it does not have (even in the new version). First of all, there is no platform-independent GUI support in C++. A typical first course in C++ might not even mention windows, graphics, or events. In addition, standard C++ does not have built-in support for threads or asynchronous programming. Nor does it have a standard interface for network programming. Of course, classes can be written to provide these features in C++. But since they are not standardized, such classes tend to be platform-dependent so that what you learn about one type of computer doesn't automatically apply to other computers. They also tend to be more complicated than the versions available in Java. By using Java, I was able to include these important features of modern computing environments in a natural way.
But enough propaganda about Java. The rest of this chapter is a very brief overview of C++.
The first thing to know about C++ is that you can write entire, complicated programs without ever using classes or objects. Whereas in Java everything, even a program's main() routine, must be contained inside classes, C++ allows free-standing subroutines and variable declarations. The main() routine, in particular, cannot be a member of a class.
C++ variables and subroutines that are defined outside classes are similar to static variables and subroutines in Java. For example, they exist for the whole time that the program is running. In C++, such variables and routines are said to be global or to have global scope. They can be used "globally" inside any subroutine and even in methods that belong to classes.
However, no variable, class, or subroutine can be use in a C++ program unless it has been declared earlier in the same file. (This is different from Java, which allows you to use a variable or subroutine that is not declared until later in the program; of course, Java even allows you to use classes that are defined in other files, and it will go off and search for them when necessary.) This might seem to require the entire program to be in one big file, with the main() routine at the end, but that is not the case. To avoid this, C++ uses header files. A header file contains declarations of variables, subroutines, and classes that are actually defined in other files. C++ distinguishes carefully between declarations and definitions. The declaration of a subroutine, for example, gives only its name, its return type, and its parameter list. The definition of a subroutine also includes the code that defines the routine. A subroutine or variable must be declared before it is used in a source code file, but its definition can come later or even in another file. A header file contains only the declaration, which gives enough information to the compiler for it to check whether the subroutine or variable is being used legally.
There are many standard header files that declare useful subroutines and classes. For example, the header file math.h defines mathematical functions such as sin(x) and sqrt(x). (By convention, the name of a header file ends with ".h".) Another standard header file, iostream.h, defines stream classes that can be used for doing input and output. To get access to the declarations in a header file, a program must include the header file. This is done with a #include statement at the beginning of the program. For example, a program that starts with the statements#include <math.h> #include <iostream.h>
will be able to use the mathematical functions and the stream classes. The #include statement is very similar to the import statement in Java. For example, saying #include <iostream.h< in C++ is similar to saying import java.io.* in Java. It's often a chore just determining which header files your program needs.
When you write a large program in C++ and you want to break it up into several pieces, you will generally have to write two files for each piece: one file that actually defines some subroutines and classes, plus a header file that declares the same subroutines and classes. Other files that need access to those subroutines and classes must #include the header file to get access to them.
Types and Variables
C++ has standard types named short, int, long, float, double, and char that are similar to Java's primitive types with the same name. In C++, however, the exact meaning of these types is not completely standardized. I can't tell you the range of legal values for ints, for example, because the legal range is different on different systems. There is no standard byte data type, but char really plays the same role, since a char in C++ is considered to be simply an 8-bit integer.
C++ does not really have a standard String type that is equivalent to the String type in Java. C++ does have some support for strings, but they are more difficult to use and they require a knowledge of pointers and arrays. I'll discuss them in the next section. It is possible to write a String class in C++ that is very similar to Java's class, and most C++ programmers would probably have access to such a class by #including a String.h header file. However, you can't depend on this since it's not a standard part of the language.
Most versions of C++ (including the new standard) use bool as the name of the boolean type, and the names true and false are used for the values of type bool. However, in C++, true and false are names for the integers 1 and 0. In fact, an integer can be used wherever a bool value is expected, such as in an if statement. Any non-zero integer is considered to be true, while zero is false. So, to test whether the integer N is non-zero, you could say "if (N)..."
I should note that there is a lot more to say about types in C++, since C++ has several different ways to define new types. Like Java, C++ has class types and array types. But it also has things called pointer types, structs, enumerated types, and function types. The later three types of types, I won't even mention again.
Variables are declared and initialized in C++ in much the same way as in Java. C++ has global variables (declared outside subroutines and classes), instance variables in classes (both static and non-static), and local variables (declared inside subroutines or methods). As in Java, local variables can be declared at any point in a routine, and are valid only for the block in which they are declared. One big difference is that in C++, a variable can actually contain an object, whereas in Java, a variable can only contain a reference to an object. I'll discuss this further in Section 3.
Control Structures, Assignment Statements, and Expressions
Fortunately, there is very little to say about control structures in C++. Except for a few minor details that you will probably never encounter in practice, they are the same as in Java. That is, C++ has if statements, for statements, while loops, do loops, and switch statements that work the same way as their counterparts in Java. Also, you can use break statements and continue statements in C++, just as in Java.
The same goes for assignment statements and expressions. All the operators are the same: +, -, *, /, %, ++, &&, ||, =, +=, and so on. One difference, already noted above, is that the mathematical functions are not contained in a Math class. Thus, instead of saying y = Math.sqrt(x), you would say simply y = sqrt(x) (On the other hand, if you want to use the sqrt() function in C++, you have to #include the header file math.h at the beginning of your program. Whereas the Math class is automatically imported into every Java program, the math.h header file is not automatically included in a C++ program.)
Input and Output
Like Java, C++ has a standard input stream and a standard output stream for doing console input/output. The C++ versions are actually much more well-developed than the Java versions, but the syntax for using them is a bit strange. The standard input stream is called cin, and the standard output stream is called cout. (The "c" in these names stands for "console.") To use these streams in a program, you must #include the header file iostream.h.
The syntax for reading a value from the standard input stream into a variable named x is:cin >> x;
(The double-arrow operation is meant to indicate the direction of flow of information.) Output is similar, except that the direction of the arrows is reversed. For example,cout << x;
will output the value of the variable x to the console, andcout << "Hello World!\n";
will output the message "Hello World!". The new line character, '\n', outputs a carriage return at the end of the message. You can string several output items into a single statement, like this:cout << "The square root of " << x << " is " << sqrt(x);
You can do the same thing with cin.
The standard I/O streams are instances of general stream classes called ostream and istream, which are analogous to Java's PrintStream and to my TextInputStream, respectively.
Subroutine definitions look pretty much the same in C++ as in Java, except of course that they are not necessarily found inside classes. The access modifiers public, private, and protected cannot be used outside classes. The static modifier can be used both inside and outside classes, but outside a class, it has a completely different meaning than it does inside a class. (It means that the subroutine is for use only in the file in which it is defined. The word static is grossly overused in C++, with several very different meanings in different contexts.)
Subroutine call statements and function invocations are also just about identical in Java and in C++.
Every program must have exactly one main() subroutine, and just as in Java, the system runs the program by calling its main() routine. The exact form of the main routine is not entirely standardized, and often several forms are acceptable. In some cases, for example, the main routine has return type void, while in other cases, it has return type int. (The int that is returned by the main routine is sent back to the system -- which called that routine -- as a status code to indicate whether the program completed successfully or ended in error.) On a given system, either or both of these formats might be acceptable.
Although exception handling is not really a " programming fundamental," I mention it in this section because it is another area in which Java and C++ are very similar. C++ uses try, catch, and throw in the same way as Java. However, C++ does not allow a finally clause in a try statement, and it does not have the large number of predefined exception classes that Java has. Since exception handling is a recent addition to C++, it is still not completely well-integrated into the language. Many of the standard subroutines, for example, were written before exception handing was introduced, and they use older, alternative ways to deal with errors.
[ Next Section | Appendix Index | Main Index ]