Saturday, January 5, 2013

Operators ,WhileLoop,DoWhileLoop,ForLoop and Switch case in c++

Flow of Control

 Motivation

Normally, a program executes statements from first to last. The first statement is executed, then the second, then the third, and so on, until the program reaches its end and terminates. A computer program likely wouldn't be very useful if it ran the same sequence of statements every time it was run. It would be nice to be able to change which statements ran and when, depending on the circumstances. For example, if a program checks a file for the number of times a certain word appears, it should be able to give the correct count no matter what file and word are given to it. Or, a computer game should move the player's character around when the player wants. We need to be able to alter the order in which a program's statements are executed, the control flow.
Control Structures
Control structures are portions of program code that contain statements within them and, depending on the circumstances, execute these statements in a certain way. There are typically two kinds: conditionals and loops.
1. Conditionals
In order for a program to change its behavior depending on the input, there must a way to test that input. Conditionals allow the program to check the values of variables and to execute (or not execute) certain statements. C++ has if and switch-case conditional structures.
 1.Operators
Conditionals use two kinds of special operators: relational and logical. These are used to determine whether some condition is true or false.
The relational operators are used to test a relation between two expressions:

They work the same as the arithmetic operators (e.g., a > b) but return a Boolean value of either true or false, indicating whether the relation tested for holds. (An expression that returns this kind of value is called a Boolean expression.) For example, if the variables x and y have been set to 6 and 2, respectively, then x > y returns true. Similarly, x < 5 returns false.
The logical operators are often used to combine relational expressions into more complicated Boolean expressions:
The operators return true or false, according to the rules of logic:
The ! operator is a unary operator, taking only one argument and negating its value:

Examples using logical operators (assume x = 6 and y = 2):
!(x > 2) → false
(x > y) && (y > 0) → true
(x < y) && (y > 0) → false
(x < y) || (y > 0) → true
Of course, Boolean variables can be used directly in these expressions, since they hold true and false values. In fact, any kind of value can be used in a Boolean expression due to a quirk C++ has: false is represented by a value of 0 and anything that is not 0 is true. So, “Hello, world!” is true, 2 is true, and any int variable holding a non-zero value is true. This means !x returns false and x && y returns true!
2.if, if-else and else if
The if conditional has the form:
if(condition)
{
           statement1
           statement2
}

The condition is some expression whose value is being tested. If the condition resolves to a value of true, then the statements are executed before the program continues on. Otherwise, the statements are ignored. If there is only one statement, the curly braces may be omitted, giving the form:

if(condition)
statement
The if-else form is used to decide between two sequences of statements referred to as blocks:
if(condition)
{
statementA1
statementA2
}
else
{
statementB1
statementB2
}

If the condition is met, the block corresponding to the if is executed. Otherwise, the block corresponding to the else is executed. Because the condition is either satisfied or not, one of the blocks in an if-else must execute. If there is only one statement for any of the blocks, the curly braces for that block may be omitted:

if(condition)
statementA1
else
statementB1

The else if is used to decide between two or more blocks based on multiple conditions:
if(condition1)
{
statementA1
statementA2
}
else if(condition2)
{
statementB1
statementB2
}

If condition1 is met, the block corresponding to the if is executed. If not, then only if condition2 is met is the block corresponding to the else if executed. There may be more than one else if, each with its own condition. Once a block whose condition was met is executed, any else ifs after it are ignored. Therefore, in an if-else-if structure, either one or no block is executed.
An else may be added to the end of an if-else-if. If none of the previous conditions are met, the else block is executed. In this structure, one of the blocks must execute, as in a normal if-else.
Here is an example using these control structures:
 #include <iostream.h>
 int main()
 {
 int x = 6;
 int y = 2;
 if(x > y)
 cout<<"\nx is greater than y";
 else if(y > x)
 cout <<"\ny is greater than x";
 else
 cout <<"\nx and y are equal";
 return 0;
 }
The output of this program is x is greater than y. If we replace lines 5 and 6 with
int x = 2;
int y = 6;
then the output is y is greater than x. If we replace the lines with
int x = 2;
int y = 2;
then the output is x and y are equal.
3 switch-case

The switch-case is another conditional structure that may or may not execute certain statements. However, the switch-case has peculiar syntax and behavior:
switch(expression)
{
case constant1:
statementA1
statementA2
...
break;
case constant2:
statementB1
statementB2
...
break;
...
default:
statementZ1
statementZ2
...
}
The switch evaluates expression and, if expression is equal to constant1, then the statements beneath case constant 1: are executed until a break is encountered. If expression is not equal to constant1, then it is compared to constant2. If these are equal, then the statements beneath case constant 2: are executed until a break is encountered. If not, then the same process repeats for each of the constants, in turn. If none of the constants match, then the statements beneath default: are executed.

