Home Previous Next

CSC100AA :: Lecture Note :: Week 03
{GDT::Bits:: Time  |  Weather  |  Populations  |  Special Dates}

Overview

Assignment(s):

Code: PrimitiveTypes.cpp | Constants.cpp | ArithOps.cpp
arithmetic.cpp | years.cpp | years2.cpp | years3.cpp | Expressions0.cpp | Expressions1.cpp | if.cpp

### Expressions (operands and operators)

An expression is a combination of one or more operands and zero or more operators. Expressions are evaluated and "express" a value. Sometimes there are "side-effects" when an expression gets evaluated.

An operand is either a constant, a variable, or a non-void function/method.

An operator determines how operands are evaluated. There are numerous categories of operators: assignment, arithmetic, relational, logical, bitwise, and others. Operators are either unary (operate on one operand), binary (operate on two operands), or ternary (operate on three operands).

The following are some examples of expressions.

```   i = 5

= is the assignment operator
variable i and constant 5 are operands
= in a binary operator
i = 5 evaluates to 5 and as a side-effect
the value of i gets set to 5

2 * j

* is the multiply operator
constant 2 and variable j are operands
* is a binary operator
2 * j evaluates to 2 times the value
stored in variable j

i++

++ is the increment operator
variable i is the operand
++ is a unary operator
i++ evaluates to the value stored in variable i
and as a side-effect the value of i gets
increased by one

-42

- is the unary minus operator
42 is a constant
-42 evaluates to the opposite of 42

-x

- is the unary minus operator
x is a variable
-x evaluates to the opposite of the value
that is stored in x
```

### Arithmetic Operators

All arithmetic operators are binary operators (i.e. they take two operands).

```   *     multiply
/     divide
%     modulus (remainder)
-     substraction
```

Important points.

• Divide by 0 is not defined and it causes your program to abort (e.g. ` 10 / 0`).

• Dividing one integer by another (integer division) results in truncation (i.e. the fractional part, if any, is lost)
example: `8 / 3` equals `2`.

• The modulus operator `%` results in the remainder when one integer is divided by another
example: `8 % 3` equals `2` (note: both operands must be integral types).

• `* / %` have higher precedence than `+ -` and associativity is left-to-right .

• Precedence and associativity can be altered by using parenthesis

```   a + b * c       binds as  a + (b * c)
(a + b) * c     ()s used to alter binding
```

### About the `cin` Object

In order to use the C++ Streams I/O, the iostream header file must be included.

Upon program startup, the cin object of class istream is created (instantiated).

Input from the keyboard (or the standard input stream) is performed using the cin object, and the right-shift bit-wise operator >> in combinations such as:

```   cin >> someVariable;
```

Multiple values can be input by executing the following.

```   cin >> variable1 >> variable2 >> variable3 >> ...;
```

Only one variable is allowed after each >>. The >> points in the direction of the data flow from cin (the standard input) and is referred to as the extraction operator.

cin provides support for all of the primitive data types.

cin skips whitespace (where whitespace is defined by a call to isspace() see ctype.h).

```   char c;
cin >> c;  //reads the first non-whitespace character into c
```

cin.width(int) can be used to restrict the number of characters read (useful when reading strings).

```   char a[16];
cin.width(sizeof(a));
cin >> a; //read at most 15 characters into a and add terminating null
```

The input stream has a state associated with it. They are:

• good() -- previous input operation worked
• eof() -- previous input operation worked; next input operation will fail
• fail() -- next operation will fail
• bad() -- stream is corrupted

Applying an input operation to a string that is not in the good() state is a null operation.

The insertion operator is intended for formatted input; reading objects of an expected type and format. The get() and getline() functions offer alternative ways to get input. These functions treat whitespace characters exactly like other characters.

get() leaves the terminator on the input stream; whereas, getline() doesn't.

```   char a[32];
cin.getline(a, sizeof(a));
// reads at most 31 characters into array  a
// appending a null character to the end
//
// the standard input stream is read until
// 31 characters read or a newline is encountered
```

