Summary

Section 4.1 Introduction

  • Before writing a program to solve a problem, you should have a thorough understanding of the problem and a carefully planned approach to solving it.

Section 4.2 Algorithms

  • A procedure for solving a problem in terms of the actions (p. 105) to execute and the order (p. 105) in which these actions execute is called an algorithm (p. 105).

  • Specifying the order in which statements (actions) execute in a program is called program control (p. 105). This chapter investigates program control using C++’s control statements (p. 105).

Section 4.3 Pseudocode

  • Pseudocode (p. 105) is an informal language similar to everyday English that helps you develop algorithms without having to worry about the strict details of C++ language syntax.

  • Pseudocode helps you “think out” a program before attempting to write it.

  • Pseudocode normally describes only statements representing the actions that occur after you convert a program from pseudocode to C++ and the program is run on a computer.

Section 4.4 Control Structures

  • Normally, statements in a program are executed one after the other in the order in which they’re written—this is called sequential execution (p. 106).

  • Various C++ statements enable you to specify that the next statement to execute is not necessarily the next one in sequence. This is called transfer of control (p. 106).

  • Bohm and Jacopini’s work demonstrated that all programs could be written in terms of only sequence (p. 106), selection (p. 106) and iteration (p. 106).

Section 4.4.1 Sequence Structure

  • The sequence (p. 106) structure is built into C++. Unless directed otherwise, the computer executes C++ statements one after the other in the order in which they’re written.

  • A UML activity diagram (p. 106) models the workflow (p. 107; also called the activity) of a portion of a software system. Such workflows may include a portion of an algorithm.

  • Activity diagrams are composed of symbols, such as action-state symbols (p. 107), diamonds (p. 107) and small circles (p. 107). These are connected by transition arrows (p. 107), which represent the flow of the activity—that is, the order in which the actions should occur.

  • Like pseudocode, activity diagrams help you develop and represent algorithms.

  • An action state (p. 107) contains an action expression (p. 107) that specifies a particular action to perform.

  • Transition arrows in the activity diagram represent transitions (p. 107), specifying the order in which the actions represented by the action states occur.

  • A solid circle (p. 107) at the top of the activity diagram represents the initial state (p. 107)—the beginning of the workflow before the program performs the modeled actions.

  • A solid circle surrounded by a hollow circle (p. 107) at the bottom of the diagram represents the final state—the end of the workflow after the program performs its actions.

  • UML notes (p. 107; like comments in C++) are explanatory remarks that describe the purpose of symbols in the diagram. A dotted line (p. 107) connects each note with the element it describes.

Section 4.4.2 Selection Statements

  • C++ has three types of selection statements (p. 108).

  • The if single-selection statement (p. 108) performs (selects) an action (or group of actions), if a condition is true, or skips it, if the condition is false.

  • The ifelse double-selection statement (p. 108) performs an action (or group of actions) if a condition is true and performs a different action (or group of actions) if the condition is false.

  • The switch multiple-selection statement (p. 108) performs one of many different actions (or group of actions), depending on the value of an expression.

Section 4.4.3 Iteration Statements

  • C++ provides four iteration statements (p. 108; sometimes called repetition statements or looping statements) that enable programs to perform statements repeatedly as long as a loop-continuation condition (p. 108) remains true.

  • The iteration statements are the while, dowhile, for and range-based for statements.

  • The while and for statements perform the action (or group of actions) in their bodies zero or more times—if the loop-continuation condition is initially false, the action (or group of actions) will not execute.

  • The dowhile statement performs its body action(s) one or more times.

  • Each of the words if, else, switch, while, do and for is a C++ keyword. Keywords cannot be used as identifiers, such as variable names, and must be spelled with only lowercase letters.

Section 4.4.4 Summary of Control Statements

  • Every program is formed by combining as many control statements as is appropriate for the algorithm the program implements.

  • Single-entry/single-exit control statements (p. 109) make it easy to build programs by connecting the exit point of one to the entry point of the next. We call this control-statement stacking (p. 109).

  • In control-statement nesting (p. 109), one control statement appears inside another.

