CHAPTER 3 STRUCTURE OF A C++ PROGRAM Expressions: - Expression: is a sequence of operands and operators that can be evaluated to a single value. The value can be any type other than void. - Operator: is a language-specific syntactical token that requires an action to be taken. Examples: +, *, /, - Operand: is an object on which an operation is performed. For any operator, there may be one, two, or more operands. - There is no limit to the number of operator and operand sets that can be combined to form an expression. The only rule is that when they have been evaluated, the result is a single value that represents the expression. Precedence of Operation Precedence is the priority assigned to an operator or group of operators that determines the order in which operators will be evaluated in an expression. Associativity determines how operators with the same precedence are grouped. The following is partial precedence table of C++ expressions: (See Table 3-1 on page 73) (Higher Priority) Parentheses Postfix and Prefix Increment Multiply, Divide, Modulus (Lower Priority) Addition, Subtraction Primary Expressions - Primary Expression: consists of only one operand and no operator. The operand in the primary expression can be a name, a constant, or a parenthetical expression. - Name: is any identifier for a variable, a function, or any other object in the language. Ex: a b12 price calc INT_MAX SIZE - Constant: is data whose value can’t change during the program’s execution. Ex: 5 123.98 ‘A’ “Welcome” - Parenthetical Expression: is any expression enclosed in parentheses must be reduced to a single value. Ex: (2 * 3 + 4) (a = 23 + b * 6) Binary Expressions A binary expression is formed by an operand-operator-operand combination. - Multiplicative Expressions: first level of binary expressions that takes it name from the first operator, multiply. Multiply, divide, and modulus operator have the highest priority (13) among binary expressions and are therefore evaluated first. Examples: 3%5=3 5%2=1 3 / 5 = 0, 5 / 2 = 2 5 % 3 = 2, 5/3=1 returns remainder returns quotient - Tables 3-2 & 3-3 show examples of multiplicative binary operators and multiplicative binary expressions respectively. - Additive Expressions: second level of binary expressions that contains the additive expressions. The second operand is added to subtracted from or the first operand, depending on the operator used. Additive expressions are evaluated after multiplicative expressions. Ex: a + 7 b – 11 - Program below shows several binary expressions. /* This program demonstrates binary expressions. Written by: Date: 11-30 */ #include <iostream.h> int main (void) { // Local Declarations int a = 17; int b = 5; // } /* Results: Statements cout << a << " + " << b << " = " << a + b << endl; cout << a << " - " << b << " = " << a - b << endl; cout << a << " * " << b << " = " << a * b << endl; cout << a << " / " << b << " = " << a / b << endl; cout << a <<" % " << b << " = " << a % b << endl; cout << "Hope you enjoyed the demonstration.\n"; return 0; // main 17 + 5 17 – 5 17 * 5 17 / 5 17 % 5 = 22 = 12 = 85 =3 = 2 */ 2 Assignment Expressions: An assignment expression evaluates the operand on the right side of the operator (=) and places its value in the variable on the left. - There are two forms of assignments: 1. Simple Assignment: found in algebraic expressions. Ex: a = 5 b=x+1 j=j+1 The value of the right expression is evaluated and becomes the value of the total expression, which, in return, becomes the value of the left operand. The left operand must be a single variable and not a constant. Table 3-4 shows several examples of assignment expressions. 2. Compound Assignment: is a shorthand notation for a simple assignment. It requires that the left operand be repeated as a part of the right expression. There are five compound assignment expressions: *=, /=, %=, +=, -=. To evaluate a compound assignment expression, change it to a simple assignment and then perform the operation to determine the value of the expression. Ex: (see tables 3-5 & 3-6 ) The following program demonstrates compound assignments #include <iostream.h> int main (void) { // Local Declarations int x; int y; // Statements x = 10; y = 5; cout cout << "x: " << x << " | " << "y: " << y << " | " << "x *= y: " << (x *= y); << " | x is now: " << x << endl; x = 10; cout << "x: " << x << " | " << "y: " << y << " | " << "x /= y: " << (x /= y); cout << " | x is now: " << x << endl; x = 10; cout << "x: " << x << " | " << "y: " << y << " | " << "x %= y: " << (x %= y); cout << " | x is now: " << x << endl; } /* return 0; // main Result: x: 10 | y: 5 | x *= y: 50 x: 10 | y: 5 | x /= y: 2 x: 10 | y: 5 | x %= y: 0 | x is now: 50 | x is now: 2 | x is now: 0 */ 3 Postfix Expressions - A postfix expression operate at the second level, immediately after primary expressions. - Function call: The function name is its operand, and the parentheses that follow the names are its operator. The function call has a value, and therefore can be used in another expression. - Postfix Increment/Decrement: in the postfix increment, the var is increased by 1. Thus, i++ results in the var i being increased by 1. Ex: (i++) is identical to (i = i + 1) - There is a major difference; the value of the postfix increment expression is determined before the var is increased. - Figure below shows result of postfix operation: - The postfix decrement (i--) also has a value and a result. The value is the value of i before the expression and results in i being decrement by 1. Table 3-7 shows examples of postfix expressions. Unary Expressions - A unary expression consists of one operator and one operand. - Prefix Increment/Decrement: are short notations for adding or subtracting 1 from a variable. - The effect takes place before the expression that contains the operator is evaluated. - Figure below shows the result of prefix operation. /* Table 3-8 shows examples of prefix operator expressions. The program below shows the use of increment and decrement operators. Example of postfix/prefix increment and decrement. */ 4 #include <iostream.h> int main (void) { // Local Declarations int a; // Statements a = 4; cout << "value of a: cout << "value of a++ + 5: cout << "new value of a: cout << endl; a = 4; cout << "value of a: cout << "value of ++a + 5: " cout << "new value of a: " return 0; // main } /* Results: value of a: value of a++ + 5: new value of a: value of a: value of ++a + 5: new value of a: */ - " << a " << (a++ + 5) " << a << endl; << endl; << endl; " << a << (++a + 5) << a << endl; << endl; << endl; 4 9 5 4 10 5 Sizeof: it tells the user the size, in bytes, of whatever type is specified. On most PCs the size of the integer type is two bytes. On most mainframes it is 4 bytes and on supercomputers it can be as large as 16 bytes. Ex: x = sizeof (int) Unary Plus/Minus: are used to compute the arithmetic value of an operand. The minus can algebraically change the sign of a value. Table 3-9 shows examples of unary plus and minus. Precedence and Associativity - Precedence: is used to determine the order in which different operators in a complex expression are evaluated. Ex: 2 + 3 * 4 (2 + (3 * 4)) = 14 -b++ (-(b++)) expr. = (- (5)), b = 6 - Associativity: used to determine the order in which operators with the same precedence are evaluated in a complex expression. - Left Associativity: evaluates the expression by starting on the left moving to the right. Ex: 3 * 8 / 4 % 4 * 5 10 - Figure below shows an example of left associativity. 5 - - - - Right Associativity: there are only three types of expressions that associate from the right: the unary expressions, the conditional ternary expressions, and the assignment expressions. When there is more than one assignment operator in an assignment expression, the assignment operators must be interpreted from right to left. This means that the rightmost expression will be evaluated first. Then its value will be assigned to the operand on the left of the assignment operator, and the next expression will be evaluated. Ex: a += b *= c -= 5 18 given that a = 3, b= 5 and c = 8. Figure below shows the diagram of a right associativity example. To initialize more than one variable to zero: Ex: a = b = c = d = 0; Side Effects - It is an action that results from the evaluation of an expression. C++ first evaluates the expression on the right of the assignment operator and then places its value in the variable on the left of the assignment operator. Changing the value of the variable is a side effect. #include <iostream.h> int main (void) { int x; x = 3; cout << "x is: " cout << "x = x + 4 is: " cout << "x now is: " cout << endl; << x << (x = x + 4) << x << endl; << endl; << endl; return 0; } // main x is: 3 x = x + 4 is: 7 x now is: 7 - Ex: a++, the value of the expression is the value of a before the expression is evaluated. As a side effect, however, the value of a is incremented by 1. Table 3-10 shows pre- and post-side effects. 6 Evaluating Expressions - To evaluate an expression without side effects, follow the simple rules below: 1. Replace the vars by their values. 2. Evaluate the highest precedence operators and replace them with the resulting value. 3. Repeat step 2 until the result is a single value. Ex: a * 4 + b / 2 - c * b, 12 + 2 – 20 – 6 the values of a, b, and c are 3, 4, 5 respectively. Ex: --a * (3 + b) / 2 – c++ * b, the values of a, b, and c are now 3, 4, 5 respectively. a * (3 + b) / 2 – c * b, 2 * (3 + 4) / 2 – 5 * 4, 14 / 2 – 20, 7 – 20 –13 // Example: P03-04 Evaluating expressions #include <iostream.h> int main (void) { // Local Declarations int a = 3; int b = 4; int c = 5; int x; int y; // Statements cout << "Initial values of the variables: \n"; cout << "a = " << a << " b = " << b << " c = " << c << endl << endl; x = a * 4 + b / 2 - c * b; cout << "Value of a * 4 + b / 2 - c * b is: " << x << endl; y = --a * (3 + b) / 2 - c++ * b; cout << "Value of --a * (3 + b) / 2 - c++ * b is: " << y << endl; cout << "\nValues of the variables are now: \n"; cout << "a = " << a << " b = " << b << " c = " << c << endl; return 0; } // main /* Initial values of the variables: a=3 b=4 c=5 Value of a * 4 + b / 2 - c * b is: -6 Value of --a * (3 + b) / 2 - c++ * b is: -13 Values of the variables are now: a=2 b=4 c=6 */ 7 - Warning: In C++, if a single var is modified more than once in an expression, the result is undefined. Ex: page 89. Mixed Type Expressions If an expression contains both integer type and floating-point type operands, the value of the expression must be the floating-point type. Examples: 5/2 2 5.0/2 2.5 5.0/2 2.5 5.0/2.0 2.5 Implicit Type conversion It is used when C++ converts a type from one format to another. Conversion is done to the more general type according to the promotion order shown in figure below. - Fortunately for users, the compiler does all the conversions. Table 3-11 on page 90 shows examples of implicit conversions. Explicit Type Conversion (CAST) - The user does the conversion instead of the compiler. - It uses the cast expression operator. - To cast data from one type to another, you specify the new type in parenthesis before the value you want converted. Ex: (float) a if a was declared as integer. Ex: (float) (x + y) to cast the sum of two int to a float Ex: average = (float) totalScores / numScores 8 Explicit conversion of totalScores and implicit for numScores - What is the difference between? Ex: (float) (a / 10) & (float) a /10 assuming that a’s value is 3. 0.0 .3 9 Statements - Causes an action to be performed by the program and translates directly into 1 or 2 more executable computer instructions. - C++ defines 6 types of statements as shows in figure below: Expression Statements - An expression is turned into a statement by placing a semicolon (;) after it. - An expression without side effects does not cause an action. Unless a statement has a side effect, it does nothing. Ex: a = 2; a = b = 3; a++; - Although they are useless the following are also expression statements: Ex: b; 3; ; - The semicolon is a terminator, and tells the compiler that the statement is finished. Compound Statements - It is a unit of code consisting of zero or more statements known as a block. - The compound statement allows a group of statements to become a single entity. - All C++ functions contain a compound statement known as the function body (e.g. Hello world program.) - Figure below shows the makeup of a compound statement. 10 - A compound statement consists of an opening brace, an optional declaration and definition section, and an optional statement section, followed by a closing brace. Although the declaration-definition and statement sections are optional, one, however, should be present. It is a good practice to place comments and declarations at the beginning of the block for readability purposes. Implementation of different C++ expression formats. (Table 3-1, p, 73) 11