ignore() reads characters but it doesn't store them anywhere. By default, ignore() reads one character and the terminator is end-of-file.

clear() can be used to clear the input flags.

```   int i;
cout << "Enter an integer: " << flush;
cin >> i;
if (cin.fail()) {
cin.clear();
cout << "Enter an integer: " << flush;
cin >> i;
if (cin.fail())
cerr << "forget it...";
}
```

### Precedence and Associativity of Operators

Whenever you have an EXPR that contains multiple operators, then you must be aware of operator precedence and associativity.

Precedence and associativity are used to "bind" operators with operands.

Every C/C++ book that I have reviewed contains a precedence and associativity chart. Here is a chart that displays the precedence and associativity of some of the operators we learn first.

Unary `+` and `-` have higher precedence than the binary forms.
Operators Associativity
`()   +   -   (type)   sizeof` right to left
`*   /   %` left to right
`+   -` left to right
`=` right to left

Precedence determines the order in which operands are bound to operators. Operators on the same line have the same precedence; rows are in order of decreasing precedence.

Examples:

• The `sizeof` operator is high precedence, whereas the assignment operator `=` has low precedence.
• The multiple operator `*` is a medium precedence operator that has slightly higher precedence that the addition operator `+`.

If an EXPR contains two operators of equal precedence, then associativity is used to bind operators and operands.

An example using the EXPR:    `a + b - c`

```   The + and - operators have equal precedence; therefore, associativity
is used.  They associate left-to-right and we end up with with the
binding  (a + b) - c
```

Precedence and associativity can be altered by using parenthesis.

```   Example expression:  a * b / c

* and / have equal precedence and they associate left-to-right;
therefore, we get the following binding:  (a * b) / c

If we want the operand  b  to be attached to the operand  c,
then we would parenthesis and code the EXPR:  a * (b / c).
```

