Every discipline has its own specialized terminology that allows practitioners to communicate quickly and effectively. Learning computer science terminology will help you communicate with your colleagues quickly and accurately. I use these terms throughout the textbook, and your instructor may use them in exam questions and programming assignments. If you are comfortable using the terms, you will find it easier to understand subsequent text sections and less frustrating to complete your projects.
Here are a few terms to add to your vocabulary:
C++, like Java, is an imperative programming language. Programs written in imperative languages consist of a sequence of statements; each statement is an instruction that tells the computer to do something. All C++ and Java terminate all statements with a semicolon.
It's possible to place multiple statements on a single line because each statement ends with a semicolon. But, experienced programmers generally place each statement on a line by itself, making the code easier to read. Sometimes, a statement may be too long to fit on a single line (modern text editors support horizontal scrolling, but consider what the code will look like if printed on paper), so it's common practice to break these long statements into multiple lines.
Correct, but not preferred | Best Practice |
---|---|
statement 1; statement 2; statement 3; |
statement 1; statement 2; statement 3; |
The overarching rule is to make the code easy for people to read and understand. In some rare cases, the first example in Figure 1 may improve readability and is preferred. Break long statements at whitespace and indent subsequent lines until the statement ends. It's easier for a reader to read a long statement that spans multiple lines than forcing the reader to scroll the display area.
An expression is a fragment of code that produces a temporary value. The computer must evaluate the expression to obtain the value; that is, the computer carries out the calculations or operations in the code fragment. Expressions are part of larger statements; the computer discards the expression value when the statement ends (i.e., expressions have statement scope). Some examples of expressions:
Most Java textbooks state that a variable must be declared before it can be used. Alternatively, C++ textbooks state that a variable must be defined before using it. So, what's the difference between declaring and defining a variable? In Java, there is no difference (and some Java textbooks will use the term "defined" in place of "declared"), but there is a difference in C++.
A declaration "introduces" a programmer-created name or identifier (called a "symbol" in the language of computer science) to the compiler. The compiler stores the symbol in a temporary data structure called the symbol table. When the symbol is a variable, the compiler also records the variable's data type and where it appears in the program. When the symbol is a function, the compiler records its return type and the number and type of its parameters. The compiler uses the symbol table while translating C++ code to machine code.
The reason that C++ makes a distinction between "declaration" and "definition" and Java does not is due to differences in the compiler implementations. Java compilers use a "two-pass" strategy, meaning the compiler reads each program file twice. The compiler builds the symbol table during the first pass and generates (virtual) machine code during the second pass. In contrast, the C++ compiler uses a "one-pass" strategy - it builds the symbol table and generates machine code in the same pass. The one-pass approach requires that every symbol be defined before the compiler uses it for code generation.When a programmer tries to do something with a symbol, the compiler must "know" what the symbol represents. Some C++ statements serve as both a definition and a declaration, further complicating understanding the distinction between the terms. We'll see some examples of these statements as we explore what it means to "define" something below.
Functions can also be declared, which is important when programs span multiple files. Function declarations, called function prototypes or just prototypes, are explored in more detail in chapter 6.
Index | Symbol | Address | Feature | Type | Arguments |
---|---|---|---|---|---|
0 | Counter | Variable | int | ||
1 | sqrt | Function | double | 2 | |
2 | x | Variable | double | ||
3 | pow | Function | double | 4, 5 | |
4 | x | Variable | double | ||
5 | y | Variable | double |
Unlike declarations, variable and function definitions allocate or set aside memory to hold the data named by the variable or the machine code for a function. If a definition statement is the first time the compiler "sees" the symbol, then the statement serves as both a declaration and a definition. For example:
The following figure illustrates two possible ways to define a sequence of variables: A programmer may define multiple variables of the same data type as a comma-separated list in a single statement or as a sequence of separate statements.
Correct, but not preferred | Best Practice |
---|---|
double x, y, z; |
double x; double y; double z; |
If the programmer knows the initial value of the variable or can calculate it at the time of the variable definition, then the programmer can also initialize the variable in the same statement that defines it:
Index | Symbol | Address | Feature | Type | Arguments |
---|---|---|---|---|---|
0 | Counter | 0x12345678 | Variable | int | |
1 | sqrt | 0xAF56C730 | Function | double | 2 |
2 | x | 0x0C83E0C5 | Variable | double | |
3 | pow | 0x0B31A84D | Function | double | 4, 5 |
4 | x | 0x561AC820 | Variable | double | |
5 | y | 0x873291FE | Variable | double |
We can write small programs in a single file. In this case, there's little need for variable declarations, but even a small program may still require function declarations, as we will see in Chapter 6. It's a common practice to spread large, complex programs over multiple files. If the program defines an element (a variable, function, class, or structure) in one file, a declaration is necessary to use the element in other program files. Even so, variable declarations are rare and only needed when all of the following are true:
Definition / file1.cpp | Declaration / file2.cpp |
---|---|
int counter; // variable defined in global scope |
extern int counter; // variable declaration |
extern
keyword in the using files.
Global variables are error-prone, making program verification and maintenance difficult, and are therefore generally avoided in general practice. Global variables are still occasionally necessary in C programs. In rare cases, they are still necessary for C++ programs but typically not in general C++ applications.
To better understand the purpose of the declaration and the extern
keyword in the example, recall that the compiler component (the second stage in the full compiler system) processes each source code (i.e., .cpp) file one at a time. So, the compiler would "see" the definition of "counter" when it processes file1. However, without the extern
statement, the name "counter" is otherwise unspecified and unknown when the compiler encounters it while processing file2.
The extern
statement creates a pure declaration, which places "counter" in the compiler's symbol table but does not cause it to allocate any memory. Programs may declare a variable any number of times (if the declarations are the same) but must define it exactly once. It is one of the linker's (Figure 4) tasks to connect all of a variables declarations to its one definition. Finally, note that a definition may have an initialization: int counter = 100;
but that a declaration may not.