An Object-oriented Stack

Chapter 6 - Working with Data

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Operators
C has many operators not found in other languages. These include bitwise operators, increment and decrement operators, conditional operators, the comma operator, and assignment and compound assignment operators.
Bitwise Operators
Bitwise operators treat variables as combinations of bits rather than as numbers. They are useful in accessing the individual bits in memory, such as the screen memory for a graphics display. Bitwise operators can operate only on integral data types, not on floating-point numbers. Three bitwise operators act just like the logical operators, but on each bit in an integer. These are AND (&), OR (|), and XOR (^). An additional operator is the one’s complement (~), which simply inverts each bit.
AND
The bitwise AND operation compares two bits; if both bits are a 1, the result is a 1, as shown here:
Bit 0
Bit 1
Result
0
0
0
0
1
0
1
0
0
1
1
1
Note that this is different from binary addition, where the comparison of two 1 bits would result in a sum flag set to zero and the carry flag set to 1. Very often, the AND operation is used to select out, or mask, certain bit positions.
OR
The bitwise OR operation compares two bits and generates a 1 result if either or both bits are a 1, as shown here:
Bit 0
Bit 1
Result
0
0
0
0
1
1
1
0
1
1
1
1
The OR operation is useful for setting specified bit positions.
XOR
The EXCLUSIVE OR operation compares two bits and returns a result of 1 when and only when the two bits are complementary, as shown here:
Bit 0
Bit 1
Result
0
0
0
0
1
1
1
0
1
1
1
0
This logical operation can be very useful when it is necessary to complement specified bit positions, as in the case of computer graphics applications.
Following is an example of using these operators with the hexadecimal and octal representation of constants. The bit values are shown for comparison.
0xF1      &  0x35           yields 0x31 (hexadecimal)
0361      &  0065           yields 061 (octal)
11110011  &  00110101       yields 00110001 (bitwise)

0xF1      |  0x35           yields 0xF5 (hexadecimal)
0361      |  0065           yields 0365 (octal)
11110011  |  00110101       yields 11110111 (bitwise)

0xF1      ^  0x35           yields 0xC4 (hexadecimal)
0361      ^  0065           yields 0304 (octal)
11110011  ^  00110101       yields 00000000 11000110 (bitwise)

~0xF1                       yields 0xFF0E (hexadecimal)
~0361                       yields 0177416 (octal)
~11110011                   yields 11111111 00001100 (bitwise)
Left Shift and Right Shift
C incorporates two shift operators, the left shift (<<) and the right shift (>>). The left shift moves the bits to the left and sets the rightmost (least significant) bit to zero. The leftmost (most significant) bit shifted out is thrown away.
In terms of unsigned integers, shifting the number one position to the left and filling the LSB with a zero doubles the number’s value. The following C++ code segment demonstrates how this would be coded:
unsigned int value1 = 65;
value1 <<= 1;
cout << value1;
If you were to examine value1‘s lower byte, you would see the following bit changes performed.
<< 0100 0001 ( 65 decimal)
—————————————
  1000 0010 (130 decimal)
The right shift operator moves bits to the right. The lower-order bits shifted out are thrown away. Halving an unsigned integer is as simple as shifting the bits one position to the right, filling the MSB position with a zero. A C-coded example would look very similar to the preceding example except for the compound operator assignment statement (discussed later in the chapter) and the output statement:
unsigned int value1 = 10;
value1 >>= 1;
printf(“%d”,value1);
Examining just the lower byte of the variable value1 would reveal the following bit changes:
>> 0000 1010 (10 decimal)
————————————-
  0000 0101 ( 5 decimal)
Increment and Decrement
Adding 1 to or subtracting 1 from a number is so common in programs that C has a special set of operators to do this. They are the increment (++) and decrement (- -) operators. The two characters must be placed next to each other without any white space. They can be applied only to variables, not to constants. Instead of coding as follows:
value1 + 1;
you can write
value1++;
or
++value1;
When these two operators are the sole operators in an expression, you will not have to worry about the difference between the different syntaxes. A for loop very often uses this type of increment for the loop control variable:
sum = 0;
for(i = 1; i <= 20; i++)
 sum = sum + i;
A decrement loop would be coded as
sum = 0;
for(i = 20; i >= 1; i—)
 sum = sum + i;