Section 4.5 if Single-Selection Statement

  • In C++, a decision can be based on any expression that can be evaluated as zero or nonzero—if the expression evaluates to zero, it’s treated as false; if the expression evaluates to nonzero, it’s treated as true.

  • C++ provides the data type bool (p. 110) for Boolean variables that can hold only the values true (p. 110) and false (p. 110)—each of these is a C++ keyword.

  • The UML decision symbol (p. 110; a diamond) indicates that a decision is to be made. The workflow continues along a path determined by the symbol’s associated guard conditions (p. 110), which can be true or false. Each transition arrow emerging from a decision symbol has a guard condition (specified in square brackets next to the arrow). If a guard condition is true, the workflow enters the action state to which the transition arrow points.

Section 4.6 ifelse Double-Selection Statement

  • The ifelse double-selection statement (p. 110) allows you to specify an action (or group of actions) to perform when the condition is true and another action (or group of actions) when the condition is false.

Section 4.6.1 Nested ifelse Statements

  • A program can test multiple cases by placing ifelse statements inside other ifelse statements to create nested ifelse statements (p. 111).

Section 4.6.2 Dangling-else Problem

  • Enclosing control-statement bodies in braces ({ and }) avoids a logic error called the “dangling-else” problem (Exercises 4.234.25).

Section 4.6.3 Blocks

  • Statements contained in a pair of braces (such as the body of a control statement or function) form a block (p. 113). A block can be placed anywhere in a function that a single statement can be placed.

  • Syntax errors are caught by the compiler.

  • A logic error (p. 113) has its effect at execution time.

  • A fatal logic error (p. 114) causes a program to fail and terminate prematurely.

  • A nonfatal logic error (p. 114) allows a program to continue executing but causes it to produce incorrect results.

  • Just as a block can be placed anywhere a single statement can be placed, it’s also possible to have an empty statement, ; (p. 114), where a statement would normally be.

Section 4.6.4 Conditional Operator (?:)

  • The conditional operator , ?: (p. 114) is C++’s only ternary operator (p. 114). Together, the operands and the ?: symbol form a conditional expression (p. 114).

  • The first operand (to the left of the ?) is a condition, the second operand (between the ? and :) is the value of the conditional expression if the condition is true and the third operand (to the right of the :) is the value of the conditional expression if the condition is false.

Section 4.8 while Iteration Statement

  • A while iteration statement (p. 118) allows you to specify that a program should repeat an action (or group of actions) while some condition remains true.

  • UML’s merge symbol (p. 118; a diamond) joins two flows of activity into one.

  • A decision symbol has one transition arrow pointing to the diamond and two or more pointing out from it to indicate possible transitions from that point. In addition, each transition arrow pointing out of a decision symbol has a guard condition next to it.

  • A merge symbol has two or more transition arrows pointing to the diamond and only one pointing from the diamond, to indicate multiple activity flows merging to continue the activity. None of the transition arrows associated with a merge symbol has a guard condition.

Section 4.9.1 Pseudocode Algorithm with Counter-Controlled Iteration

  • Counter-controlled iteration (p. 119) uses a variable called a counter (p. 119; or control variable) to control the number of times a set of statements will execute. This is often called definite iteration (p. 119), because the number of iterations is known before the loop begins executing.

Section 4.9.2 Implementing Counter-Controlled Iteration

  • An unsigned int variable can assume only nonnegative values. Variables of unsigned integer types can represent values from 0 to approximately twice the positive range of the corresponding signed integer types.

  • You can determine your platform’s maximum unsigned int value with the constant UINT_MAX from <climits>.

  • A variable declared in a function body is a local variable and can be used only from the line of its declaration to the closing right brace of the block in which the variable is declared.

  • A local variable’s declaration must appear before the variable is used; otherwise, a compilation error occurs.

Section 4.9.3 Notes on Integer Division and Truncation

  • Integer division yields an integer result—any fractional part of the calculation is truncated.

Section 4.9.4 Arithmetic Overflow

  • Adding two integers could result in a value that’s too large to store in an int variable. This is known as arithmetic overflow (p. 122) and causes undefined behavior, which can lead to unintended results and security problems.

  • The maximum and minimum values that can be stored in an int variable are represented by the constants INT_MAX and INT_MIN, respectively, which are defined in the header <climits>. There are similar constants for the other integral types and for floating-point types.

  • To see these constants’ values on your platform, open the headers <climits> and <cfloat> in a text editor (you can search your file system for these files).

Section 4.9.5 Input Validation

  • A program uses range checking (p. 123) to ensure that values are within a specific range.

