Tokens, Expression and
Control Structures
Structure of the Unit:
3.0 Objective
3.1 Introduction
3.2 Tokens
3.3 Keywords
3.4 Identifiers
and Constants
3.5 Basic Data
Types
3.6 User-Def1ned
Data Types
3.7 Derived Data
Types
3.8 Symbolic
Constants
3.9 Type
Compatibility
3.10 Declaration of Variables
3.11 Dynamic Initialization of Variables
3.12 Reference Variables
3.13 Operators in C+ +
3.14 Manipulators
3.15 Type Cast Operator
3.16 Expressions and Their Types
3.17 Operator precedence
3.18 Control Structures
3.19 Summary
3.20 Self Assessment Questions
3.0 Objective
After studying this unit you
will be able :
-
To understand the token and keywords in C++
-
To understand identifiers, constant and declaration of
variables
-
To understand basic data types and user defined data
type of C++
-
To understand operators and their precedence in C++
-
To understand the control structures
3.1 Introduction
As we know C++
is a superset of C and therefore most constructs of C are legal in C++. But
there are some exceptions and additions. In this unit, we shall discuss these
exceptions and additions in C++.
3.2 Tokens
As we know, the smallest
individual units in a program are known as tokens. C++ has the following
tokens:
•
Keywords
•
Identifiers
•
Constants
•
Strings
•
Operators
C++ program is
written using these tokens, white spaces, and the syntax of the language. Most of the C++ tokens are basically similar
to the C tokens with the exception of some additions and minor modifications.
3.3 Keywords
The keywords
implement specific C++ language features. They are explicitly reserved
identifiers and cannot be used as names for the program variables or other
user-defined program elements.
Table 3.1 gives
the complete set of C++ keywords. Many of them are common to both C and C++.
The ANSI C keywords are shown in boldface. Additional keywords have been added
to the ANSI C keywords in order to enhance its features and make it an
object-oriented language. ANSI C++ standards committee has added some more
keywords to make the language more versatile. These are shown separately.
3.4 Identifiers and Constants
Identifiers refer to the names of variables, functions,
arrays, classes, etc. created by the programmer. They are the fundamental
requirement of any language. Each language has its own rules for naming these
identifiers. The following rules are common to both C and C++:
*
Only alphabetic characters, digits and underscores are
permitted.
*
The name cannot start with a digit.
*
Uppercase and lowercase letters are distinct.
*
A declared keyword cannot be used as a variable name.
asm
|
double
|
new
|
switch
|
||||||
auto
|
else
|
operator
|
template
|
||||||
break
|
enum
|
private
|
this
|
||||||
case
|
extern
|
protected
|
throw
|
||||||
catch
|
float
|
public
|
try
|
||||||
char
|
for
|
register
|
typedef
|
||||||
class
|
friend
|
return
|
union
|
||||||
const
|
goto
|
short
|
unsigned
|
||||||
continue
|
if
|
signed
|
virtual
|
||||||
default
|
inline
|
sizeof
|
void
|
||||||
delete
|
int
|
static
|
volatile
|
||||||
do
|
long
|
struct
|
while
|
||||||
|
|
Added by ANSI C++
|
|
||||||
bool
|
export
|
reinterpret_cast
|
typename
|
||||||
const_cast
|
false
|
static_cast
|
using
|
||||||
dynamic_cast
|
mutable
|
true
|
wchar_t
|
||||||
explicit
|
namespace
|
typeid
|
|
||||||
Table 3.1 C++ keywords
A major
difference between C and C++ is the limit on the length of a name. While ANSI C
recognizes only the first 32 characters in a name, ANSI C++ places no limit on
its length and, therefore, all the characters in a name are significant.
Care should be
exercised while naming a variable which is being shared by more than one file
containing C and C++ programs. Some operating systems impose a restriction on
the length of such a variable name.
Constants refer to fixed values
that do not change during the execution of a program.
Like C, C++
supports several kinds of literal constants. They include integers, characters,
floating point numbers and strings. Literal constant do not have memory
locations. Examples:
123 //decimal integer
12.34 // floating point integer
037 // octal integer
0X2 // hexadecimal integer
"C++" // string constant
'A' // character constant
L 'ab' // wide-character constant
The wchar_t
type is a wide-character literal introduced by ANSI C++ and is intended for
character sets that cannot fit a character into a single byte. Wide-character
literals begin with the letter L.
C++ also recognizes all the
backslash character constants available in C.
3.5 Basic Data Types
Fig 3.5 Hierarchy of C++ data types
Both C and C++
compilers support all the built-in (also known as basic or fundamental) data
types. With the exception of void, the basic data types may have several
modifiers preceding them to serve the needs of various situations. The
modifiers signed, unsigned long, and short may be applied to character and
integer basic data types. However, the modifier long may also be applied to double.
Data type representation is machine specific C++. Table 3.2 lists all
combinations of the basic data types and modifiers along with the size and
range for a 16-bit word machine.
Type
|
Bytes
|
Range
|
||
char
|
1
|
-128 to
127
|
||
unsigned char
|
1
|
0 to
255
|
||
signed char
|
1
|
- 128 to
127
|
||
int
|
2
|
- 32768 to
32767
|
||
nsigned int
|
2
|
0 to
65535
|
||
signed int
|
2
|
- 31768 to
32767
|
||
short int
|
2
|
- 31768 to
32767
|
||
unsigned short int
|
2
|
0 to
65535
|
||
signed short int
|
2
|
-32768 to
32767
|
||
long int
|
4
|
-2147483648 to 2147483647
|
||
signed long int
|
4
|
-2147483648 to 2147483647
|
||
unsigned long int
|
4
|
0 to
4294967295
|
||
float
|
4
|
3.4 E-38 to
3.4E+38
|
||
double
|
8
|
1 . 7E-308 to 1. 7E+308
|
||
long double
|
10
|
3.4E-4932 to 1.1E+4932
|
||
Table 3.2 Size and range of C++ Basic Data Types
ANSI C++
committee has added two more data types, bool and wchar_t. The type void was
introduced in ANSI C. Two normal uses of void are (1) to specify the return
type of a function when it is not returning any value, and (2) to indicate an
empty argument list to a function. Example:
void funct1(void);
Another interesting use of void
is in the declaration of generic pointers. Example :
void *gp; // gp
becomes generic pointer
A generic
pointer can be assigned a pointer value of any basic data type, but it may not
be dereferenced. For example,
int *ip; // int pointer
p = ip; // assign int printer to void pointer
are valid statements. But, the statement
*ip = *gp; is illegal. It would
not make sense to dereference a pointer to a void value.
Assigning any pointer type to a void pointer without using a
cast is allowed in both C++ and ANSI C. In ANSI C, we can also assign a void
pointer to a non-void pointer without using a cast to non-void pointer type.
This is not allowed in C++. For example, void
*ptr1; char *ptr2;
ptr2 = ptr1;
are all valid statements in
ANSI C but not in C++. A void pointer cannot be directly assigned to other type
pointers in C++.
3.6 User-Defined Data Types
Structures and Classes
Like C, C++
also support user defined data type such as
struct and union. Some more features have been added to make them suitable
for object oriented programming. C++ also permits us to define another
user-defined data type known as class which can be used, just like any other
basic data type, to declare variables. The class variables are known as
objects, which are the central focus of object-oriented programming.
Enumerated Data Type
An enumerated
data type is another user-defined type which provides a way for attaching names
to numbers, thereby increasing comprehensibility of the code. The enum keyword
(from C) automatically enumerates a list of words by assigning them values
0,1,2, and so on. This facility provides an alternative means for creating
symbolic constants. The syntax of an enum statement is similar to that of the
struct statement. Examples:
enum
shape{circle, square, triangle}; enum colour{red, blue, green, yellow}; enum
position{off, on};
The enumerated
data types differ slightly in C++ when compared with those in ANSI C. In C++,
the tag names shape, colour, and position become new type names. By using these
tag names, we can declare new variables. Examples:
shape ellipse;
// ellipse is of type shape
colour background; //
background is of type colour
ANSI C defines the types of enums to be ints. In C++, each
enumerated data type retains its own separate type. This means that C++ does
not permit an int value to be automatically converted to an enum value.
Examples:
colour background = blue;
|
// allowed
|
colour background = 7;
|
// Error in C++
|
colour background= (colour)
7;
|
// OK
|
However, an enumerated value can be used in place of an int
value
int c = red; //valid, colour typed promoted to int
By default, the enumerators are
assigned integer values starting with 0 for the first enumerator, 1 for the
second, and so on. We can over-ride the default by explicitly assigning integer
values to the enumerators.
For example, enum colour{red,
blue=4, green=8};
enum colour{red=5, blue, green};
are valid definitions. In the first case, red is 0 by
default. In the second case, blue is 6 and green is 7. Note that the subsequent
initialized enumerators are larger by one than their predecessors. C++ also
permits the creation of anonymous enums (i.e., enums without tag names).
Example:
enum{off, on};
Here, off is 0 and on is 1. These constants may be
referenced in the same manner as regular constants. Examples:
int switch_1 = off; int switch_2 = on;
In practice, enumeration is used
to define symbolic constants for a switch statement.
Example:
Enum shape
{
circle,
rectangle,
triangle } ; int main()
{
cout << "Enter shape code:"; int
code; cin>> code; while(code >= circle && code <= triangle)
{ switch(code)
{
case circle:
……………..
……………..
break; case rectangle:
……………..
……………..
break; case triangle:
……………..
……………..
}
cout " "Enter shape code:"; cin
" code;
}
cout " "BYE \n"; return 0;
}
ANSI C permits an enum to be defined within a structure or
a class, but the enum is globally visible.
In C++, an
enum defined within a class (or structure) is local to that class (or
structure) only.
3.7 Derived Data Types
Arrays
The application
of arrays in C++ is similar to that in C. The only exception is the way
character arrays are initialized. When initializing a character array in ANSI
C, the compiler will allow us to declare the array size as the exact length of
the string constant. For instance,
char string[3] =
"xyz";
is valid in ANSI C. It assumes that the programmer intends
to leave out the null character \0 in the definition. But in C++, the size
should be one larger than the number of characters in the string.
char string[4] =
"xyz"; //O.K.
for C++
Functions
Functions have
undergone major changes in C++. While some of these changes are simple, others
require a new way of thinking when organizing our programs. Many of these
modifications and improvements were driven by the requirements of the
object-oriented concept of C++. Some of these were introduced to make the C++
program more reliable and readable.
Pointers
Pointers are declared and
initialized as- in C. Examples:
int *ip; // int pointer
ip = &x; // address of x assigned to ip
*ip = 10; // 10 assigned to x through indirection
C++ adds the concept of constant pointer and pointer to a
constant.
char * const prt1 =
"GOOD"; // constant pointer
We can modify the address the ptr1 is initialized to
int const * ptr2 = &m; // pointer to a constant
ptr2 is declared as pointer to a constant. It can point to
any variable of correct type, but the contents of what it points to cannot be
changed.
We can also declare both the pointer and the variable as
constants in the following way:
const char * const cp =
"xyz";
This statement declares cp as a constant pointer to the
string which has been declared a constant. In this case, neither the address
assigned to the pointer cp nor the contents it points to can be changed.
Pointers are extensively used C++ for memory management and
achieving polymorphism.
3.8 Symbolic Constants
The symbolic constants can be
created in two ways:
•
Using the qualifier const, and
•
Defining a set of integer constants using enum keyword.
In both C and
C++, any value declared as const cannot be modified by the program in any way.
However, there are some differences in implementation. In C++, we can use const
in a constant expression, such as const int size = 10; char name[size];
This would be
illegal in C, const allows us to create typed constants instead of having to
use #define to create constants that have no type information.
As with long and short, if we use the const
modifier alone, it defaults to in. For example, const size = 10;
C++ requires a
const to be initialized. ANSI C does not require an initializer; if none is
given, it initializes the const to 0. The scoping of const values differs. A
const in C++ defaults to the internal linkage and therefore it is local to the
file where it is declared. In ANSI C, const values are global in nature. They
are visible outside the file in which they are declared. However, they can be
made local by declaring them as static. To give a const value an extemallinkage
so that it can be referenced from another file, we must explicitly define it as
an extern in C++. Example:
This defines X, Y and Z as
integer constants with values 0, 1, and 2 respectively. This is equivalent to:
const X=0; const Y=1;
const Z=2;
Such values can be any integer values.
3.9 Type Compatibility
C++ is very
strict with regard to type compatibility as compared to C. For instance, C++
defines int, short int, and long int as three different types. They must be
cast when their values are assigned to one another. Similarly, unsigned char,
char, and signed char are considered as different types, although each of these
has a size of one byte. In C++, the types of values must be the same for
complete compatibility, or else, a cast must be applied. These restrictions in
C++ are necessary in order to support function overloading where two functions
with the same name are distinguished using the type of function arguments.
Another notable difference is the way char constants are
stored. In C, they are stored as int, and therefore, sizeof(‘X’); is eqivalent
to sizeof(int); in C.
In C++, however, char is not promoted to the size
of int and therefore sizeof(‘x’);
equals sizeof(char);
3.10Declaration of Variables
We know that,
in C, all variables must be declared before they are used in executable.
statements. This is true with C++ as well. However, there is a significant
difference between C and C++ with regard to the place of their declaration in
the program. C requires all the variables to be defined at the beginning of a
scope. When we read a C program, we usually come across a group of variable
declarations at the beginning of each scope level. Their actual use appears elsewhere
in the scope, sometimes far away from the place of declaration. Before using a
variable, we should go back to the beginning of the program to see whether it
has been declared and, if so, of what type.
C++ allows the
declaration of a variable anywhere in the scope. This means that a variable can
be declared right at the place of its first use. This makes the program much
easier to write and reduces the errors that may be caused by having to scan
back and forth. It also makes the program easier to understand because the
variables are declared in the context of their use.
int main ( )
{
float x;
float sum = 0;
for (int i=l; i<5; i++)
{
cin ">>x; sum = sum +x;
}
float average; average = sum/(i-l); cout
<<average;
return 0;
}
The only
disadvantage of this style of declaration is that we cannot see all the
variables used in a scope at a glance.
3.11 Dynamic Initialization of Variables
In C, a
variable must be initialized using a constant expression, and the C compiler
would fix the initialization code at the time of compilation. C++, however,
permits initialization ofthe variables at run time. This is referred to as
dynamic initialization. In C++, a variable can be initialized at run time using
expressions at the place of declaration. For example, the following are valid
initialization statements:
...................
...................
int n = strlen(string);
...................
float area = 3.14159 * rad *
rad;
Thus, both the
declaration and the initialization of a variable can be done simultaneously at
the place where the variable is used for the first time. The following two
statements in the example of the previous section
float average; // declare where it is necessary
average = sum/i; can be combined into a single
statement;
float average = sum/i; // initialize dynamically at run time
Dynamic
initialization is extensively used in object-oriented programming. We can
create exactly the type of object needed, using information that is known only
at the run time.
3.12Reference Variables
C++ introduces
a new kind of variable known as the reference variable. A reference variable
provides an alias (alternative name) for a previously defined variable. For
example, if we make the variable sum a reference to the variable total, then
sum and total can be used interchangeably to represent that variable. A
reference variable is created as follows:
data-type &
reference-name=variable-name
float total =100; float &sum = total
total is a
float type variable that has already been declared; sum is the alternative name
declared to represent the variable total. Both the variables refer to the same
data object in the memory. Now, the statements cout<< total;
and cout<< sum
both print the value 100. The statement total =
total + 10; will change the value of both total and sum to 110. Likewise, the
assignemnt sum = 0;
will change the value of both
the variables to zero.
A reference
variable must be initialized at the time of declaration. This establishes the
correspondence between the reference and the data object which it names. It is
important to note that the initialization of a reference variable is completely
different from assignment to it.
C++ assigns additional meaning to the symbol &. Here,
& is not an address operator. The notation float & means reference to
float. Other examples are:
int n[10];
int & x = n[10];
|
// x is alias for n[10]
|
char & a = '\n';
|
// initialize reference to a literal
|
The variable x is an alternative to the array element n[10].
The variable a is initialized to the newline constant. This creates a reference
to the otherwise unknown location where the newline constant \n is stored. i.
int x;
int *p = &x; int & m =
*p;
ii. int &n=50;
The first set of declarations causes m to refer to x which
is pointed to by the pointer p and the statement in ( ii) creates an int object
with value 50 and name n.
A major application of reference variables is in passing
arguments to functions. Consider the following:
void f(int & x)
{ x=x+10;
}
int main ( )
{
int m = l0;
f(m) ;
_ _ _
}
When the function call f(m) is executed, the following
intialization occurs:
int & x= m;
Thus x becomes an alias of m after executing the statement
f(m);
The Such function calls are known as call by
reference. This implementation is illustrated in Fig. 3.2 . Since the variables
x and m are aliases, when the function increments x, m is also incremented. The
value ofm becomes 20 after the function is executed. In traditional C, we
accomplish this operation using pointers and dereferencing techniques.
Fig 3.2 Call by refernce mechanism
The call by
reference mechanism is useful in object-oriented programming because it permits
the manipulation of objects by reference, and eliminates the copying of object
parameters back and forth. It is also important to note that references can be
created not only for builttin data types but also for userdefined data types
such as structures and classes. References work wonderfully well with these
userdefined data types.
3.13 Operators in C ++
C++ has a rich
set of operators. All C operators are valid in C++ also. In addition, C++
introduces some new operators. We have already seen two such operators, namely,
the insertion operator <<, and the extraction operator >>. Other
new operators are:
: : Scope resolution
::* Pointer-to-member declarator
->* Pointer-to-member operator .* Pointer-to-member operator delete Memory release operator endl Line feed operator new Memory allocation operator setw Field width operator
In
addition, C++ also allows us to provide new definitions to some of the built-in
operators. That is, we can give several meanings to an operator, depending upon
the types of arguments u ed. This process is known as operator overloading.
Unary Operators
These are the
unary +(plus) sign and the unary – (minus) sign. They are used to indicate the
sign of an integer, a floating point quantity, or the exponent of the power of
10 in a floating point quantity. The auto increment (++) and auto decrement
(--) operators provide a convenient way of, respectively, adding and
subtracting 1 from a numeric variable.
Example The fragment
int K = 5;
++K + 10;
|
//gives 16
|
K++ +10;
|
//gives 15
|
–K+10;
|
//gives 14
|
K– +10;
|
//gives 15
|
Both operators
can be used in prefix and postfix form. The difference is significant. When
used in prefix form, the operator is first applied and the outcome is then used
in the expression. When used in the postfix form, the expression is evaluated
first and then the operator applied. Both operators may be applied to integer
as well as real variables.
Arithmetical Binary Operators
The
usual binary operations of arithmetic may be performed on integers and floating
point numbers:
addition, subtraction, multiplication
and division have the symbols + – * /,
and have algebraic precedence rules. Integral division, however, truncates the
decimal part of the quotient. For example, 16/3 yields 5 and 20/3 yields 6. If
at least one of the operands is negative, the result is compiler-dependent.
Some compilers choose a/b ==a / b whilst others choose a/b ==a / b.
For example, on some compilers 16/–3 == –
6 and on others, 16/–3 ==
–5. If we wish to obtain a decimal value for 16/3 then we must cast at
least one of the numbers into a double.
16.0/3 //or else 16/3.0
// or
else 16.0/3.0 //or
else double (16)/3
//or
else 16/double (3) //or else double (16)/double (3)
Example :
An integer
variable initialized as a float, will truncate the decimal part, losing this
information forever. The fragement
int a = 3.14; cout << a = <<a << ‘\n’;
float b;
b = a –0.14; cout << b= << b;
will print
a=3 b = 2.86
There is a
further operand on integers: %(read modormodulo) . Here a % b gives the
remainder of a upon division by b. Again, if at least one of the operands is
negative, the result is compiler dependent, but we always have(a/b) *b+a%b is
identical to a. The % operator has the same level of precedence as multiplication
or division, and it is left-associative.
Assignment Operators
The assignment
operator = is used to indicate that what is to the left of it acquires the
value to the right of it. Example The fragment
int a = 4; cout << a = << a << .;
a= a+19;
cout <<\na=<<a <<now.;
will print
a= 4. a = 23 now.
Note : The
assignment operator = does not test for equality.
An lvalue ( left-value) is a storage area (memory location) bound to a
variable during the programme execution. An rvalue( right-value) is the encoded value stored in the location
associated with the variable.
Relational Operators
The relational
operators <, < =, > =, ==, != evaluate to 1 if the relation is true
and to 0 if the relation is false. The operator! = is read not equal to.
Example: In the
fragment
int x = 1, y = 4, z, w, a; z = x < y; w= (x + 5)
< = y; a = y! = 5;
z
becomes 1 since x < y is true. w becomes 0 since (x + 5) < = y is false.
Finally, a becomes 1 since
y! = 5 is true.
Logical Operators
The logical negation operator
! gives output according to the following rules:
!1 gives 0 !0 gives1
The logical AND operator
&& gives output according to the following rules:
1 && 1 giv sddes 1 1 && 0 gives
00 && 1 gives 00 && 0
gives 0
Notice the similarity between this operator and regular
multiplication by 0.
The logical OR operator || gives
output according to the following rules:
1 || 1 gives 1 1 || 0 gives 1 0 || 1 gives 1 0
|| 0 gives 0
Notice the similarity between this operator and regular
addition to 0.
A value different from 0 will be interpreted as 1 by these
operators.
Example The fragment of code
int a = -1, b = 3, x, y, z, w, r,
s;
x = a
& & b; y = (s + 1) || b; z = (a + 1) && (b -3); w = (a!= b)
&& (a < = 0); r = (a < b) ||
( y = =0); s =!b;
will produce x = = 1, y = =1 , z
==0, w==1, r ==1, and s ==0.
Conditional Operator
C++’s only ternary operator is the conditional
operator ?:. which has the following syntax: test ? alternative_1 :
alternative_2
and evaluates
as follows. Test is evaluated first. If it is true, then the whole expression
becomes alternative_1, and alternative_2 is not evaluated at all. If test is
false, alternative _1 is skipped, and the whole expression becomes
alternative_2.
Example in the fragment
int a = 3, b = 6, c; c = (a == b)?(a + 1):(b - 8);
c becomes -2, since a = = b
is false and so the conditional
expression assumes the second alternative b-8.
Comma Operator
The comma,
operator takes its arguments and evaluates them from left to right and returns
the value of the rightmost expression.
Example in the fragment
int a = 1, b;
b = (a += 1, a += 2, a + 5);
The comma
operator first evaluates a += 1 which makes a == 2. The next expression a += 2 is evaluated
and so a == 4. Finally, the last expression a + 5 is evaluated becoming a + 5
== 9. Hence b == 9.
Bitwise Operators
C++ provides six bitwise operators for
manipulating the individual bits in an integer quantity. These are:
Operator
|
Name
|
Example
|
~
|
Bitwise
Negation
|
~\011 //gives\366
|
&
|
Bitwise And
|
\011& \ //gives\001
|
|
|
Bitwise Or
|
\011\ //gives\037
|
^
|
Bitwise
Exclusive Or
|
\011^\ //gives\036
|
<<
|
Bitwise Left
Shift
|
\011 //gives\044
|
>>
|
Bitwise
Right Shift
|
\011 //gives\002
|
3.14Manipulators
Manipulators
are operators that are used to format the data display. The most commonly used
manipulators are endl and setw. The endl manipulator, when used in an output
statement, causes a linefeed to be inserted. It has the same effect as using
the new line character" \ n".
For example, the statement
.........................
..........................
cout « "m = "<<
m << endl
« "n = "<< n
<< endl
« "p = “<< p <<
endl;
would cause
three lines of output, one for each variable. If we assume the values of the
variables as 2597 , 14, and 175 respectively, the output will appear as follows
:
It is important to note that this form is not the ideal
output. It should rather appear under:
It is important to note that this from is not the ideal
ouput, It should rather appear as under:
m = 2597
n = 14
p = 175
Here, the
numbers are right-justified. This form of output is possible only if we can s a
common field width for all the numbers and force them to be printed
right-justified. setw manipulator does this job. It is used as follows:
cout << setw(5) <<
sum << endl;
The manipulator
setw(5) specifies a field width 5 for printing the value of the varia sum. This
value is right-justified within the field as shown below:
Example program to illustrate the use of manipulators
#include <iostream.h>
#include <iomanip.h> // for setw
int main( )
{
cout «setw(10) «
"Basic" « setw(10) « Basic « endl
« setw(10) «
"Allowance" « setw(10) « Allowance « endl
« setw(10) « "Total" « setw(10) « Total «
endl; return 0;
}
The following is the output of above program:
Basic
|
950
|
Allowance
|
95
|
Total
|
1045
|
We can also write our own manipulators as follows:
#include <iostream.h>
ostream & symbol (ostream & output)
{
return output << “\t Rs”;
}
The symbol is
the new manipulator which represents Rs.The identifier symbol can be used
whenever we need to display the string Rs.
3.15 Type Cast Operator
C++ permits explicit type
conversion of variables or expressions using the type cast operator.
Traditional C
casts are augmented in C++ by a function-call notation as a syntactic
alternative. The following two versions are equivalent:
(type-name) expressi on
|
// C notation
|
type-name (expression) examples :
|
// C++ notation average
|
average = sum/(float)i;
|
// C notation
|
average = sum/float(i);
|
// C++ notation
|
A type-name
behaves as if it is a function for converting values to a designated type. The
functioncall notation usually leads to simplest expressions. However, it can be
used only if the type is an identifier. For example,
p = int*(q);
is illegal.
in such cases we must use c type notation p= (int
*)q;
Alternatively,
we can use typedef to create an identifier of the required type and use it in
the functional notation.
typedef int * int_pt; p = int_pt(q);
ANSI C++ adds the following new cast operators:
•
const_cast
•
static_cast
•
dynamic __ cast
•
reinterpret_cast
3.16 Expressions and Their Types
An expression
is a combination of operators, constants and variables arranged as per the
rules of the language. It may also include function calls which return values.
An expression may consist of one or more operands, and zero or more operators
to produce a value. Expressions may be of the following seven types:
•
Constant expressions
•
Integral expressions
•
Float expressions
•
Pointer expressions
•
Relational expressions
•
Logical expressions • Bitwise
expressions
An expression
may also use combinations of the above expressions. Such expressions are known
as compound expressions.
Constant Expressions
Constant Expressions consist of
only constant values.
Examples:
15
20 + 5 /
2.0
‘X’
Integral Expressions
Integral Expressions
are those which produce integer results after implementing all the automatic
and explicit type conversions.
Examples: m
m * n - 5 m * 'x'
Float Expressions
Float Expressions are those
which, after all conversions, produce floating-point results. Examples: x + y x
* y / 10
5 + float (10)
10 .75
Pointer Expressions
Pointer Expressions produce
address values. Examples:
&m
ptr
ptr + 1 "xyz" Relational
Expressions
Relational
Expressions yield results oftype bool which takes a value true or false.
Examples:
x <= y a + b == c + d m + n > 100
When arithmetic
expressions are used on either side of a relational operator, they will be
evaluated first and then the results compared. Relational expressions are also
known as Boolean expressions.
Logical Expressions
Logical
Expressions combine two or more relational expressions and produces bool type
results. Examples:
a > b && x == 10 x == 10 || y == 5
Bitwise Expressions
Bitwise
Expressions are used to manipulate data at bit level. They are basically used
for testing or shifting bits. Examples:
x << 3
|
//Shift three bit position to left
|
y << 1
|
// Shift one bit position to right
|
ANSI C++ has
introduced what are termed as operator kevwords that can be used as alternative
representation for operator symbols.
3.17 Operator Precedence
Although C++
enables us to add multiple meanings to the operators, yet their association and
precedence remain the same. For example, the multiplication operator will
continue having higher precedence than the add operator. Table 3.3 gives the
precedence and associativity of all the C++ operators. The groups are listed in
the order of decreasing precedence. The labels prefix and postfix distinguish
the uses of ++ and --. Also, the symbols
+. -, *, and & are used as both unary and binary operators.
|
Operator
|
Associativity
|
||
: :
|
|
left to right
|
||
|
–>.( ) [ ] postfix ++ postfix - prefix
++ prefix - - ~! unary + unary -
|
left to right
|
||
|
unary * unary & (type) size of new delete
–> **
|
right to left
left to right
|
||
|
* / %
|
left to right
|
||
|
+ -
|
left to right
|
||
|
<< >>
|
left to right
|
||
|
<< = >> =
|
left to right
|
||
|
= = ! =
|
left to right
|
||
|
&
|
left to right
|
||
|
^
|
left to right
|
||
|
|
left to right
|
|||
&&
|
left to right
|
|||
| |
|
left to right
|
|||
?;
|
left to right
|
|||
= * = / = % = + = =
|
right to left
|
|||
<< = >> = &
= ^ = | =
|
left to right
|
|||
, (comma)
Table 3.3 Operator precedence and associativity
3.18 Control Structures
In C++
, a large
number of functions are used that pass messages, and process the data contained
in objects. A function is set up to perform a task. When the task is complex,
many different algorithms can be designed to achieve the same goal. Some are
simple to comprehend, while others are not. Experience has also shown that the
number of bugs that occur is related to the format of the program. The format
should be such that it is easy to trace the flow of execution of statements.
This would help not only in debugging but also in the review and maintenance of
the program later. One method of achieving the objective of an accurate,
error-resistant and maintainable code is to use one or any combination of the
following three control structures:
1. Sequence
structure (straight line)
2. Selection
structure (branching)
3. Loop
structure (iteration or repetition)
Figure 3.4 shows how these structures are
implemented using one-entry, one-exit concept, a popular approach used in
modular programming.
Fig. 3.4 Basic control
structures
It is important to understand that all
program processing can be coded by using only these three logic structures. The
approach of using one or more of these basic control constructs in programming
is known as structured programming, an important technique in software
engineering.
Using these three basic constructs, we
may represent a function structure either in detail or in summary form as shown
in Fig. 3.4.
Like C, C++
also supports all the three basic control structures, and implements them using
various control statements as shown in Fig. 3.6. This shows that C++ combines
the power of structured programming with the object-oriented paradigm.
The if statement the if statement is implemented in two forms:
•
Simple if statement
•
if ... else statement
Entry Entry
Examples:
Form 1
if(expression is
true)
{
actionl;
}
action2;
action3; Form 2
if(expression is
true)
{
actionl;
}
else
{
action2;
}
action3;
The
switch statement
This is a
multiple-branching statement where, based on a condition, the control is
transferred to one of the many possible points. This is implemented as follows:
switch(expression)
{
casel:
{
actionl;
}
case2:
{
action2;
}
case3:
{
action3;
}
default:
{
action4;
}
}
action5;
The do-while statement
The do-while is
an exit-controlled loop. Based on a condition, the control is transferred back
to a particular point in the program. The syntax is as follows:
do
{
action1;
}
while(condition is true);
action2;
The while statement
This is also a loop structure,
but is an entry-controlled one. The syntax is as follows: while(condition is
true)
{
action1; }
action2;
The for statement
The for is an
entry-controlled loop and is used when an action is to be repeated for a predetermined
number of times. The syntax is as follows:
for (initial value; test;
increment/decrement)
{
action1;
}
action2;
The syntax of the control statements in
C++ is very much similar to that of C and therefore they are implemented as and
when they are required.
3.19Summary
C++
provides various types of token-keywords, identifiers, constants and operators.
Identifiers are name of variable, function, arrays, and classes. In C++, the
size of character array should be one larger than the number of characters in
the string, C++ provides const to declare named constant. C++ supports seven
types of expression. C++ performs conversion automatically using rules. C++
also permits explicit type conversion of variables and expressions using the
type cast operators. C++ also supports the three basic control structure
namely, sequence, selection and loop and implements them, using various control
statements such as if, if....else, switch, do...while, while and for.
3.20 Self Assessment Questions
1. Describe
the differences in the implementation of enum data type in ANSI C and C++.
2. In
C++, a variable can be declared anware in the scope. What is significance of
this feature?
3. What
is a reference variable? What is its major use?
4. Write
a program for prime number.
Write a program to read any ten nuumbers and find sum and average.
Contact--
Ankit Pundir
(ankitpundir623@gmail.com)