c3134 - Oops Notes - Module I
c3134 - Oops Notes - Module I
Preprocessor Directives
Preprocessor directives are lines included in the code of programs preceded by a hash sign (#).
These lines are not program statements but directives for the preprocessor. The preprocessor
examines the code before actual compilation of code begins and resolves all these directives
before any code is actually generated by regular statements.
#include <iostream>
This directive causes the preprocessor to add the contents of the iostream file to the program.
The header file iostream should be included at the beginning of all programs that use
input/output statements.
#define arg1 arg2: The #define directive is also used for text substitution. Its first argument
specifies the text to be substituted, and the second argument specifies the text to be used as
the substitute.
Eg1: #define PI 3.14159266
Comments
C++ has two types of comments: block comments (multi-line comments) and end-of-line
comments (single-line comments).
Block comments start with a two-character symbol /* and end with a two-character symbol
*/.
End-of-line comments start with a two-character symbol // and ends without a special symbol
but till the line ends.
A variable is used to store a value. Before the identifier is used as a name for a variable in a
C++ the program, it has to be defined. The names of variables denote locations (addresses) in
computer memory that hold typed values. These values can change during program execution.
The keywords in their lowercase cannot be used as variables. The type of the variable describes
the range of values permissible for that type and the operations allowed over values of this
type.
The definition establishes an association between the identifier and its type, reserving a
memory space for it based on the type; each definition ends with a semicolon as follows:
int num1, num2;
double sum;
char letter;
Generally, declaration of a variable is same as its definition. But in C++, both are different.
While definitions associate the name of the variable with its type and allocate the space for
the variable, declarations only associate the name and the type, because the space for the
variable is allocated elsewhere.
Integral Type: On all computer architectures, the C++ integer type represents the most basic
type. The values of this type are always the fastest to operate on the given platform.
Character Type: The character type is treated by C++ as just another kind of integer. Its size is 1
byte (8 bits). It can represent any ASCII symbol: a letter, a digit, or a nonprintable control
character. Here are examples of definitions for character variables.
char abc;
char c = 'A', ch = 65; // both c and ch contain 'A'
Boolean Values: It has values true and false. These values are useful for computing logical
expressions and for choosing execution paths through the program code. The Boolean values
take only one byte of memory.
Eg: bool flag = false, result = true;
If we print the values flag and result defined above, the first one will be printed as zero (not as
false ), and the second one will be printed as one (not as true ).
Floating Point Types: Used to store fractional numbers. There are three floating point types in
C++: float, double, and long double. Usually, type float is allocated four bytes, type double is
Conditional Statements
The simplest conditional statement is the if statement. Its general form is
if (testExpression)
{
// statements
}
If-else statement
Syntax:
if(condition) {
Statement(s);
}
else {
Statement(s);
}
The statements inside “if” would execute if the condition is true, and the statements inside “else”
would execute if the condition is false.
Example
if (b > a) {
cout << "b is greater";
} else {
cout << "a is greater";
}
Nested if...else
if (condition1)
{
if-else-if ladder
Syntax:
if (condition)
statement;
else if (condition)
statement;
.
.
else
statement;
example
if (i == 10)
cout<<"i is 10";
else if (i == 15)
cout<<"i is 15";
else if (i == 20)
cout<<"i is 20";
The 'switch' Statement:
The switch statement is a tool for making multiway decisions in a program. It provides
alternative execution paths based on the value of an integral expression.
The expression in parentheses follows the keyword switch. The rest of the statement consists
of branches that are placed within the braces.
Each branch consists of the keyword case, a value of the same type as the switch expression, a
colon, and a set of one or more statements terminated by semicolons.
The switch expression can be only of type char, short, int, or long (integral types). Floating point
types ( float, double, or long double ) or programmer-defined types (arrays, structures, or classes)
are not allowed. Also. Each case statement block must have a break statement as the last statement
in order to avoid successive execution of the case blocks after that. The default branch is executed
if none of the case expressions match.
Iteration:
They are used for repetitive actions. C++ provides three iterative statements: while loops, do-while
loops, and for loops.
While:
* The while loop tests the loop condition to be true before each iteration through the loop
body and stops the iterations when the loop condition becomes false.
* The loop expression is tested before the first iteration itself and so it is an entry-controlled
loop. Thus the loop body will not be executed at all if the condition is false when it is first
checked.
Syntax:
while (expression)
{
statement;
}
Example:
int a = 1;
while( a <= 10 )
{
cout << "value of a: " << a;
do-while:
* The do - while loop is very similar to the while loop but it tests its condition at the bottom
of the loop body, after each iteration and the loop body will be executed at least once.
Since the condition is checked at the end of the loop body, this loop is called exit controlled
loop.
Syntax:
do
{
statements; // this is the loop body – simple or compound statement
}while(expression);
Example:
int a = 1;
do
{
cout << "value of a: " << a;
a++;
} while(a<=10);
for:
* The for loop is usually considered an appropriate loop when the number of repetitions is
known in advance, before the loop starts.
* This form of iteration brings together the three most important elements of the loop
design: initialization of the current value before the first iteration, evaluation of the current
value before the start of next iteration, and change of the current value after the iteration
(before the next iteration).
Syntax:
for (init; condition; IncrementExpr)
statement;
* The init step is executed first, and only once. This step allows you to declare and initialize
any loop control variables. You are not required to put a statement here, as long as a
semicolon appears.
* Next, the condition is evaluated. If it is true, the body of the loop is executed.
* After the body of the for loop executes, the flow of control jumps back up to the increment
Eg:
for(int a=1; a<=10; a++)
{
cout << "value of a: " << a;
}
* Arrays are useful when we have to process a number of similar data many times. For eg:
Initialising an array:
int hours[7] = { 8, 8, 12, 8, 4, 0, 0 }; // 7 values
int hours[] = { 8, 8, 12, 8, 4, 0, 0 };
Multidimensional Arrays
* C++ supports multidimensional arrays. Theoretically, there is no limit to the number of array
dimensions.
* When defining a multidimensional array, specify the type of array components, the name of
the array, and, in separate brackets, the number of elements in the first direction, number of
elements in the second direction, and so on.
Eg: int m[2][3]; // 2 dimensional array. 2 rows of arrays, 3 elements each, total 6 int elements
Initialisation:
int m[2][3] = { 10, 20, 30, 40, 50, 60 }; // just like a one-d array
int m[2][3] = { { 10, 20 }, {30, 40 } };
* Access to an element of the multidimensional array requires several indices, one for each
dimension. Each index starts from 0, reaching one less than the maximum.
Character Arrays
* Character arrays are often called as strings. Since there is no array-boundary checking in C++,
the programmer has to take care of the length of the array. For character array, the end of
the array can be indicated by numeric Zero. This end character is called zero terminator
character or just the terminator. It is represented as '\0'.
Eg: char t[4] = { 'H','i','!','\0' }; // it displays “Hi!”. It has a length of 4 (including
the terminator). char t[4] = { 'H','i','!',0 }; // same as above
char t[] = { 'H','i','!',0 }; // same as above
Defining a structure
To define a structure, you use the struct keyword.
struct struct_name
{
Data type variable 1;
Data type variable 2;
…
Data type variable n;
};
struct person{
char first[32]; //first field an array of chars
char last[32]; //second field an array of chars
int age; //third field an int
};
Note that the above code is only defining a person structure. There are two ways to
declare a structure variable:
Declaring a structure
You can declare structure variables together with the structure defintion:
struct struct_name {
structure_member;
...
} var_1,var_2, var_n;
Or, you can declare the structure variable after you define the structure:
structure_name.structure_member
The following example demonstrates how to access the first name of structure
person:
person student;
student.first = "Richard";
Array of Structures
Just like you can have an array of any data type, you can have an array of structures.
struct person{
char first[32]; //first field an array of chars
char last[32]; //second field an array of chars
int age; //third field an int
};
Union
A union in C programming is a user defined data type which may hold members of different
sizes and type.
Union uses a single memory location to hold more than one variables. However, only one of
its members can be accessed at a time and all other members will contain garbage values.
The memory required to store a union variable is the memory required for the largest
element of the union.
Defining a Union
union person {
char name;
int age;
double height;
};
Since the union is still a type of structure the method for declaring it is as follows:
union person {
char name;
int age;
double height;
}newPerson;
Or
Person newPerson;
Initializing a Union
The process of initializing variables in a union is the same as a union but the results are what make
unions unique. The dot operator is still used in order to reach the data types inside of the union.
Person newPerson;
newPerson.age = 20;
newPerson.height = 6.2;
Once the height variable is initialized the variable age is overwritten and no longer exists.
Structure Union
A structure is defined with ‘struct’ keyword A union is defined with ‘union’ keyword
All members of a structure can be manipulated The members of a union can be manipulated only
simultaneously one at a time
The size of a structure object is equal to the sum The size of the union object is equal to the size of
of the individual sizes of the member objects the largest member object.
Structure members are allocated distinct Union members share common memory space
memory location. for their exclusive usage.
Bit Fields :
Classes and structures can contain members that occupy less storage than an integral type.
These members are specified as bit fields. The syntax for bit-field member-
declarator specification follows:
Syntax
declarator : constant-expression
Example :
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
};
block scope : The opening and closing curly braces delimit the block scope.
function scope : The function scope is also delimited by the opening and closing curly braces.
The difference between the block and the function scope is that the function has parameters
(and their names are known within the scope) and the name. The function scope is entered
during execution when the function is called.
file scope : The file scope is delimited by the physical boundaries of the file. It can contain type
definitions, definitions and declarations of variables, and definitions and declarations of
functions.
the scope of the whole program : The program scope has no delimiters. Anything belonging to
any source file that is part of the program is within the program scope.
Scope enables the programmer to define variables of the same name at different areas of the code.
For example if we define a variable in our code and inside a block after that with the same name,
the outside variable cannot be accessed inside the block.
Eg:
int j=10;
{
int j=2;
cout<<j<<endl; //will print 2
}
cout<<j; // will print 10
Scope rules help us avoid name conflicts and excessive communications among programmers.
Storage class refers to a span of execution time when the association between a name of a variable
and its location in memory exists.
In addition, C++ supports dynamic variables. Dynamic variables are allocated on the program
heap.
Eg: auto int j=10; // auto if it is inside a block or function, otherwise cause error
Static Variables
Static variables are local variables defined in a function (or in an unnamed block) so that their values
1. should survive from one function call to another (or from one scope execution to another).
2. Static storage class is also used to define global variables that should be accessed by the
code only in
The static variable is stored in the fixed memory and has a life span is from the start of the variable
definition (program – in the case 2), to the end of its execution. But the name is not known outside
of the braces (file – in the case 2) where the variable is defined.
Register Variables
The register storage class is used to define local variables just like the auto variables but are
stored in a register instead of memory. The number of register variables that can be defined
depends on the number of free registers available.
Eg: register int count=0;
When a local pointer (automatic variable) is not initialized, it contains a random bit pattern like any
other automatic variable. This pattern can be interpreted as an address, but this address can be
anywhere in memory. Reading from this location returns garbage; writing to this location corrupts
computer memory. It might crash the operating system, cause run-time memory protection
exception, produce incorrect results, or even produce correct results (if the location pointed to by
the pointer is not used by the program). Using noninitialized pointers is a common error, and it is
hard to diagnose because they can point to any area in memory.
eg:
int *p,*r; // two integer
pointers p and r int q=10;
The operator delete takes the name of a pointer as its operator. It finds the area on the heap pointed
to by its operand pointer and asks the operating system to mark this location (of the size defined by
It is very important to use delete operator corresponding to each new to avoid memory leakage.
Since C++ is backward compatible with C, malloc() and free() are supported in C++. They are defined
in the cstdlib standard library.
Eg: #include<iostream>
#include<fstream>
using namespace std; int main()
{
char c;
ifstream f("1.cpp");
if(f.fail())
{
cout<<"Error in opening file";
return 1;
}
do {
f>>c; // read each character
if(f.eof()) break;
cout<<c;
}while(1);
return 0;
}
But the >> operator has chances of errors. It will not read white spaces or new lines. Hence we use
functions get() and getline().
(1) get()
char c;
ifstream f("1.cpp");
do
{
f.get(c); //read each character to c
if(f.eof()) break; // check if reached end-of-file cout<<c;
}while(1);
char c[100];
ifstream f("1.cpp");
do
{
f.getline(c,90); // reads line, maximum 90 characters
if(f.eof()) break;
cout<<c;
}while(1);