Use parenthesis if you are ever in doubt about the precedence and associativity rules. [Note: it is possible to overuse ()'s.]

GDT::Resource::C++:: Precedence chart that includes all operators.

### Relational Operators

Relational operators are used to compare the value of two expressions (EXPRs).

  ==    != expr1 == expr2 equals expr1 != expr2 not equals expr1 > expr2 greater than expr1 < expr2 less than expr1 >= expr2 greater than or equal to expr1 <= expr2 less than or equal to

The operators that are made up of two characters cannot have any whitespace between. For example: `= =` would be treated as two separate assignment operators and would result in a compile-time error. `==` is used to test two operands for equality.

It is easy to sometimes use the equality operator in lieu of the assignment operator and vice versa. You must remember the following.

```   ==   is the relational equality operator; it compares two operands
for equality and evaluates to either 0 (false) or 1 (true)

=    is the assignment operator; it copies the value of the operand
on the right-hand side to the operand on the left-hand side; the
EXPR evaluates to the value that was copied (i.e. assigned)
```

Examples.

```   int thisCourse = 100;   /* 100 assigned to thisCourse */
int nextCourse = 205;   /* 205 assigned to nextCourse */

thisCourse == nextCourse   /* evaluates to 0 (false) */
thisCourse != nextCourse   /* evaluates to 1 (true) */
thisCourse > nextCourse    /* evaluates to 0 */
thisCourse < nextCourse    /* evaluates to 1 */
thisCourse >= nextCourse   /* evaluates to 0 */
thisCourse <= nextCourse   /* evaluates to 1 */
```

GDT::C++::Code:: RelationalOps.cpp

### The `if` Statement and `else` Clause

The `if` is a selection control statement. It is a keyword of the language. It has the following syntax.

```   if (EXPR)
statement';
statement'';

If  EXPR  evaluates to true (i.e. not zero), then  statement'  is
executed followed by statement''; otherwise,  statement'  is skipped
and the flow control of the program jumps to  statement''.

if (netWorth > 1000000)
cout << "you are rich (at least money wise)";
netWorth = netWorth * 2;   //let us double our net worth
```

Typically, there is no semicolon after the `if`. If there is, then the body of the `if` is simply a `NULL` (empty) statement. In many cases, this is a defect with your program (i.e. it is done by accident, not design).

```   if (netWorth < 0)
;  //do nothing...
```

If more than one statement needs to be executed when an `if` EXPR is true, then a compound statement. should be used. A compound statement is a collection of zero or more statements enclosed in braces `{}`.

Compound statements are terminated by the closing brace `}` -- not a semicolon.

```   if (EXPR) {
statement';
statement'';
}                //note that there is no semicolon
statement''';

If EXPR evaluates to true, then both statement' and statement''
are executed followed by statement'''; otherwise, statement' and
statement'' are skipped and the flow control of the program jumps
to statement'''.

isSuperStar = false;
bonus = 0;

...

if (battingAvg > 300) {
isSuperStar = true;
bonus = 10000;
}
number = 55;
```

Every `if` statement can have a corresponding `else` clause which is executed whenever the `if` is false (i.e. 0). Syntax.

```   if (EXPR)
statement';
else
statement'';
statement''';

If EXPR is true, then statement' is executed, the else clause is
skipped and the flow control of the program jumps to statement''';
otherwise, statement' is skipped, statement'' is executed and
the flow control of the program jumps to statement'''.

if (netWorth > 1000000)
cout << "you are rich (with respect to money)";
else
cout << "you are rich in other ways";
```

An `else` clause cannot be used without a corresponding `if` statement. Example.

```   int i = 10;

...

else   //not allowed -- there is no if statement
cout << "this is not legal\n";
```

The body of an `if` construct can be any type of statement. Examples.

```   if (EXPR) EXPR;      //the body is an expression statement
if (EXPR) return EXIT_SUCCESS;  //body is a return statement
if (EXPR) ;          //body is a null statement
if (EXPR) { }        //body is an empty compound statement
if (EXPR) if (EXPR)  //body is another if statement
```

An `if` statement containing another `if` is referred to as a nested if. There is no limit to the amount of nesting that can occur. Examples.

```   if (EXPR)
if (EXPR')
statement';
statement'';

If EXPR is true, then EXPR' is evaluated; otherwise,
flow control jumps to statement''.  If EXPR' is evaluated
and it evaluates to true, then statement' is executed;
otherwise, flow control jumps to statement''.

if (age >= 100)
if (gender == 'M')
cout << "old man look at my life";

if (age >= 100)
if (gender == 'M')
if (iq > 120)
cout << "smart old man look at my life";
cout << endl;
```

When using `if` statements, it is a good programming practice to use indentation to aid readability. The body of an `if` statement should be indented three or four spaces.

In all cases, each `if` can have a corresponding `else` clause.

```   if (EXPR)
if (EXPR')
statement';
else
statement'';
statement''';

The top-most  if  does not have an  else  clause, whereas the
inner-most  if  does.  If EXPR evaluates to false, then
flow control jumps to statement'''; otherwise, EXPR' is
evaluated.  If it evaluates to true, then statement' is
executed; otherwise, statement' is skipped and statement'' is
evaluated.  Regardless of which statement is executed,
flow control jumps to statement'''.
```

Caution is required to make sure that `else` clauses match up to the correct `if` construct.

```   if (age > 100)
if (gender == 'M')
cout << "you are an old man";
else
cout << "you are a young person";

If age is greater than 100, then  if (gender == 'M')  will
be executed.  If the gender is 'M', then the correct statement
will print, but if the gender is not 'M', then the
"you are a young person" message will print.

To correct this problem, a compound statement is needed to
"tie" the  else  clause with the outer-most  if  statement.

if (age > 100) {
if (gender == 'M')
cout << "you are an old man";
} else
cout << "you are a young person";

Now if age > 100, then the body of the  if  is executed;
otherwise, flow control jumps to the  else  clause.
```

GDT::C++::Code:: Age0.cpp and Age1.cpp and Age2.cpp

Home Previous Next