Due to the peculiar behavior of switch-cases, curly braces are not necessary for cases where
there is more than one statement (but they are necessary to enclose the entire switch-case). switch-cases generally have if-else equivalents but can often be a cleaner way of expressing the same behavior

Here is an example using switch-case:
#include <iostream.h>
int main()
{
int x = 6;
switch(x)
{case 1:cout << "x is 1\n";
break;
case 2:
case 3:cout << "x is 2 or 3"; break;
default:cout << "x is not 1, 2, or 3";
 }
return 0;
}
This program will print x is not 1, 2, or 3. If we replace line 5 with int x = 2; then the program will print x is 2 or 3.

2.Loops

Conditionals execute certain statements if certain conditions are met; loops execute certain statements while certain conditions are met. C++ has three kinds of loops: while, do-while, and for.

1.while and do-while
while(condition)
{
statement1
statement2
}

As long as condition holds, the block of statements will be repeatedly executed. If there is only one statement, the curly braces may be omitted. Here is an example:
#include <iostream.h>
int main()
{
int x = 0;
while(x < 10)
x = x + 1;
cout << "x is " << x << "\n";
return 0;
}


This program will print x is 10.

The do-while loop is a variation that guarantees the block of statements will be executed at least once:

do
{
statement1
statement2
}
while(condition);

The block of statements is executed and then, if the condition holds, the program returns to the top of the block. Curly braces are always required. Also note the semicolon after the while condition.

2. for

The for loop works like the while loop but with some change in syntax:

for(initialization; condition; incrementation)
{
statement1
statement2

}



The for loop is designed to allow a counter variable that is initialized at the beginning of the loop and incremented (or decremented) on each iteration of the loop. Curly braces may be omitted if there is only one statement. Here is an example:

#include <iostream.h>
 int main()
 {
for(int x = 0; x < 10; x++)
 cout << x << "\n";
 return 0;
 }
This program will print out the values 0 through 9, each on its own line.
If the counter variable is already defined, there is no need to define a new one in the initialization portion of the for loop. Therefore, it is valid to have the following:

#include <iostream.h>
int main() {
int x = 0;
 for(;x < 10; x = x + 1)
 cout << x << "\n";
 return 0;
 }

Note that the first semicolon inside the for loop's parentheses is still required.
A for loop can be expressed as a while loop and vice-versa. Recalling that a for loop has the form

for(initialization; condition; incrementation)
{
statement1
statement2
}

we can write an equivalent while loop as

initialization
while(condition)
{
statement1
statement2
incrementation
}

Using our example above,

#include <iostream.h>
int main()
{
 for(int x = 0; x < 10; x++)
 cout << x << "\n";
 return 0;
 }

is converted to

#include <iostream.h>
int main()
{
int x = 0;
while(x < 10)
{
cout << x << "\n";
x++;
}
return 0;
 }
The incrementation step can technically be anywhere inside the statement block, but it is good practice to place it as the last step, particularly if the previous statements use the current value of the counter variable.

 3.Nested Control Structures

It is possible to place ifs inside of ifs and loops inside of loops by simply placing these structures inside the statement blocks. This allows for more complicated program behavior.Here is an example using nesting if conditionals:

#include <iostream.h>
int main()
{
 int x = 6;
 int y = 0;
 if(x > y)
 {
 cout << "x is greater than y\n";
 if(x == 6)
 cout << "x is equal to 6\n";
 else
 cout << "x is not equalt to 6\n";
 } else
 cout << "x is not greater than y\n";
 return 0;
 }

This program will print x is greater than y on one line and then x is equal to 6 on the next line.
Here is an example using nested loops:

#include <iostream.h>
 int main()
 {
 for(int x = 0; x < 4; x = x + 1)
 {
 for(int y = 0; y < 4; y = y + 1)
 cout << y;
 cout << "\n";
}
 return 0;
 }

This program will print four lines of 0123.

Wednesday, January 2, 2013

DATA TYPES IN C++

Primitive Types 
C++ is a typed programming language.  Typed programming languages use systems of types to distinguish value data, address data, and program code in primary memory.  The C++ memory model is byte-addressible at its lowest level: that is, the smallest region of memory that we can identify with a C++ type is a single byte.  The type that we assign to the contiguous sequence of bytes starting at a specific address identifies the nature of the information stored in that region of memory as either value data, address data, or program code. 
In the type system of any programming language, type defines:
  • how to interpret the bit string at a specified location
  • what operations are valid on the bit string at the specified location