If you use these operators in complex expressions, you have to consider when the increment or decrement actually takes place.
The postfix increment, for example i++, uses the value of the variable in the expression first and then increments its value. However, the prefix increment—for example, ++I increments the value of the variable first and then uses the value in the expression. Assume the following data declarations:
int i=3,j,k=0;
See if you can figure out what happens in each of the following statements. For simplicity, for each statement assume the original initialized values of the variables:
k = ++i;                 // i = 4, k = 4
k = i++;                 // i = 4, k = 3
k = —i;                 // i = 2, k = 2
k = i—;                 // i = 2, k = 3
i = j = k—;             // i = 0, j = 0, k = -1
While the subtleties of these two different operations may currently elude you, they are included in the C language because of specific situations that cannot be eloquently handled in any other way. In Chapter 10, you will look at a program that uses array indexes that need to be manipulated by using the initially confusing prefix syntax.
Arithmetic Operators
The C language naturally incorporates the standard set of arithmetic operators for addition (+), subtraction (-), multiplication (*), division (/), and modulus (%). The first four are straightforward and need no amplification. However, an example of the modulus operator will help you understand its usage and syntax:
int a=3,b=8,c=0,d;

d = b % a;              // returns 2
d = a % b;              // returns 3

d = b % c;              // returns an error message
The modulus operator returns the remainder of integer division. The last assignment statement attempts to divide 8 by zero, resulting in an error message.
Assignment Operator
The assignment operator in C is different than the assignment statement in other languages. Assignment is performed by an assignment operator rather than an assignment statement. Like other C operators, the result of an assignment operator is a value that is assigned. An expression with an assignment operator can be used in a large expression such as this:
8 * (value2 = 5);
Here, value2 is first assigned the value 5. This is multiplied by the 8, with value1 receiving a final value of 40.
Overuse of the assignment operator can rapidly lead to unmanageable expressions. There are two places in which this feature is normally applied. First, it can be used to set several variables to a particular value, as in the following:
value1 = value2 = value3 = 0;
The second use is most often seen in the condition of a while loop, such as the following:
while ((c = getchar( )) != EOF) {
 .
 .
 .
}
This assigns the value that getchar( ) returned to c and then tests the value against EOF. If it is EOF, the loop is not executed. The parentheses are necessary because the assignment operator has a lower precedence than the nonequality operator. Otherwise, the line would be interpreted as
c = (getchar( ) != EOF)
The variable c would be assigned a value of 1 (TRUE) each time getchar( ) returned EOF.
Compound Assignment Operators
The C language also incorporates an enhancement to the assignment statement used by other languages. This additional set of assignment operators allows for a more concise way of expressing certain computations. The following code segment shows the standard assignment syntax applicable in many high-level languages:
irow_index = irow_index + irow_increment;
ddepth = ddepth - d1_fathom;
fcalculate_tax = fcalculate_tax
* 1.07;
fyards = fyards / ifeet_convert;
C’s compound assignment statements would look like this:
irow_index += irow_increment;
ddepth -= d1_fathom;
fcalculate_tax
*= 1.07;
fyards /= ifeet_convert;
If you look closely at these two code segments, you will quickly see the required syntax. Using a C compound assignment operator requires you to remove the redundant variable reference from the right-hand side of the assignment operator and place the operation to be performed immediately before the =. The bottom of Table 6-4 lists all of the compound assignment operators. Other parts of this table are discussed in the section “Understanding Operator Precedence Levels” later in this chapter.
Table 6-4: C/C++ Operator Precedence Levels (from Highest to Lowest)
Symbol
Name or Meaning
Associates from
++
Post-increment
Left to right
--
Post-decrement
( )
Function call
[ ]
Array element
->
Pointer to structure member
.
Structure or union member
++
Pre-increment
Right to left
--
Pre-decrement
!
Logical NOT
~
Bitwise NOT
-
Unary minus
+
Unary plus
&
Address
*
Indirection
sizeof
Size in bytes
new
Allocate program memory
delete
Deallocate program memory
(type)
type cast [for example, (int) i]
.*
Pointer to member (objects)
Left to right
->*
Pointer to member (pointers)
*
Multiply
Left to right
/
Divide
%
Remainder
+
Add
Left to right
-
Subtract
<<
Left shift
Left to right
>>
Right shift
<
Less than
Left to right
<=
Less than or equal to
>
Greater than
>=
Greater than or equal to
==
Equal
Left to right
!=
Not equal
&
Bitwise AND
Left to right
^
Bitwise EXCLUSIVE OR
Left to right
|
Bitwise OR
Left to right
&&
Logical AND
Left to right
||
Logical OR
Left to right
? :
Conditional
Right to left
=
Assignment
Right to left
*=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
Compound assignment
,
Comma
Left to right
Relational and Logical Operators
All relational operators are used to establish a relationship between the values of the operands. They always produce a value of !0 if the relationship evaluates to TRUE or a 0 value if the relationship evaluates to FALSE. Following is a list of the C and C++ relational operators:
Operator
Meaning
==
Equality (not assignment)
!=
Not equal
>
Greater than
<
Greater than or equal
<=
Less than or equal
The logical operators AND (&&), OR (||), and NOT (!) produce a TRUE (!0) or FALSE (zero) based on the logical relationship of their arguments. The simplest way to remember how the logical AND && works is to say that an ANDed expression will only return a TRUE (!0) when both arguments are TRUE (!0). The logical OR || operation in turn will only return a FALSE (zero) when both arguments are FALSE (zero). The logical NOT ! simply inverts the value. Following is a list of the C and C++ logical operators:
Operator
Meaning
!
NOT
&&
AND
||
OR
Have some fun with the following C program as you test the various combinations of relational and logical operators. See if you can predict the results ahead of time.
/*
*   oprs.c
*   A C program demonstrating some of the subtleties of
*   logical and relational operators.
*   Copyright (c) William H. Murray and Chris H. Pappas, 1998
*/

