and Expressions in C++ 3.1 CONCEPT OF DATA TYPES The kind of data that variables may hold in a programming language is called the data types. The ability to divide data into different types in C++ enables you to work with complex objects. There are two reasons for distinguishing between data types. These are: (a) The compiler may use the proper internal representation for each data type. (b) The programmer designing the programs may use proper operators for each type of data. The C++ language offers a set of data types. They can be broadly classified into the following three categories. (a) User-defined type (b) Built-in type (c) Derived type Figure 3.1 shows the hierarchy of C++ data types. The user defined data type enables a pro- grammer to invent his/her own data type and define what values it can take on. This can help make listings more readable, in the case of a complicated program or when more than one programmer works on it. Thus this data type can help a programmer reduce programming errors. Derived data types are built from the basic integer and floating-point data types. The array data type is one example of derived data type. An array can hold several values of the same type under one variable name. In this chapter we shall confine our study to built-in data types. 3.1.1 Built-in Data Types The three built-in data types available in C++ are: (a) Integral type (b) Floating type (c) Void bpbonline all rights reserved 24 Programming in C++ Part I Figure 3.1 Hierarchy of C++ data types Inte g ra l Typ e This can be further classified into: (i) int (ii) char int. Int is the basic integer data type. It is treated as an integer in that it cannot hold fractional val- ues. char. This is a data type which can hold both the character data or the integer data. For example, after making the declaration: char c; you can make either of the following assignments: c = A; c = 65 In both cases, the decimal value 65 is loaded into the variable c. Floa ting Typ e This can be further classified into: (iii) float (iv) double C++ Data Types Built-in Type User-defined Type Derived Type Integral Floating void int char float double bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 25 float. Integers are not adequate for representing very large numbers and fractions. For this you need floating-point types of data representation. The simplest method is to place a decimal point in the number as shown below: 0.356 0.000001 In order to declare a variable capable of holding one of these values you use the float or double keyword. double. The word double stands for double precision. It is capable of representing a real number ranging from 1.7 to 1.710 308 which gives twice as much precision as represented by a float. The precision refers to the number of decimal places that can be represented. Void Typ e The void data type has two important purposes. The first is to indicate that a function does not return a value and the other is to declare a generic pointer. For instance, you may see a function definition such as void func(a,b) int a,b; { . } This indicates that the function does not return any useful value. Likewise, on the calling side, you would declare func() as extern void func(); This informs the compiler that any attempt to use the returned value from func() is a mistake and should be flagged as an error. For example, you could invoke func() as follows: func(x,y); But you cannot assign the returned value to a variable. 3.1.2 Declarations Every variable must be declared before it is used. A declaration provides the compiler with infor- mation about how many bytes should be allocated and how those bytes should be interpreted. To declare j as an integer, you would write: int j; As a shorthand, you can declare variables that have the same type in a single declaration by separating the variable names with commas. You could declare j and k with int j,k; which is the same as 10 308 bpbonline all rights reserved 26 Programming in C++ Part I int j; int k; It is usually a good idea to group declarations of the same type together for an easy reference. For example: int j,k; float x,y,z; The word int and float are reserved words that specify the integer data type and real data type. There are nine reserved words for data types in C++ as given below: char int double short signed float void long unsigned The first five char, int, float, double, and void are built-in data types. The others long, short, signed, and unsigned are qualifiers or modifiers that modify a built-in data type, with the exception of void in some way. You can think of the built in data types as nouns and the qualifiers as adjectives. Typical range and size of these data types are given in Table 3.1. Variable names can be single-character names in certain circumstances, particularly in short example programs and test programs. To make them a bit more meaningful, there is a convention. The names i, j, k, m and t are generally used for integer counters and temporary variables; x, y and z are used for floating-point temporary variables; and c is used for character variables. 3.1.3 Declaring Different Types of Integers In Turbo C++, a short int is two bytes and a long int is four bytes. To declare j as a short int and k as a long int, you would write: short int j; long int k; If you need to store integer values less than 32,768 or greater than 32,767, you should use long int. If you need to store integer values in the range 32767 and 32767, then you can use short int. Unsig ne d Inte g e rs There are a number of cases where a variable will have to hold only non-negative values. For instance, variables that are used to count things are often restricted to non-negative numbers. The C++ language allows you to declare that a variable is non-negative only (or unsigned), thereby doubling its positive range. Thus a signed short int has a range from 32,767 to 32,767, whereas an unsigned short int has a range from 0 to 65,535. To declare an integer variable as being non negative only, use the unsigned qualifier, as given below: bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 27 unsigned int k; unsigned short m; unsigned long n; C ha ra c te rs a nd Inte g e rs C++ makes a distinction between numeric and character data. The number "5" is a number while the letter "A" is a character. The data type char can be used to hold either characters or numbers. For instance, after making the declaration char c; you can make either of the following assignments; c = A; or c = 65; Note that character constants are enclosed in single quotes. The quotes tell the compiler to get the numeric code (ASCII code value) of the character. Table 3.1 Typical range and size of basic data types Type Range Bytes Repre- sents From To char 128 127 1 charac- /short ters unsigned char 0 255 1 charac- ters int 32,768 32,767 2 whole numbers unsigned int 0 65,535 2 whole numbers long 2,147,438,648 2,147,438,647 4 whole numbers unsigned long 0 4,294,967,295 4 whole numbers float 3.4 3.410 38 4 frac- tional numbers double 1.7 1.710 308 8 frac- tional numbers 10 38 10 308 bpbonline all rights reserved 28 Programming in C++ Part I long double 3.4 3.410 4932 10 frac- tional numbers In the following example, the variable a gets the value 5, whereas the variable b gets the value 53 since that is the ASCII code value for the character "5". char a, b; a = 5; b = 53; Exa mp le 1 The program shown in Figure 3.2 asks you to input a character from the keyboard and then dis- plays the ASCII code value of the character. The goto statement at the end of the program enables you to input the next character from the keyboard. In the ASCII character set, character codes are ordered alphabetically. For example, ASCII code value of an upper case A, is 65, B is 66,... Z is 90. ASCII code value of lower case letters i.e. a starts at 97 and runs through 122. 3.2 VARIABLES AND CONSTANTS In a program, the name assigned to a data field that can assume any of a given set of values is defined as the variable. However, constant is a value, written into a program instruction, that does not change during the execution of the program. Each one of these terms are further discussed in the following sections. 3.2.1 Variables The statement j = 5+10; means "add the values 5 and 10 and assign the result to a variable called j." We know that "5" and "10" are integer values. "+" and "=" are operators. ";" determines the end of the statement and j is a variable whose value can be changed. To make sense out of the expression, the computer must be told at some point as to what each symbol means. This is one of the functions of the compiler used to translate the program into a machine language code. In the following statement: j = 5+10; The symbols "5" and "10" are constants because they have the same value no matter where they appear in a program. The symbol j, on the other hand, is the name of a variable that is able to rep- resent different values. 10 4932 bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 29 //*****************************************************// // The following C++ program prints// // the numeric code value of a character // //*****************************************************// #include <iostream.h> main (void) { char ch; int number1; qwrt: cout << "Enter a character:"; cin >> ch; number1 = ch; cout << "Its numeric code value is: "; cout << number1 << endl; goto qwrt; } Figure 3.2 Program to print ASCII code value of the inputted character Na me s You can name variables, constants, etc. in C++. The names may contain letters, numbers and the underscore character _, but must start with a letter or underscore. However, names beginning with an underscore are reserved for internal system variables. The names given in C++ language are case sensitive, which means that it differentiates between lower case and upper case letters. So the names: VaR var VAR are all different. The advantage of case sensitivity is that you have more names to choose from. The names cannot be the same as one of the reserved keywords. So you should avoid using names that are used as keywords. Table 3.2 gives some of the valid and invalid names. Exp re ssions An expression is any combination of operators, numbers and names that denotes the computation of a value. The following are some of the examples of expressions: 5 A constant j A variable 5+j A constant plus a variable 5*j+6 A constant times a variable plus a constant bpbonline all rights reserved 30 Programming in C++ Part I Table 3.2 Valid and invalid variable names Valid variable names Invalid variable names j 5j name may not begin with a digit j5 _system_name $name name may not contain a $ sign UpPer_and_Lower_cAse int Int is a reserved keyword bad%#*n name may not contain any special character except an underscore. The building blocks of expressions include variables, constants etc. The building blocks by themselves are expressions, but they can also be combined by operators to form more complex expressions. For example, the following are some of the most basic operators: + Addition - Subtraction * Multiplication / Division % Remainder Floa ting - p oint Va ria b le s To declare a variable capable of holding fractional or real values, you use the keyword float or double . For example: float pi; double pi_squared; pi = 3.141; pi_squared = pi * pi; The word double stands for double-precision. It is capable of representing a value which is about twice as much precision as that of a float. The precision refers to the number of decimal places that can be represented. M ixing Typ e s The C++ language allows you to mix arithmetic types in expressions with few restrictions. For example, you can write: num = 3 * 2.1; Even though the expression on the right-hand side of the assignment is a mixture of two types, an int and a double precision. Also, the data type of num could be any numerical data type, such as int, float etc. To make sense out of an expression with mixed types, C++ performs conversions automati- cally. These implicit conversions make the programmers job easy. For example, the expression: bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 31 3.0 + 1/2 does not evaluate to 3.5 as you might expect. Instead, it evaluates to 3.0. Implicit conversions or automatic conversions occur under the following circumstances: (a) In assignment statements, the value on the right side of the assignment is converted to the data type of the variable on the left side. These are called assignment conversions. (b) In an arithmetic expression, objects are converted to conform to the conversion rules of the operator. Exa mp le 2 Suppose j is declared as an int type of variable, then in the following statement: j = 2.6; The compiler converts j to an int, giving it an integral value of 2. Note that the compiler truncates the fractional part rather than rounding it to the closest integer. To understand the conversion of arithmetic expressions mentioned in sub-para (b) above of implicit conversion, we first need to describe briefly how the compiler processes expressions. The rules for implicit conversions in expressions can be summarized as follows. (i) If a pair of operands contains a long double, the other value is converted to long double. (ii) Otherwise, if one of the operands is a double, the other is converted to double. (iii) Otherwise, if one of the operands is a float, the other is converted to a float. (iv) Otherwise, if one of the operands is an unsigned long int, the other is converted to unsigned long int. (v) Otherwise, if one of the operands is a long int, then the other is converted to long int. (vi) Otherwise, if one of the operands is an unsigned int, then the other is converted to unsigned int. M ixing Inte g e rs with Floa ting - p oint Va lue s In C++ language, you can mix integers and floating-point values in an expression, to assign a floating-point value to an integer variable, or assign an integer value to a floating-point variable. The simplest case is assignment of an integer to a floating-point variable. In such a case, the inte- ger value is understood to be converted to a floating-point type. If the floating-point type is capa- ble of representing the integer, there is no change in value. Suppose f is a double precision variable then the assignment: f = 10 is executed as if it had been written as follows: f = 10.0 Similar action is taken in the case of mixing integer and floating-point values in an expres- sions. The compiler converts all integers into the largest floating-point type present. Suppose j is an Int and f is a float, the expression: bpbonline all rights reserved 32 Programming in C++ Part I f + j would cause j to be quietly converted to a float. In the expression: f + j + 2.5 both f and j would be converted to doubles because f is of double precision type. Exa mp le 3 The expression 3/4 + 2.5 contains three operators: , /, and +. The operand to is 3; there are two operands to /, 3 and 4; and there are two operands to +, 3/4 and 2.5. The value of 3/4 is .75. To this 2.5 is added. Thus the result will be 1.75. The minus operator is said to be a unary operator because it takes just one operand, whereas the division and addition operators are binary operators. 3.2.2 Constants Ba c ksla sh C ha ra c te r C onsta nts The backslash (\) alters the meaning of the character that follows it. Thus the character a when typed after the backslash, i.e. \a will mean to produce an audible or visual alert signal. Table 3.3 Backslash character strings Backslash character Meaning \a (alert) Produces an audible or visible alert signal \b (backspace) Moves the cursor back one space \f (form feed) Moves the cursor to the next page \n (new line) Prints a new line \r (carriage return) Prints a carriage return \t (horizontal tab) Prints a horizontal tab \v (vertical tab) Prints a vertical tab Table 3.3 gives the list of backslash character strings and the action they produce. Inte g e r C onsta nts We have understood a few integer constants such as 5, 10 and 2 etc. We can also write octal and hexadecimal constants. An octal constant is written by preceding the octal value with the digit zero. A hexadecimal constant is written by preceding the value with a zero and an x or X. Table 3.4 lists of the integer constants. Table 3.4 Integer constants bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 33 Decimal Octal Hexadecimal 3 003 0x3 8 010 0x8 15 017 0xf 16 020 0x10 21 025 0x15 87 0127 0x57 An octal constant cannot contain the digit 8 or 9 since they are not part of the octal number set. Floa ting - Point C onsta nts Integers are inadequate for representing very large or very small numbers and fractions. For this, you need floating-point types. There are two ways to write floating-point constants, the simplest being to place a decimal point in the number. For example: 0.356 5.0 0.00001 .7 7 are all legal examples of floating-point constants. Table 3.5 lists some of the valid and invalid floating point constants. Table 3.5 Floating point constants Valid floating Invalid floating Remarks point constant point constant 3.141 35 No decimal point or exponent .333333333 0.3 3,500.45 Commas are illegal 3e2 4E The exponent sign must be followed 5E-2 by a number 3.7e12 4e3.6 The exponent value must be an inte- ger String C onsta nts A sequence of zero or more characters surrounded by double quotes is called a string constant. This can also be defined as an array of character constant. For example, the string given below is placed between two quotes and represents a string constant. "This is a " A blank string constant can be represented by " ". In this case, a blank space is placed between two quotes. bpbonline all rights reserved 34 Programming in C++ Part I Exa mp le 4 What would be the appropriate data types to store the following: (a) Some ones height in metres (b) An exclamation mark (!) (c) The number of students in a university Solution The selected data types should be as follows: (a) A float, because the height may contain a decimal fraction. (b) A char, because it is an ASCII character. (c) An int, or more appropriately, an unsigned int, because there will never be a negative number of students. 3.3 CHOOSING THE DATA TYPE When choosing the data type to represent something in a program, think about the likely data range of the variable. For example, if a variable is to hold student examination marks out of 100, then an int type will be more than sufficient. However if the variable is to hold, for example, the population of India, then the integer type will be too small, and a long data int type will be required. Unsigned variables are useful if we know in advance that there will never be a negative value for that variable. For example, number of students in a class, then the value can never be less than zero, so an unsigned variable may be used. Any variable which is likely to contain decimal fractions will have to be at least a float, as will a variable which is required to handle very large numbers. For programs dealing with astronomy for example the long double data type would be necessary to deal with large numbers to meet the accuracy requirements. The char data type holds numbers, but is used to represent characters. A char can be assigned either a numeric value or the character itself, surrounded by apostrophes. For example, using ASCII code, the number 65 and the character A are equivalent values for a char data type, since 65 is the ASCII code for a capital A. Data such as A, or any other single character between apostrophes, is known as character constant. 3.4 ACCESS MODIFIERS The category of keywords known as access modifiers tells the C++ compiler something special about a memory locations contents. The two keywords const and volatile help to identify which variables will never change (const) and those variables that can change unexpectedly (volatile). 3.4.1 The C onst Keyword There are three reasons to declare a variable with the const keyword. The first is when a program- mer wants the compiler to flag, as an illegal operation, any statement within the source code that attempts to change the constants contents. In other words, the variable being declared as a constant does not reference a memory cell whose contents are variable, but locked. For example, if bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 35 a program deals with the area and circumference of a circle, the constant value pi = 3.14159 would be used frequently. In such a case, you can improve the readability of the program by giving the constant a descriptive name. There is another very good reason for using constants. By suing a descriptive name to refer- ence a frequently used value, such a FEET_TO_INCHES, you avoid possible typographical value errors. The following constant declaration: const int FEET_TO_INCHES = 12; allows you to write length_in_inches = length_in_feet * FEET_TO_INCHES; instead of a possible typographical value error such as: length_in_inches = length_in_feet * 11 The above sentence though syntactically correct, is logically incorrect. So the program will run and give a wrong result. Thus using FEET_TO_INCHES prevents this possibility. While numer- ical typographical errors go undetected by the compiler, misspelled constants do not. You can declare a C++ constant by writing const before the identifiers data type. For example, const int height = 8; const float normal_temp = 98.6; Because a constant cannot be changed, it must be initialized when it is declared. The int con- stant, height, is initialized to a value representing a normal wall height. The constant normal_temp is of type float and has been initialized to represent the human bodys normal temperature. Syntactically you use constants and variables the same way. However, the initial values assigned to a constant cannot be changed. That is, the constants can not appear to the left of an equal sign. Normally, the assignment operation assigns the value of the right-hand operand to the storage location named by the left-hand operand. Therefore, the left-hand operand of an assign- ment operation must be an expression that refers to a modifiable memory location. Expressions that refer to memory locations are called lvalue expressions. Expressions referring to modifiable locations are modifiable lvalues. One example of a modifiable lvalue expression is a variable name declared without the const specifier. 3.5 WHAT IS AN OPERATOR? An operator in a high level computer language specifies an operation to be performed that yields a value. An operand is an entity on which an operator acts. You can think of operators as verbs and of operands as the subject and object of those verbs. For example in the expression: a + b the sign + is an operator which specifies the operation of addition on the two operands a and b. The operators can be classified as under: (a) Unary operator Requires one operand (b) Binary operator Requires two operands bpbonline all rights reserved 36 Programming in C++ Part I (c) Ternary operator Requires three operands Operators can be grouped as arithmetic operators, increment and decrement operators, unary operators, relational operators, and conditional operators. Each of the group of operators is described in the following sections. 3.6 ARITHMETIC OPERATORS Arithmetic operators are used for mathematical calculations. An arithmetic expression is made up of constants, variables, a combination of both or a function call, connected by arithmetic operators. The unary, binary and ternary arithmetic operators are as follows: 3.6.1 Unary Arithmetic Operator The unary arithmetic operator needs only one operand. For example, b, +k use the unary opera- tor, namely (negative) or + (positive). 3.6.2 Binary Arithmetic Operator The binary arithmetic operator requires two operands. For example, the following arithmetic operators need two operands. (a) + (addition or plus) (b) (subtraction or minus) (c) * (multiplication) (d) / (slash for division) (e) % (modulus operator for remainder). This operator cannot be applied with floats or double data type. Here x % y means remainder of x divided by y. Thus if x = 5 and y = 2 then x % y will be 1. This operator is applicable only if x and y both are of integer vari- ables. The following is an example showing other binary arithmetic operators: m + v * v/2 3.6.3 Ternary Arithmetic Operator Ternary arithmetic operator takes three operands. This is one of the special features of C++ lan- guage. For example: big = a > b ? a : b; In the above assignment statement, if a > b then big is equal to a otherwise big is equal to b. 3.6.4 Hierarchy of Arithmetic Operators The hierarchy or order of operation of arithmetic operators is as follows: (a) * / % are evaluated from left to right (b) + are evaluated from left to right bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 37 The expressions within the parenthesis are evaluated first following the hierarchy given in subparas (a) and (b) above. In the event of nested parentheses (i.e. parentheses inside the paren- theses), the C++ compiler groups the expression enclosed by the innermost parentheses first. For example, the compiler will group and evaluate the expression: 1 + ((3 + 1)/(8 4) 5) as shown in Figure 3.3. Figure 3.3 Evaluation of an expression enclosed by parantheses 3.6.5 Integral Division and Remainder When both operands of the division operator (/) are integers, the result is an integer. If operands are positive and the division is imprecise, the fractional part is truncated. For example: 5/2 evaluates to 2 7/2 evaluates to 3 1/3 evaluates to 0 If either operand is negative, the compiler is free to round the result either up or down. For example: -5/2 evaluates to 2 or 3 7/-2 evaluates to -3 or -4 1/3 evaluates to 0 or -1 Hence you should avoid division and remainder operations with negative numbers since the results can vary from one compiler to another. If the sign of the remainder is important to your programs operation, you should use the runtime library div() function, which computes the quo- tient and the remainder of its two arguments. 1 + ( ( 3 + 1 ) / ( 8 _ 4 ) _ 5 ) + 1 ( 4 / ( _ 8 _ 4 ) ) 5 + 1 ( 4 / 4 _ 5 ) + 1 ( 1 _ 5 ) + 1 4 _ 3 _ The innermost parentheses are evaluated first. The expressions ( 3 + 1 ) and ( 8 4 ) are at the same depth, so they can be evaluated in either order. Division has a higher precedence than subtraction. _ Final result. bpbonline all rights reserved 38 Programming in C++ Part I Exa mp le 5 Given the following declarations: int m = 3, n = 4; float x = 2.5, y = 1.0; Evaluate the values for the following expressions: (a) m + n + x+ y (b) m + x * n + y (c) x / y + m / n (d) x - y * m + y / n (e) x / 0 Solution (a) The expression (m + n + x + y) is equal to 3 + 4 + 2.5 + 1.0 = 10.5 (b) The expression (m + x * n + y) is equivalent to ((m + (x * n) + y)) because the hierarchy of * is higher than that of +. Substituting the values of the variables, we get: ((3 + (2.5 * 4) + 1.0)) = 14.0 (c) The expression (x / y + m / n) is equivalent to ((x / y) + (m / n)). Thus substituting the values of x, y, m and n, we get: (2.5 / 1.0) + (3 / 4) = 2.5 Note that the value of 3 / 4 is calculated to be 0. Because the division of two integer val- ues 3 / 4 does not give any integer quotient. Hence it is taken to be zero. (d) The expression (x - y * m + y / n) is equivalent to (x - (y * m)) + (y / n). Thus substituting the values of x, y, m and n, we get: (2.5 - (1.0 * 3) + (1.0 / 4) i.e. 2.5 - 3.0 + .25, i.e. 0.25. (e) x / 0 is undefined. Any number divided by zero is infinite and hence the value is not defined. 3.6.6 Remainder Operator (%) Unlike the other arithmetic operators, which accept both integer and floating point operands, the remainder operator (sometimes called the modulus operator) accepts only integer operands. The resulting value is the remainder of the first operand divided by the second operands. For example, the expression: 9 % 5 has a value of 4 because 5 goes into 9 once with a remainder of 4. The expression: 10 % 5 has a value of zero because 5 goes into 10 two times with no remainder. If either operand is negative the remainder can be negative or positive, depending on the implementation. bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 39 3.7 INCREMENT AND DECREMENT OPERATORS In some problems, a situation may arise to increase or decrease a variable by 1 continuously for some time. C++ provides special operators ++ and -- to do this. The increment and decrement operators are unary. The operand must be a scalar value. It is illegal to increment or decrement constant or a floating point data type. The incrementing and decrementing can be of two types. These are: (a) First increment or decrement the value of the variable and then take this new value for processing (prefix) (b) First take the value of the variable for processing and then only increment or decrement the variable. (postfix). Table 3.6 summarizes the postfix and prefix operators. Table 3.6 Postfix and prefix operators Operator Symbol Form Operation Postfix increment ++ a++ Get the value of a, then increment a Postfix decrement -- a-- Get the value of a, then decrement a Prefix increment ++ ++a Increment a, then get the value of a Prefix decrement -- --a Decrement a, then get the value of a The postfix increment and decrement operators fetch the current value of the variable and store a copy of it in a temporary location. The C++ compiler then increments or decrements the vari- able. The temporary copy, which has the variables value before it was modified, is used in the expression. This statement will be more clear by running the programs given Example 6. Exa mp le 6 Type the program in Figure 3.4(a) and run it. The program gives the value of integer variables j and k in the two different situations. In the first cout statement, the current values of j and k are printed. This value is 5 for both the variables. The next cout statement prints the postfix incremental value for the variable j which is the original value of the variable j increased by 1. Thus the printed value for j is 6. However in the case of k, the postfix decremental value is printed. This means that the original value of k is decreased by one and therefore, the printed value is 4. bpbonline all rights reserved 40 Programming in C++ Part I // ***************************************** // // Following C++ program prints the// // postfix incremental and decremental // // values of the variable j and k respectively// // ***************************************** // #include <iostream.h> main (void) { int j = 5; int k = 5; cout << "print the values of variable j and k" << endl; cout << "without postfix increment or decrement" << endl; cout << "j=" << j++ << endl; cout << "k=" << k-- << endl; cout << "print the value of j after postfix increment" << endl; cout << j << endl; cout << "print the value of k after postfix decrement" << endl; cout << k << endl; } The result seen on the screen for the above program will be: print the values of variable j and k without postfix increment or decrement j=5 k=5 print the value of j after postfix increment 6 print the value of k after postfix decrement 4 Figure 3.4(a) Illustration of postfix incremental and decremental bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 41 // ***************************************** // // Following C++ program prints the prefix // // incremental and decremental values of // // the variable j and k respectively// // ***************************************** // #include <iostream.h> main (void) { int j = 5; int k = 5; cout << "print the values of variable j and k" << endl; cout << "j = " << j << endl; cout <<" k = " << k << endl; cout << "print the prefix incremental value of j:" << endl; cout << "j=" << ++j << endl; cout << "print the prefix decremental value of k:" << endl; cout << "k=" << --k << endl; } Figure 3.4(b) Illustration of prefix incremental and decremental The program in Figure 3.4(b) is designed to demonstrate the prefix incremental and decre- mental values of integer variables j and k. On running the program shown in Figure 3.4(b) the result seen on the screen would be: print the values of variable j and k j=5 k=5 print the prefix incremental value of j: j = 6 print the prefix decremental value of k k = 4 You would thus notice that prefix increment and decrement operators modify their operands before they fetch the values. Exa mp le 7 The two programs shown in Figure 3.5(a) and 3.5(b) give the product of two variables a and b in the postfix and prefix increment situations respectively. After executing the above program in Figure 3.5(a), you will get the following output. print the value of the product of a and b 25 bpbonline all rights reserved 42 Programming in C++ Part I print the value of the product after postfix incremental value of a and b: 36 In the program shown in Figure 3.5(b), the product of the variables a and b is calculated using prefix incremental values. The output of the program will be as follows: print the value of the product of a and b 25 print the value of the product with prefix incremental value of a and b: 36 // *************************************** // // Following C++ program prints the product// // of variables a and b // // without and with postfix incremental // // *************************************** // #include <iostream.h>main (void) { int z; int a = 5; int b = 5; cout << "print the value of the product of a and b" << endl; z = (a++) * (b++); cout << z << endl; cout << "print the value of the product after postfix" << endl; cout << " incremental value of a and b:" << endl; z = (a) * (b); cout << z << endl; } Figure 3.5(a) Program to print product of two variables with postfix incremental values bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 43 // *************************************** // // Following C++ program prints the // // product of variables a and b without // // and with prefix incremental values // // *************************************** // #include <iostream.h> main (void) { int z; int a = 5; int b = 5; cout << "print the value of the product of a and b" << endl; z = a*b; cout << z << endl; cout << "print the value of the product with prefix" << endl; cout << " incremental value of a and b:" << endl; z = (++a) * (++b); cout << z << endl; } Figure 3.5(b) Program to print product of two variables with prefix incremental values 3.8 UNARY OPERATORS The plus and minus operators are called unary operators because they take only one operand. The operand can be any integer or floating-point value. The type of the result is the type of the operand after integral promotions. The minus operator returns the negation of its argument. If m equals 5, m equals 5. On the other hand, if m equals 5 then m equals 5. Do not confuse the unary minus operator with the binary subtraction operator. Even though they use the same minus ( ) symbol. However, they are different operators. For example: j = 3 - -x is interpreted as j = (3 - (-x)); The first dash is a subtraction operator; the second is a unary minus sign. Note that the space between the two dashes prevents them from being interpreted as a decrement operator(--). Table 3.7 summarizes the unary plus and minus operators. bpbonline all rights reserved 44 Programming in C++ Part I Table 3.7 Unary plus and minus operators Operator Symbol Form Operation unary minus a negation of a unary plus + +b 3.9 RELATIONAL OPERATORS Relational operators are used to test the relation between two values. All C++ relational operators are binary operators and hence require two operands. A relational expression is made up of two arithmetic expressions connected by a relational operator. It returns zero when the relation is false and a nonzero when it is true. The relational operators are summarized in Table 3.8. Table 3.8 Relational operators Operator Symbol Form Result greater than > a > b 1 if a is greater than b; else 0 less than < a < b 1 if a is less than b; else 0 greater than or equal to >= a >=b 1 if a is greater than or equal to b; else 0 less than or equal to <= a <= b 1 if a is less than or equal to b; else 0 equal to == a == b 1 if a is equal to b; else 0 not equal to != a != b 1 if a is not equal to b; else 0 All the relational operators have lower precedence than the arithmetic operators. For example, the expression: a + b * c < d / f is evaluated as if it had been written as follows: ( a + (b * c )) < (d / f) Exa mp le 8 Given the following declarations: int j = 0, m = 1, n = 1; float x = 2.5, y = 0.0 Evaluate the following expressions: (a) j > m (b) m / n < x (c) j <= m >= n (d) j <= x == m (e) -x + j == y > n >= m (f) x += (y >= n) (g) ++j == m != y * 2 bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 45 Solution (a) j > m is not true because the value of j = 0 and value of m = 1. Hence the result is 0 (zero). (b) The expression m / n < x is equivalent to (m / n) < x because the hierarchy of / is higher than that of <. Substituting the values of the variables, we get the result to be 1 (true). (c) The expression j <= m >= n is equivalent to ((j <= m) >= n). Substituting the values of the variables we get the result to be 1 (true). (d) The expression j <= x == m is equivalent to ((j <= x) == m). Substituting the values of the variables, we get the result to be 1 (true). (e) The expression -x +j == y > n >= m is equivalent to ((-x) +j ) == ((y > n) >= m). Substi- tuting the values of the variables we get the result to be 0 (false). (f) The expression x += (y >= n) is equivalent to x = (x + (y >= n). Substituting the values of the variables we get the result to be 3.5. (g) The expression ++j == m != y * 2 is equivalent to ((++j) == m) != (y * 2). Substituting the values of the variables we get the result to be true (1). The term (++j == m) is evaluated to be 1 because the value of ++j is 1, and the value of m =1. Therefore, (++j == m) is true or the value of the term is 1. The value of the term (y * 2) is zero because 0 * 2 is zero. Hence the resultant expression amounts to (1 != 0) and this is true. Thus the value of the expression is 1. 3.10 LOGICAL/BOOLEAN OPERATORS A logical operator combines the results of one or more expressions and the resultant expression is called the logical expression. After testing the conditions, they return logical status (true or false) as net result. The logical operators are unary or binary operators. The operands may be constants, variables or expressions. Table 3.9 summarizes logical operators. Table 3.9 Logical operators Operator Symbol Form Result logical AND && a && b 1 if a and b are nonzero; else 0 logical OR || a || b 1 if a or b is nonzero; else 0 logical negation ! !a 1 if a is zero; else 0 In algebra, the expression x < y < z is true if y is greater than x and less than z. But this expression has a different meaning in C++ since it is evaluated as (x < y) < z The subexpression (x < y) is evaluated first and results in either 0 or 1. So in C++, the expres- sion is true if x is less than y and z is greater than 1, or if x is not less than y and z is greater than zero. To obtain the algebraic meaning, you must rewrite the expression using relational operators. bpbonline all rights reserved 46 Programming in C++ Part I The logical AND operator (&&) and the logical OR operator (||) evaluate the truth or falseness of pairs of expressions. The AND operator returns TRUE only if both expressions are TRUE. The OR operator returns TRUE if either expression is TRUE. To test whether y is greater than x and less than z, you would write (x < y) && (y < z) 3.10.1 Hierarchy of Logical Operators The logical NOT (!) operator has a higher precedence than the others. The AND operator (&&) has higher precedence than the OR operator (||). Both the logical AND and OR operators have lower precedence than the relational and arithmetic operators. 3.10.2 Boolean Table for Logical Operator NOT The logical negation operator (!) takes only one operand. If the operand is TRUE, the result is FALSE; if the operand is FALSE, the result is TRUE. This is shown in Table 3.10. Table 3.10 Boolean Table for logical operator NOT Operator Operand Result ! false (0) 1 ! true (nonzero) 0 3.10.3 Boolean Table for Logical Operator AND Logical AND (&&) operator takes two operands. If both the operands are TRUE (non zero), the result is TRUE (non zero) otherwise FALSE (zero). This is shown in Table 3.11. Table 3.11 Boolean Table for logical operator AND (&&) Oprand1 Operator Operand2 Result false (0) && false (0) 0 true (nonzero) && false (0) 0 false (0) && true (nonzero) 0 true (nonzero) && true (nonzero) 1(nonzero) 3.10.4 Boolean Table for Logical Operator OR Logical OR operator (||) takes two operands. If both the operands are FALSE (zero) the result is FALSE (zero) otherwise TRUE (nonzero). This is shown in Table 3.12. The operands to the logical operators may be integers or floating point objects. The expression 1 && -5 results in 1 because both operands are nonzero. The same is true of the expression: 0.5 && -5 bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 47 Table 3.12 Boolean Table for logical operator OR (||) Oprand1 Operator Operand2 Result false (0) || false (0) 0 true (nonzero) || true (nonzero) 1 (nonzero) false (0) || true (nonzero) 1 (nonzero) true (nonzero) || true (nonzero) 1 (nonzero) Exa mp le 9 Given the following declarations: int j = 0, m = 1, n = -1; float x = 2.5, y = 0.0 Evaluate the following expressions: (a) j && m (b) j < m && n <m (c) m + n || !j (d) x * 5 && 5 || m / n (e) j <= 10 && x >= 1 && m (f) !x || !n || m + n (g) x * y < j + m || n (h) (x > y) + !j || n++ (i) (j || m) + (x || ++n) Solution (a) j && m is not true because the value of j = 0 and the value of m = 1. Hence the result is 0 (zero). (b) The expression j < m && n < m is equivalent to (j < m) && (n < m) because the hierarchy of relational operators is higher than that of logical operators. Substituting the values of the variables we get the result to be 1 (true). (c) The expression m + n || !j is equivalent to (m + n) || (!j). Substituting the values of the variables we get the result to be 1 (true). (d) The expression x * 5 && 5 || m / n is equivalent to ((x * 5) && 5) || (m / n). Substituting the values of the variables, we get the result to be 1 (true). (e) The expression j <= 10 && x >= 1 && m is equivalent to ((j <= 10) && (x >= 1) && m. Substituting the values of the variables, we get the result to be 1 (true). (f) The expression !x || !n || m + n is equivalent to ((!x) || (!n) || (m + n). Substituting the val- ues of the variables we get the result to be false (0). (g) The expression x * y < j + m || n is equivalent to ((x * y) < (j + m)) || n. Substituting the values of the variables, we get the result to be true (1). (h) The expression (x > y) + !j || n++ is equivalent to ((x > y) + (!j) || (n++). Substituting the values of the variables, we get the result to be true (1). Note here that n++ represents the postfix increment value of n. bpbonline all rights reserved 48 Programming in C++ Part I (i) The expression (j || m) + (x || ++n) is equivalent to (j || m) + (x || (++n)). Substituting the values of the variables, we get the result to be 2. Note here that ++n represents the prefix increment value of n. 3.11 CONDITIONAL OPERATOR (?) The conditional operator ? : takes three operands. The value of an expression using the conditional operator is the value of either its second or third operand, depending on the value of the first oper- and. This evaluation could be pseudo-coded as if c result value is r1 else result is r2 For example the statement: z = ((x < y) ? x : y); means if (x < Y) z = x else z = y; In the above statement, the first operand is the test condition. The second and third operands represent the final value of the expression. Only one of them is selected, depending on the value of the first operand. Table 3.13 summarizes the conditional operator. Table 3.13 Conditional operator Operator Symbol Form Result conditional ? : a ? b : c if a is nonzero result is b; otherwise result is c. 3.12 PRECEDENCE OF OPERATORS All operators have two important properties called precedence and associativity. Both properties affect how operands are attached to operators. Operators with higher precedence have their oper- ands bound, or grouped, to them before operators of lower precedence, regardless of the order in which they appear. For example, the multiplication operator has higher precedence than the addition operator, so the two expressions. 2 + 3 * 4 3 * 4 + 2 bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 49 both evaluate to 14 the operand 3 is grouped with the multiplication operator rather than the addition operator because the multiplication operator has a higher precedence. If there were no precedence rules, and the compiler grouped operands with operators in a left-to-right order, then the first expression: 2 + 3 * 4 would evaluate to 20 which is not correct. In the case where operators have the same precedence, associativity (sometimes called bind- ing) is used to determine the order in which operands are grouped with operators. Grouping occurs in either a right-to-left or left-to-right order, depending on the operator. Right-to-left associativity means that the compiler starts on the right of the expression and works towards left. Left-to-right associativity means that the compiler starts on the left of the expression and works towards right. For example, the plus and minus operators have the same precedence and are both left-to-right associative. For example, in the expression: a + b - c; The expression is evaluated as: add a to b, then subtract c The assignment operator, on the other hand, is right-associative. For example in the expression: a = b = c; The expression is evaluated as: assign c to b, then assign b to a Table 3.14 gives a summary of the precedence for various operators including their associativity. Table 3.14 Precedence for different operators and their associativity Class of Operators in Associativity Precedence Operator that class unary - + Highest multipli * / % Left-to-Right ^ cative | additive + - Left-to-Right | shift << >> Left-to-Right | relational < <= > >= Left-to-Right | equality == != Left-to-Right | logical AND && Left-to-Right | logical OR || Left-to-Right | conditional ? : Right-to-Left | assignment = += -= *= Right-to-Left | comma , Left-to-Right Lowest bpbonline all rights reserved 50 Programming in C++ Part I 3.13 EXPRESSIONS AND THEIR DEFINITION An expression consists of one or more operands and zero or more operators linked together to compute a value. For example: a + 2 is a legal expression that results in the sum of a and 2. The variable a is also an expression as is the constant 2, since they both represent value. There are four types of expressions: (a) Constant expressions (b) Integral expressions (c) Float expressions (d) Pointer expressions 3.13.1 Constant Expressions This type of expression contains only constant values. For example, the following are all constant expressions: 5 5 + 6 * 13 / 3.0 a 3.13.2 Integral Expressions These are expressions that, after all the automatic and explicit type conversions, produce a result that has one of the integer types. If j and k are integers, the following are all integral expressions: j j * k j / k + 3 k - a 3 + (int) 5.0 3.13.3 Float Expressions These are the expressions that, after all the automatic and explicit type conversions, produce a result that has one of the floating-point types. If x is a float or double, the following are floating- point expressions: x x + 3 x / y * 5 3.0 3.0 - 2 3 + (float) 4 bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 51 3.13.4 Pointer Expressions These are expressions that evaluate to an address value. These include expressions containing pointer variables, the "address of" operator (&), string literals, and array names. If p is a pointer and j is an int, the following are pointer expressions: p &j p + 1 "abc" 3.14 AUTOMATIC TYPE CONVERSIONS IN EXPRESSIONS When the compiler encounters an expression, it divides it into sub-expressions, where each sub- expression consists of one operator and one or more objects, called operands, that are bound to the operator. For example, the expression 3 / 4 + 2.5 contains three operators: , /, and +. The operand to is 3; there are two operands to /, 3 and 4; and there are two operands to +, 3 / 4 and 2.5. The minus operator is said to be a unary operator because it takes just one operand, whereas the division and addition operators are binary operators. Each operator has its own rules for oper- and type agreement, but most binary operators require both operands to have the same type. If the types differ, the compiler converts one of the operands to agree with the other one. To decide which operand to convert, the compiler resorts to the hierarchy of data types shown in Figure 3.6 and converts the "lower" type to the "higher" type. For example 1 + 2.5 involves two types, an int and a double. Before evaluating it, the compiler converts the int into a double because double is higher than int in the type hierarchy (see Figure 3.6). The conversion from an int to a double does not usually affect the result in any way. It is as if the expression were written 1.0 + 2.5 3.14.1 Rules for Automatic (Implicit) Conversions The rules for implicit conversions in expressions can be summarized as follows. (a) If a pair of operands contain a long double, the other value is converted to a long double. (b) Otherwise, if one of the operands is a double, the other is converted to a double. (c) Otherwise, if one of the operands is a float, the other is converted to a float. (d) Otherwise, if one of the operands is an unsigned long int, the other is converted to an unsigned long int. (e) Otherwise, if one of the operands is a long int, then the other is converted to a long int. (f) Otherwise, if one of the operands is an unsigned int, then the other is converted to an unsigned int. In general, most automatic conversions are invisible. They occur without any obvious effect. bpbonline all rights reserved 52 Programming in C++ Part I Figure 3.6 Hierarchy of operators 3.14.2 Mixing Integers There are four possible sizes of integers char, short, int, and long and they may be mixed freely in an expression. The compiler converts chars and shorts to ints before evaluating an expression. All smaller integer types are converted to int or unsigned int before an expression is evaluated. 3.14.3 Mixing Floating-point Values There are three types of floating-point values float, double, and long double (ANSI extension). There is no difficulty in mixing them in an expression. 3.14.4 Mixing Integers with Floating-point Values It is perfectly legal to mix integers and floating-point values in an expression, to assign a floating- point value to an integer variable, or assign an integer value to a floating-point variable. The sim- plest case is assignment of an integer to a floating-point variable. In this case, the integer value is implicitly converted to a floating-point type. If the floating-point type is capable of representing the integer, there is no change in value. If f is a double, the assignment f = 10; is executed as if it had been written: f = 10.0; long double double float unsigned long int unsigned int long int bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 53 This conversion is invisible. There are cases, however, where a floating-point type is not capable of exactly representing all integer values. Even though the range of floating-point values is generally greater than the range of integer values, the precision may not be as good for large numbers. In these instances, conversion of an integer to a floating-point value may result in a loss of precision. The most risky mixture of integer and floating-point values is the case where floating-point value is assigned to an integer variable. An equally serious situation occurs when the floating- point value cannot fit in an integer. For example, if j is an integer, the assignment statement: j = 999999999.88888 would cause an overflow condition which may halt program execution. As a general rule, it is a good idea to keep floating-point and integer values separate from one another unless you have a good reason for mixing them. 3.15 ASSIGNMENT STATEMENT The assign operator (=) causes the value of the right-hand operand to be written into the memory location of the left-hand operand. In addition, an assignment expression itself has a value, which is the same value that is assigned to the left-hand operand. The left-hand operand, sometimes called an lvalue, must refer to a memory location. The assign operator has right-to-left associativity, so the expression a = b = c = d = 1; is interpreted as (a = (b = (c = (d = 1)))); First the value 1 is assigned to d, then d is assigned to c, then c is assigned to b, and finally b is assigned to a. The value of the entire expression is 1. This is a convenient syntax for assigning the same value to more than one variable. Note, however, that each assignment may cause quiet con- versions, so int j; double f; f = j = 3.5; assigns the truncated value 3 to both f and j. On the other hand, j = f = 3.5; assigns 3.5 to f and 3 to j. 3.15.1 Arithmetic Assignment or Compound Operators The C++ language supports five additional assignment operators that combine assignment with each of the arithmetic operations. The operators are given in Table 3.15. The equivalences are shown in Figure 3.7. bpbonline all rights reserved 54 Programming in C++ Part I Figure 3.7 Arithmetic Assignment Operator Equivalences Table 3.15 Assignment Operators Operator Symbol Form Operation assign = a = b put the value of b into a add-assign += a +=b put the value of a+b into a subtract-assign -= a -=b put the value of a-b into a multiply-assign *= a * = b put the value of a*b into a divide-assign /= a /=b put the value of a/b into a remainder-assign %= a %=b put the value of a%b into a For example, the expression j = j * 5; can be written as j *= 5; One of the main reasons for using the arithmetic assignment operators is to avoid spelling mistakes and make code more readable. For example, the expression op_big_x_dimension = op_big_x_dimension * 2; can be written as op_big_x_dimension *= 2; The second version is easier to read and to write and contains fewer opportunities for spelling errors. The assign operators have relatively low precedence. This leads to interesting consequences. For example, the following two expressions are not the same: j = j * 3 + 4; j *= 3 + 4; The addition operator has higher precedence than the assign operator, and the multiplication operator has higher precedence than the addition operator, so the two expressions are interpreted as follows: a + b = a = a b + a = _ b a = a _ b a = * b a = a * b a = / b a = a / b a = % b a = a % b is the same as bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 55 Expression1 Expression2 j = j * 3 + 4 j *= 3 + 4 or or j = ((j * 3) + 4) j *= (3 + 4) or j = (j * (3 + 4)) Exa mp le 10 Given the following declarations: int m = 3, n = 4; float x = 2.5, y = 1.0 Evaluate the following expressions: (a) m += n + x y (b) m /= x * n + y (c) n %= y + m (d) x += y = m Solution (a) The expression m += n + x - y is equivalent to m = (m + ((n + x) - y)). Substituting the values of the variables, we get the answer as 8. (b) The expression m /= x * n + y is equivalent to m = (m / ((x * n) + y)). Substituting the values of the variables we get the result to be 0. (c) The expression n %= y + m is equivalent to n = (n % (y+m)). Substituting the values of the variables we get the result to be 0. (d) The expression x += y = m is equivalent to x = (x+ (y = (y m))). Substituting the values of the variables, we get the result to be 0.5. 3.15.2 General Form In C++, one use of the assignment statement is to store in a variable the result of a computation. The assignment statement: kms = kms_per_mile * miles; assigns a value to the variable kms. In this case, kms is being assigned the result of multiplying (* means multiply) the value of kms_per_mile by the value of miles. Valid information must be stored in miles before the assignment statement is executed. The symbol = is the assignment operator in C++ and should be read and understood as "becomes", or "gets" or "takes the value of" instead of "equals" since it is not equivalent to the "equal sign" used in mathematics. In mathe- matics, this symbol states a relationship between two values, but in C++ it represents an action to be carried out by the computer. For example, in C++, one can write the assignment statements of the form: sum = sum + item; bpbonline all rights reserved 56 Programming in C++ Part I where the variable sum is used on both sides of the assignment operator. This is not an alge- braic equation (which is meaningless in algebra), but it is a common practice in programming. Figure 3.8 Effect of sum = sum + item The statement instructs the computer to add the current value of the variable sum to the value of item, the result is saved temporarily and then stored back into sum. The previous value of sum is destroyed in the process. However the value of sum is unchanged. The effect of the above assign- ment statement is shown in Figure 3.8. 3.15.3 Variable Initialization A simple definition of a variable specifies the type and identifier of a variable. It does not provide an initial or first value. A variable without a first value is spoken of as un-initialized. An un- initialized variable is not without a value. Its first value is to be undefined. This is because the memory storage allocated for the variable is not swept clean. Whatever was stored there previously remains. This value may vary from one execution of a program to another. An initial or first value may be specified in the definition of a variable. A variable with a declared first value is spoken of as an initialized variable. C++ supports two forms of variable ini- tialization. The first form is an explicit syntax using an assignment operator. For example: int ival = 1024; In the above assignment, the initial value of the integer variable ival is 1024. The other form of initialization is an implicit form in which the first or initial value is placed within parentheses as shown below: int ival(1024); Some of the examples of initialized variables include the following: 90 sum 10 item 100 sum + Before assignment After assignment bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 57 #include <math.h> double price = 109.99, discount = 0.15; double sale_price(price * discount); int val = get_value(); unsigned abs_val = abs(val); In the above program, abs(), a predefined function stored in the math library, returns the abso- lute value of its argument; get_value() is a user-defined function that returns a random integer value. A variable may also be initialized with an arbitrarily complex expression. 3.15.4 Type Compatibility C++ is a strongly typed language. Both the argument list and the return type of every function call are type checked during compilation. If there is a type mismatch between an actual type and a type declared in the function prototype, an implicit conversion will be applied if possible. If an implicit conversion is not possible or if the number of arguments is incorrect, a compiler run-time error is issued. The function prototype provides the compiler with the type information necessary for it to perform compiler-time type checking. 3.15.5 Type Cast Operator In addition to automatic conversion, C++ also provides an explicit or distinct type conversion operation called a cast. Suppose you are calculating the average marks using the formula total_marks / num_students where you have declared both the variables total_marks and num_students to be of the type int. Then the division of the two integers will be an integer. But you are interested to know the frac- tional part of the average also. In this case, you need to use explicit type conversion operator. Thus placing the name of the desired type in the parentheses immediately before the value to be converted causes the value to be changed to the desired data format before it is used in the com- putation. For example, if you have declared the variable average to be of the type double, then writing the assignment expression as: average = (double)total_marks / (dou- ble)num_students would cause the fractional part of the average to be preserved. This type of explicit conversion is very important in situations where the fractional part is to be preserved. When a cast operation is applied to a variable, the conversion carried out determines the value of the expression, but the conversion does not change what is stored in the variable. For example, if x is a type int variable whose value is 5, the following statements will first print 5.00 and then print 5. The value of the expression (double)x is 5.00, but the value stored in x is still the integer 5. bpbonline all rights reserved 58 Programming in C++ Part I Statement Output cout << (double)x << endl; 5.00 cout << x; 5 TEST PAPER Time: 3 Hrs Max Marks: 100 Answer the following questions. 1. Evaluate the following expressions as C++ would: (a) 8 * 9 + 2 (b) 6 * 3/4 (c) 3 / 4 * 6 (d) 6.0 * 3 / 4 (e) 15 % 4 2. Write a program in C++ that asks you for your height in integer centimeter and then converts your height to feet and inches. 3. Write down the declaration statements for the following: (a) Upper, lower, and middle as integers. (b) max, min as floating point numbers. (c) eligible, ch as character type variables. 4. State the rules for the following: (a) In naming an identifier in C++. (b) For valid comment statements in C++. 5. Pick the incorrect floating point constants from the following list. (a) 40,900.65 (b) 46 E+3 (c) 486.+6 (d) 1/2.2 (e) 465. 6. Pick the incorrect identifiers from the following list. (a) constant (b) variable (c) double (d) int result (e) roll.no bpbonline all rights reserved Part I Data Types, Operators and Expressions in C++ 59 7. Define the backslash character constants. Describe any three backslash character con- stants. 8. Distinguish between the following: (a) Built-in and derived data type (b) Float and double data type (c) Constant and variable (d) Integer and character constant 9. Write short notes. (a) Choosing data type in a C++ program. (b) Types of integers and their declaration. 10. Write the logical statements for the following: (a) basic_pay is more than 2200 for all employees whose category is T (b) stock below 100 for all items whose item_no is 100 and in the shop A. 11. Explain the following type of operators each with one example and list the hierarchy of operations. (a) Arithmetic operators (b) Logical operators 12. Explain the difference between prefix and postfix increment and how does it affect the result of an expression. 13. What is the result after the execution of the following program segment. a = 7; b = ++a + 5; c = b-- + 10; 14. Evaluate following expressions independent of each other. Assume that i, j, k are inte- gers with values 3, 4 and 2 respectively. (a) i++ - j-- (b) i-- % j++ (c) j++ / i-- (d) k++ * --i (e) i - 1 % j + 1 15. Write C++ expressions corresponding to the following. Assume all quantities are of the type integer. (a) (b) (c) (ax + b) (ax b) (2x + 3y) (x 3 6) (4a + 3) (2y 2 + 2z + 2) bpbonline all rights reserved 60 Programming in C++ Part I (d) 16. What is the final value of x in the following program segment: float x; int i; x= 2.5; x = (x + 0.04)*10; x 5 + 10x 4 + 8x 3 + 4x + 2 bpbonline all rights reserved