Once we assign a type to a region of memory, the compiler can flag those operations that are not permissible on that region of memory.  For example, the compiler will flag any multiplication of two C-style strings as an error because multiplication of a pointer to a char with another pointer to a char is not an admissible operation on pointers to chars. 
In this chapter, we describe the primitive types of C++ in detail.  These types include both scalar types - integrals, floating-points, and pointers - and a void type - valueless and operationless.

INTEGRAL TYPES

Standard C++ defines four integral types:
  • char
  • bool
  • int
  • enum
All of these types store their values in equivalent binary form without approximation. 
1.char
The char type occupies one byte of memory by definition: 
char
1 Byte
2.bool
The bool type also occupies one byte of memory: 
bool
1 Byte
A variable of bool type can hold one of two values: 0 for false and 1 for true. 
3.int
The int type occupies one word of memory.  One word is typically the size of a CPU register, making the int type the optimally efficient type.  On 32-bit platforms, one word occupies 4 bytes:
int (32-bit platforms)
1 Byte1 Byte1 Byte1 Byte
On a 16-bit platforms or emulations of 16-bit platforms, one word occupies 2 bytes:
int (16-bit platforms)
1 Byte1 Byte
The ordering of the bytes themselves depends upon the host platform.  Big-endian platforms store the highest order byte first.  Little-endian platforms store the lowest order byte first.  PowerPC platforms are typically big-endian, while Intel platforms are typically little-endian.  The ordering of bits within each byte is also platform dependent.

Size Specifiers

Three size specifiers define the minimum number of bits in an int type:
  • short
  • long
  • long long
short int type, or more concisely a short type, contains at least 16 bits:
short
1 Byte1 Byte
long int type, or more concisely a long type, contains at least 32 bits:
long
1 Byte1 Byte1 Byte1 Byte
long long int type, or more concisely a long long type, contains at least 64 bits:
long long
1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte
Size-wise, a short fits between a char and an int, while an int fits between a short and a long.
Range Specifiers
Range specifiers define the range of values associated with an int or a char.  The two range specifiers are
  • unsigned - no negative values
  • signed - negative and positive values
The default range for int types is signed.  The default range for char is platform-dependent. 
Unsigned
The unsigned keyword describes a range that extends from zero into the positive domain.  All of the bits in anunsigned type store value data. 
TypeSizeMinMax - 32 bitMax - 16 bit
 unsigned char 1 byte0255255
unsigned short>=16 bits0>= 65,535
unsigned int1 word04,294,967,29565,535
unsigned long>=32 bits0>= 4,294,967,295
 unsigned long long >=64 bits0>= 18,446,744,073,709,551,615 
If a variable only holds non-negative values, we add this keyword to its definition.  For example,
  • unsigned char letter;
  • unsigned short languages;
  • unsigned int persons; or more simply unsigned persons;
  • unsigned long students;
  • unsigned long long citizens;
The range of an unsigned int type depends upon the word size of the host platform.
Signed
The range of a signed int depends upon the word size of the host platform and the encoding scheme for negative values. 
The encoding schemes for negative values of integral type include:
  • two's complement notation - flip the bits and subtract one
  • one's complement notation - flip the bits
  • sign magnitude notation - reserve one bit for the sign
All three schemes represent positive values identically.  Two's complement, which is the most popular, renders separate ALU subtraction circuits unnecessary and yields only one representation of 0. 
For a two's complement encoding scheme, the ranges are:
32-bit platforms
TypeSizeMinMax
 signed char 1 byte-128127
char1 byte<=0>=127
short>=16 bits<= -32,768>= 32,767
int1 word-2,147,483,6482,147,483,647
long>=32 bits<= -2,147,483,648>= 2,147,483,647
long long>=64 bits<= -9,223,372,036,854,775,808 >= 9,223,372,036,854,775,807 
16-bit platforms
TypeSizeMinMax
 signed char 1 byte-128127
char1 byte<=0>=127
short>=16 bits<= -32,768>= 32,767
int1 word-32,76832,767
long>=32 bits<= -2,147,483,648>= 2,147,483,647
long long>=64 bits<= -9,223,372,036,854,775,808 >= 9,223,372,036,854,775,807 
Note that the ranges for charshortlong, and long long types are independent of the word size of the host platform.  Only the range for the int type is platform-dependent. 
Signed char
The default range for the char type varies across platforms.  The IBM AIX platform treats values of char type asunsigned, while Microsoft treats values of char type as signed
Since the ASCII collating sequence extends from 0 to 127 inclusive, the char type stores ASCII characters identically on all ASCII platforms.  However, if we use a char type to hold EOF (typically, -1), we need to identify thechar type as signed:
 signed char c; // for possibly storing EOF