Section 4.10 Formulating Algorithms: Sentinel-Controlled Iteration

  • In sentinel-controlled iteration (p. 124), a special value called a sentinel value (p. 123; also called a signal value, a dummy value or a flag value) is used to indicate “end of data entry.”

  • Sentinel-controlled iteration is often called indefinite iteration (p. 124) because the number of iterations is not known before the loop begins executing.

Section 4.10.1 Top-Down, Stepwise Refinement: The Top and First Refinement

  • Top-down, stepwise refinement (p. 124) is essential to the development of well-structured programs.

  • Begin with a pseudocode representation of the top (p. 124)—a single statement that, in effect, is a complete representation of a program.

  • The top rarely conveys sufficient detail from which to write a C++ program. So in the first refinement (p. 124), we refine the top into a series of smaller tasks and list these in the order in which they’ll be performed. This refinement uses only tasks in sequence.

Section 4.10.2 Proceeding to the Second Refinement

  • In the second refinement (p. 124), we commit to specific variables and logic.

Section 4.10.3 Implementing Sentinel-Controlled Iteration

  • A number with a decimal point is called a real number or floating-point number (p. 126; e.g., 7.33, 0.0975 or 1000.12345).

  • C++ provides types float (p. 126) and double (p. 126) to store floating-point numbers in memory.

  • double variables can typically store numbers with larger magnitude and finer detail (i.e., more precision; p. 126).

  • C++ also supports type long double (p. 126) for floating-point values with larger magnitude and more precision than double.

Section 4.10.4 Converting Between Fundamental Types Explicitly and Implicitly

  • The static_cast operator (p. 129) converts a temporary copy of its operand in parentheses to the type in angle brackets (double). Using a cast operator in this manner is called explicit conversion (p. 129).

  • For arithmeitc, the compiler knows how to evaluate only expressions in which the operand types are identical. To ensure this, the compiler performs an operation called promotion (p. 129; also called implicit conversion) on selected operands.

  • In an expression containing values of data types int and double, C++ promotes (p. 129) int operands to double values.

  • static_cast is a unary operator (p. 129)—it has only one operand.

  • C++ also supports unary versions of the plus (+) and minus (-) operators, so that you can write such expressions as -7 or +5.

Section 4.10.5 Formatting Floating-Point Numbers

  • setprecision (p. 130) is a parameterized stream manipulator (p. 130) that specifies the number of digits of precision to the right of the decimal point when a floating-point number is output.

  • Programs that use parameterized stream manipulators must include the header <iomanip> (p. 130).

  • The manipulator endl (from the header <iostream>) is a nonparameterized stream manipulator (p. 130), because it does not require an argument.

  • By default, floating-point values are output with six digits of precision.

  • The stream manipulator fixed (p. 130) indicates that floating-point values should be output in fixed-point format (p. 130), as opposed to scientific notation (p. 130).

  • Scientific notation displays a floating-point number between 1.0 and 10.0, multiplied by a power of 10. Scientific notation is useful when displaying very large or very small values.

  • Fixed-point formatting forces the decimal point and trailing zeros to print, even if the value is a whole number amount.

  • When the stream manipulators fixed and setprecision are used in a program, the printed value is rounded (p. 130) to the number of decimal positions indicated by setprecision’s argument, although the value in memory remains unaltered.

  • It’s also possible to force a decimal point to appear by using stream manipulator showpoint (p. 130). If showpoint is specified without fixed, then trailing zeros will not print.

  • Nonparameterized stream manipulators fixed and showpoint require the header <iostream>.

Section 4.11.7 Preventing Narrowing Conversions with List Initialization

  • For fundamental-type variables, list-initialization syntax prevents narrowing conversions (p. 136) that could result in data loss.

Section 4.12 Compound Assignment Operators

  • The compound assignment operators +=, -=, *=, /= and %= (p. 136) abbreviate assignment expressions.

Section 4.13 Increment and Decrement Operators

  • The increment (p. 137; ++) and decrement (p. 137; --) operators increment or decrement a variable by 1, respectively. If the operator is prefixed to the variable, the variable is incremented or decremented by 1 first, then its new value is used in the expression in which it appears. If the operator is postfixed to the variable, the variable is first used in the expression in which it appears, then the variable’s value is incremented or decremented by 1.

Section 4.14 Fundamental Types Are Not Portable

  • All variables must have a type.

  • The fundamental types are not guaranteed to be identical from computer to computer. An int on one machine might be represented by 16 bits (2 bytes) of memory, on a second machine by 32 bits (4 bytes), and on another machine by 64 bits (8 bytes).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset