Imagine that we print out a program on fan-fold paper, the long, continuous paper used by old dot-matrix printers. Further, imagine that we spread the program out on a long table. Find the main function, and place the tip of a marker at the top. Now, mentally run the program while tracing each instruction with the marker as you run it. The marker traces the branches taken by if-statements and coils around the program's loops. We must pick up the marker and move it when we call a function, but we return it to the original trace when the function ends. The trace left in ink on the paper is the flow of control (aka, the nexus of control).
Each kind of statement solves a particular programming problem and adds power and complexity to a program. Nesting one statement inside another amplifies the statements' computational power and complexity. C++ does not limit how deeply we can nest flow control statements, but the logic can become difficult to follow if they are too deeply nested. What constitutes "too deeply" is a function of the program and the problem that the program solves, but a good rule of thumb is to limit nesting to four (or, if the code is otherwise simple, five) levels of branches and loops.
All imperative programming languages build the flow of control statements with keywords and symbols. They often use different words and symbols to represent the same concepts. For example, C, C++, Java, and C# use { and } to delimit a control statement's body. Pascal, Modula II, and Ada use the keywords begin and end for the same purpose. Although not as evident, Python uses indentation to group control statements.
Keywords | Symbols |
---|---|
|
|
The examples presented in Chapter 2 utilized only sequential statements: statements that execute one after the other in a strict top-to-bottom order. Figure 1 graphically illustrates the behavior of sequential statements.
Although sequential statements are important and powerful, only simple programs complete their tasks without branches and loops. However, before we can look at branches and loops, we must first explore two prerequisite concepts: block structure and logical expressions.