FLOATING-POINT TYPES

The core language defines two floating-point types:
  • float - a single-precision, floating-point
  • double - a double-precision, floating-point
The standard does not specify the size of a float or double type but leaves it open to the compiler writer. 
Typically, a float type occupies 4 bytes of memory: 
float
1 Byte1 Byte1 Byte1 Byte
Typically, a double type occupies 8 bytes of memory: 
double
1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte
Size Specifier
The keyword long on the double type maximizes the number of significant digits.  Typically, a long double type occupies at least 64 bits of memory:
long double
1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte
The standard requires that the long double type occupy no less bits than the double type.  The standard does not specify a minimum number of bits for this type. 
Data Representation
The floating-point types store values approximately.  The most popular model is the IEEE (Eye-triple-E for the Institute of Electrical and Electronics Engineers) Standard 754 for Binary and Floating-Point Arithmetic. 
Under IEEE 754, a float type occupies 32 bits, has one sign bit, a 23-bit mantissa and an 8-bit exponent.  The arrangment of the mantissa and exponent bits is open:

float
1 Byte1 Byte1 Byte1 Byte
sexponentmantissa
or
float
1 Byte1 Byte1 Byte1 Byte
smantissaexponent
Under IEEE 754, the value stored is determined by the following formula
 value = s * 2e * { 1 + f12-1 + f22-2 + ... + f232-23}
where fi is the value of bit i (i = 1,2,...,23) of the mantissa and e is the exponent, which has a value between -127 and 128 inclusive.
Under IEEE 754, a double type occupies 64 bits, has one sign bit, a 52-bit mantissa and an 11-bit exponent.  The arrangment of the mantissa and exponent bits is open:
double
1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte
sexponentmantissa
or
double
1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte1 Byte
smantissaexponent
Under IEEE 754, the value stored is determined by the following formula
 value = s * 2e * { 1 + f12-1 + f22-2 + ... + f522-52}
where fi is the value of bit i (i = 1,2,...,52) of the mantissa and e is the exponent, which is between -1022 and 1023 inclusive.
Limits and Ranges
The limits on the number of significant digits and the ranges of the exponents for IEEE 754 float and double types are:


TypeSizeSignificant DigitsMin ExponentMax Exponent
float4 bytes6-3738
double8 bytes15-307308
The exponent values in this table are decimal (base 10). 

SYNONYMS
We can declare synonyms for types to improve the readability of our code.  Synonym types are simply aliases for other types.  We declare a synonym type using the keyword typedef.  The declaration takes the form
 typedef specifiedType Synonym;
where specifiedType is the original type along with its specifiers.  Synonym is the alias for that type. 
We allocate memory for a variable of synonym type by writing
 Synonym identifier;
For example
 typedef long long int VeryLong; // declaration

 VeryLong x, y;                  // definition
declares the type VeryLong as an unsigned long long int.  The definition allocates memory for twounsigned long long int variables: 
 long long int x;
 long long int y;
We may not add specifiers to a synonym type.  We must include the specifiers in the original declaration.
 unsigned VeryLong x, y; /* ERROR */

POINTER TYPES
A pointer type exists for each type in an application, including each specified type and each synonym type.  The pointer types declared for the core primitive types are:
  • char*
  • short*
  • int*
  • long*
  • long long*
  • float*
  • double*
  • long double*
Different pointer types are not assignment compatible.  We must use explicit casts:
 int* i;
 char* c;
 i = c;            // ERROR - Different Types 
 i = (int*) c;    // OK
Size of a Pointer Type
The size of a pointer type may vary from type to type and is platform dependent.  A common assumption has been that a variable of long type occupies at least as much space as any pointer type would require in any application. 
Synonym Pointer Types
We can use a synonym pointer type to simplify pointer definitions.  For example, we declare a synonym for a pointer to an int
 typedef int* ptr2int;
We can then define several pointer variables without having to include the * before each identifier
 ptr2int px, py;
Note that this synonym form is more readable than a direct definition
 int* px,* py;


VOID TYPE
In addition to the pointer types associated with the different types in an application, the core language also defines a generic pointer type that is not associated with any particular type: 
 void*
We may convert any pointer into a generic pointer (void*) and back to the application type without incurring any loss of information: 
 void* v;
 int* i;
 v = i;  // OK
 i = v;  // OK