#include <stdio.h>

int main( )
{
 float foperand1, foperand2;

 printf(“\nEnter foperand1 and foperand2: ” );
 scanf(“%f%f”,&foperand1,&foperand2);

 printf(“\n  foperand1  > foperand2 is %d”,
            (foperand1  > foperand2));
 printf(“\n  foperand1  < foperand2 is %d”,
            (foperand1  < foperand2));
 printf(“\n  foperand1 >= foperand2 is %d”,
            (foperand1 >= foperand2));
 printf(“\n  foperand1 <= foperand2 is %d”,
            (foperand1 <= foperand2));
 printf(“\n  foperand1 == foperand2 is %d”,
            (foperand1 == foperand2));
 printf(“\n  foperand1 != foperand2 is %d”,
            (foperand1 != foperand2));
 printf(“\n  foperand1 && foperand1 is %d”,
            (foperand1 && foperand2));
 printf(“\n  foperand1 || foperand2 is %d”,
            (foperand1 || foperand2));

 return(0);
}
You may be surprised at some of the results obtained for some of the logical comparisons. Remember, there is a very strict comparison that occurs for both data types float and double when values of these types are compared with zero—a number that is very slightly different from another number is still not equal. Also, a number that is just slightly above or below zero is still TRUE (!0).
The C++ equivalent of the program just examined follows:
//
//  oprs.cpp
//  A C++ program demonstrating some of the subtleties of
//  logical and relational operators.
//  Copyright (c) William H. Murray and Chris H. Pappas, 1998
//

#include <iostream.h>

int main( )
{
 float foperand1, foperand2;

 cout << “\nEnter foperand1 and foperand2: ”;
 cin >> foperand1 >> foperand2;
 cout << “\n”;
 cout << “  foperand1  > foperand2 is ”
      <<   (foperand1  > foperand2) << “\n”;
 cout << “  foperand1  < foperand2 is ”
      <<   (foperand1  < foperand2) << “\n”;
 cout << “  foperand1 >= foperand2 is ”
      <<   (foperand1 >= foperand2) << “\n”;
 cout << “  foperand1 <= foperand2 is ”
      <<   (foperand1 <= foperand2) << “\n”;
 cout << “  foperand1 == foperand2 is ”
      <<   (foperand1 == foperand2) << “\n”;
 cout << “  foperand1 != foperand2 is ”
      <<   (foperand1 != foperand2) << “\n”;
 cout << “  foperand1 && foperand1 is ”
      <<   (foperand1 && foperand2) << “\n”;
 cout << “  foperand1 || foperand2 is ”
      <<   (foperand1 || foperand2) << “\n”;

 return(0);
}
Conditional Operator
You can use the conditional operator (?:) in normal coding, but its main use is for creating macros. The operator has the syntax
condition ? true_expression : false-expression
If the condition is TRUE, the value of the conditional expression is true-expression. Otherwise, it is the value of false-expression. For example, look at the following statement:
if(‘A’ <= c && c <= ‘Z’)
 printf(“%c”,’a’ + c - ‘A’);
else
 printf(“%c”,c);
You could rewrite the statement using the conditional operator:
printf(“%c”,(‘A’ <= c && c <= ‘Z’) ? (‘a’ + c - ‘A’) : c );
Both statements will make certain that the character printed, “c,” is always lowercase.
Comma Operator
The comma operator (,) evaluates two expressions where the syntax allows only one. The value of the comma operator is the value of the right-hand expression. The format for the expression is
left-expression, right-expression
One place where the comma operator commonly appears is in a for loop, where more than one variable is being iterated. For example:
for(min=0,max=length-1; min < max; min++,max—) {
 .
 .
 .
}

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net