You are on page 1of 75

Session 2

Module-2
Prepared by - Neetu Gupta
Contents
Control Statements
break, continue, switch, goto
Functions
- arguments
- return type
Scope global & local scope
Scope operator
Storage classes
auto, register, extern, static
Contents
Inline functions
Default arguments
Enumerations
Runtime stack
Command line arguments
Recursion


break statement
Using break we can leave a loop even if the
condition for its end is not fulfilled.
It can be used to end an infinite loop, or to
force it to end before its natural end.
The format is
break;
break statement - Example
// break loop example
#include <iostream>
using namespace std;
int main () {
int n;
for (n=10; n>0; n--) {
cout << n << ", ";
if (n==3) {
break;
}
}
return 0;
}
In this example, we are going to stop the
count down before its natural end. The loop
should executes till n is 0. But we are using
break when n is 3. That means loop will not
executes further when n becomes 3.
Hence the output is
10, 9, 8, 7, 6, 5, 4, 3

Please note that 2,1 is not printed as the loop is
break when n = 3.

continue statement
The continue statement causes the program
to skip the rest of the loop in the current
iteration as if the end of the statement block
had been reached, causing it to jump to the
start of the following iteration. The format is
simple as
continue;
continue statement - Example
// continue loop example
#include <iostream>
using namespace std;
int main () {
for (int n=10; n>0; n--)
{
if (n==5)
continue;
cout << n << ", ";
}
return 0;
}
continue statement - Example
Output is
10, 9, 8, 7, 6, 4, 3, 2, 1

In the example, a for loop is used to print values
from 10 to 1. But here we check if n==5, then we
use continue. hence, the control goes back to
start of for loop and statement the prints n is
skipped.
So the value 5 is not printed in the output above.
goto statement
The goto allows to make an absolute jump to
another point in the program.
You should use this feature with caution since its
execution causes an unconditional jump ignoring
any type of nesting limitations.
The destination point is identified by a label,
which is then used as an argument for the goto
statement.
goto label;

goto statement
// goto loop example
#include <iostream>
using namespace std;
int main () {
int n=10;
loop: cout << n << ", ";
n--;
if (n>0) goto loop; // loop is label here
return 0;
}
goto statement
Output is
10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Here, the loop is created using goto statement.
We check the value of n. If it is > 0, we executes
statement goto loop, this makes the control is
transferred to statement labeled as loop
switch statement
Its objective is to check several possible constant values for an
expression. Syntax is as:
switch (expression) {
case constant1:
group of statements 1;
break;
case constant1:
group of statements 1;
break;
. . .
default:
default group of statements
}
switch statement
It works in the following way:
1. switch evaluates expression and
2. checks if it is equivalent to constant1, if it is, it executes group of
statements 1 until it finds the break statement. When it finds this
break statement the program jumps to the end of the switch.
3. If expression was not equal to constant1 it will be checked against
constant2. If it is equal to this, it will execute group of statements
2 until a break keyword is found, and then will jump to the end of
the switch.
4. Finally, if the value of expression did not match any of the
previously specified constants , the program will execute the
statements included after the default: label, if it exists (since it is
optional).
switch statement - Example
// goto loop example
#include <iostream>
using namespace std;
int main () {
int x
cout << Enter the value of X: ";
cin >> X;
switch (x) {
case 1:
cout << "x is 1";
break;
case 2:
cout << "x is 2";
break;
default:
cout << "value of x unknown";
}
switch statement - Example
In the example, the value of X is read. Switch
checks the value of X with every case. If the
value of X is 1, then case 1 is executed. If the
value of X is 2 case 2 is executed. Otherwise
the default case is executed.

Output is
Enter the value of X: 2
X is 2
Function
Function is a self contained block of statements that
perform a coherent task of some kind.
Functions make the programs more modular and easy
to read and manage.
All C++ programs must contain atleast one function i.e.,
main( ), from which the execution of a program starts
Functions separate the concept (what is done) from the
implementation (how it is done).
Functions make programs easier to understand.




Function definition
Before we use a function in main() function of a
program, the function must be properly defined.
A function definition consists of two parts:
1. function prototype and
2. function body
Once define a function can be called several times
in the same program, allowing the code to be
reused.

Function prototype
The prototype specifies how a function can be used/called. It
basically tells the signature of a function
A function prototype consists of three parts:

1. name : This is simply a unique identifier.
2. parameters : This is a set of zero or more typed identifiers
used for passing values to and from the function.
3. return type: This specifies the type of value the function
returns. A function which returns nothing should have the
return type void.

Function body
The body of a function contains the computational
steps (statements) that comprise the function i.e. the
code of the function that will get executed when a
function is called.

The body of the function is return after its prototype
between the curly braces {}.

The last line in a function body is usually a return
statement.
A simple function - Example
// add two numbers - EXAMPLE
int addition (int a , int b) {
int sum;
sum = a + b;
return sum;
}

Here, addition is a function that adds two integer nos.:
int addition (int a , int b) function prototype, which tells
1. function name is addition
2. parameters are two int values a & b here
3. return type is an int value sum here

A simple function Example contd..
Function body : the code between {} is the body of
the function
{
int sum;
sum = a + b;
return sum;
}
Here, the code uses the parameters a and b. It adds the
value of a & b using + operator and saves the result into int
variable sum.
The value of int type variable sum is returned.

Using a function
After definition a function should be called in a
program to use it.
A function call consists of the function name
followed by the call operator brackets (), inside
which zero or more comma-separated arguments
appear.
The values passed between (), are called arguments
which are passed to parameters mentioned in
function prototype.
The following code depicts that how the addition function can
be called in main()
// function call - example
#include <iostream>
using namespace std;
int main () {
int x, y;
x = 10;
y = 45;
// Call the function addition with arguments x and y.
int add = addition (x , y);
cout << Sum of two nos << x <<and << y <<is << add;
return 0;
}
Here,
x and y are arguments which are used to pass the value into parameters a
and b
The variable add saves the return value from the function addition.


Types Of Function
In C++, we can basically use/call two types of functions:
1. Standard Library Functions
These are also called inbuilt functions that are already defined in
various header files we #include in our program.
The code of these functions is in .lib files of C++
For e.g.- getch() is defined in file <conio.h>

2. User Defined Functions
These are the functions which a user defines and provide code.
Like a function addition that we define in our previous example.

User Defined Function
These are of Four type
No Arguments No return
No Arguments but Return
Arguments but No return
Arguments with Return
No Arguments No Return
Neither the main function pass any value nor the called
function return any value
// Example - No Arguments No Return function
#include<conio.h>
void fact(); \\ function prototype

void main()
{
fact(); \\ function calling
)

void fact()
{ int i,n,fact=1;
cout<<Enter Number;
cin>>n;
for(i=n;i>0;i--)
fact=fact*i;
cout<<fact;
getch();
}
No Arguments But Return
A main function doesnt pass any value to a called
function but called function must return a value to main
function.
// Example - No Arguments But Return
int fact(); \\ function prototype

void main()
{
int f;
f=fact(); \\ function calling no arguments but it will gat a returned value
cout<<f;
}

int fact()
{ int i,fact=1,n;
cout<<Enter Number;
cin>>n;
for(i=n;i>0;i--)
fact=fact*i;
return fact;
}



Arguments But No Return
A main function will send arguments to the called
function and called function doesn't return any value to
main ().
// Example - Arguments But no Return
Void fact ( int ); \\ function prototype
Void main()
{ int n;
cout<<Enter Number;
cin>>n;
fact(n); \\ function calling with a single argument
}
Void fact(int x) \\ a copy of actual argument copies into formal argument x
{ int fact=1,I;
for(i=x;i>0;i--)
fact=fact*I Function Definition
cout<<fact;
}
Arguments With Return
The main function send values to a calling function and
called function must return value to main function back.
// Example - Arguments with Return
void fact(int); \\ function prototype

void main()
{ int n,f;
cout<<Enter Number;
cin>>n;
f=fact(n); \\ function calling with a single argument
cout<<f;
}

void fact(int x)\\ a copy of actual argument copies into formal argument x
{ int fact=1,i;
for(i=x;i>0;i--)
fact=fact*I Function Definition
return fact;
}
Scope
All the variables that we intend to use in a program must have
been declared with its type specifier in an earlier point in the
code, like we did in the previous code at the beginning of the
body of the function main when we declared that a, b, and
result were of type int.

The scope of a variable tells that where a particular identifier
can be used with in a program and where it can not be used.
Mainly two types
Global Scope
Local Scope
Global Scope
Everything defined at the program scope level
(i.e., outside any functions and classes) is said to
have a global scope.
A global variable is a variable declared in the main
body of the source code, outside all functions.
Global variables can be referred from anywhere in
the code, even inside functions, whenever it is
after its declaration.
Global Scope - Example
Variables may also be defined at the global scope.
Below, year is a global variable which can be used in
max() function and main() function
int year = 1994; // global variable
int max (int, int); // global function
int main (void) // global function
{
//...
}
int max (int, int) {
// body of function Max
..
.
}
Local Scope
A local variable is one declared within the body of
a function or a block
The scope of local variables is limited to the block
enclosed in braces ({}) where they are declared.
A local variable can not be accessed outside its
block.
A local scope overrides the global scope i.e.
having a local variable with the same name as a
global variable makes the latter inaccessible to
the local scope.


Each block in a program defines a local scope. Thus the body of a
function represents a local scope. The parameters of a function
have the same scope as the function body.

int xyz; // This xyz is global
void Foo (int xyz) // This xyz is local to the body of Foo
{
if (xyz > 0) {
double xyz; // This xyz is local to this block
//...
}
}

Local Scope
A complete program could be something like
as below :
Scope Operator
A local scope overrides the global scope, having a
local variable with the same name as a global
variable makes the latter inaccessible to the local
scope. For example,
int error = 10;
void Error (int error)
{
error = 15;
cout << error; // This will always print 15
}
Here, the global variable error is inaccessible inside Error
function , because it is overridden by the local error
parameter.
cout in function Error will always print value 15 not 10.
Scope Operator
What if at places in a program, we wish to refer
to the variable error which is defined outside not
the variable error which is defined inside
function.
This problem is overcome using the unary scope
operator
A scope operator is written as ::
It takes a global entity as argument.

Scope Operator - Example
// Use of Scope operator ::
int error = 10;
void Error (int error)
{
error = 15;
cout << Local error is: << error; // Local - will always print 15
cout << Global error is: << ::error; // Global - This will print 10
}

Output will be
Local error is:15
Global error is:10
Storage Classes

The "storage class" of a variable determines
The determines the part of member storage is
allocated for an object and how long the
storage allocation continues to exit. It tells
a.Where the variable is stored.
b.Initial value of the variable.
c.Scope of the variable. Scope specifies the
part of the program which a variable is
accessed global or local scope
d.Life of the variable.

There are four types of storage classes in
C++ which it inherits from C:
1. Automatic storage class
2. Register storage class
3. Static storage class
4. External storage class
Auto Variable
The lifetime of a local variable is limited and is
determined automatically, these variables are
also called automatic.
1. In this automatic storage class, variable is stored in
memory.
2. Default value is garbage value
3. Scope is local to the block
4. Life is, with in the block in which the variable is defined
5. Variable is defined using keyword auto
auto int I;

// auto variable Example
#include <iostream>
using namespace std;
main()
{
auto int i;
auto int j = 100;
cout >> j is: >> i
cout >> j is: >> j
}

Output:
I is: 2000
J is: 10

Here I is not initialized any value so it print say value
like 2000 here, whereas j has the value 10 as
initialized
Register Variable
The storage class specifier register may be used
to indicate to the compiler that the variable
should be stored in a register if possible.
1. Variable is stored in CPU registers.
2. Default value is garbage value.
3. Scope is local to the block.
4. Life is, with in the block in which the variable is defined.
5. We can not use register storage class for all types of variables.
6. These are used for fast retrieval.
7. Variable is defined using keyword register
register int I;


// register variable Example
#include <iostream>
using namespace std;
main()
{
for (register int i = 0; i < n; ++i)
sum += i;
}

Here, each time round the loop, i is used three times:
once when it is compared to n, once when it is added
to sum, and once when it is incremented. Therefore
it makes sense to keep i in a register for the duration
of the loop.
Static Variable
Defining a variable simply means that once the
variable has been initialized, it remains in
memory until the end of the program.
1. Variable is stored in memory.
2. Default value is zero.
3. Scope is local to the block.
4. Life is, value of the variable persists between different
function calls.
5. Variable is defined using keyword static
static int I;


// STATIC variable Example
#include <iostream>
using namespace std;
main()
{
add();
add();
}

// Function definition
add()
{
static int i=10; // i static variable defined
cout << I is :: << I;
i+=1;
}

Output:
I is :: 10
I is :: 11

Here, in function add() I is initialized to 10. so first time 10 is printed. In the second call to
add() function in main(), the value of I is preserved as it is defined as static. So the value
printed I is 11 not 10.
Extern Variables
A global variable may be defined in one file and
referred to in other files, some means of telling the
compiler that the variable is defined elsewhere may
be needed. This is facilitated by an extern declaration.
1. Variable is stored in memory.
2. Default value is zero.
3. Scope is local to the block.
4. Life is, as long as the program execution doesnt come to an end.
5. Declared using keyword extern as
extern int size; // variable declaration
This informs the compiler that size is actually defined somewhere (may be later in this file or in another file)..
// extern class Example
File 1: main.c
int count=5;
main() {
write_extern();
}

File 2: write.c

void write_extern(void);
extern int count;
void write_extern(void) {
cout >> "count is \n >> count;
}

Here extern keyword is being used to declare count in another file.
Enumerations
An enumeration consists of a set of named integer
constants.
An enumeration type declaration gives the name of
the (optional) enumeration tag and defines the set of
named integer identifiers (called the "enumeration
set," "enumerator constants).
A variable with enumeration type stores one of the
values of the enumeration set defined by that type.
Variables of enum type can be used in indexing
expressions and as operands of all arithmetic and
relational operators.
Enumerations - Use
Syntax to declare an enum is

enum identifier { enumerator-list } ;

// Defines an enumeration type named as DAY
enum DAY
{
saturday,
sunday = 0,
monday,
wednesday
thursday,
friday
} ;

The first value starts with 0 by default so value 0 is associated with saturday by
default.
The identifier sunday is explicitly set to 0. The remaining identifiers are given the
values 1 through 5 by default in sequence.
A variable today of type DAY can be declared
and initialized as
enum DAY today = wednesday;
In this example, a value from the set DAY is assigned to the variable today.

To explicitly assign an integer value to a
variable of an enumerated data type, use a
type cast:
enum DAY workday = ( enum DAY ) ( day_value - 1 );




// Enum example

#include <stdio.h>
int main()
{
// declare a enum Days
enum Days {Sunday,
Monday,Tuesday,
Wednesday,Thursday,
Friday,Saturday
};
Days TheDay; // a variable of type Days
int j = 0;
cout >> Please enter the day of the week (0 to 6)\n";
cin << theDay;
TheDay = Days(j);
if(TheDay == Sunday || TheDay == Saturday)
printf("Hurray it is the weekend\n");
else
printf("Curses still at work\n");
return 0;
}

Recursion
A function which calls itself is said to be a
recursive function and the process is called
recursion.
It is useful for many tasks, like sorting or
calculate the factorial of numbers
There should always be an exit condition to
end the recursion otherwise the call to
function might go in as a infinite loop.
(Important !!)
Recursion - Example
A function that calculates the factorial of a
number n - the mathematical formula is n! =
n * (n-1) * (n-2) * (n-3) ... * 1
like if n = 5
5! = 5 * 4 * 3 * 2 * 1 = 120

The task to be done for this is recursive in
nature , hence we can apply recursion as
// factorial calculator - Example
#include <iostream>
using namespace std;

long factorial (long a) {
if (a > 1) // exit condition tested
return (a * factorial (a-1));
else
return (1);
}
int main () {
long number, fact;
cout << "Please type a number: ";
cin >> number;
facto = factorial (number);
cout << \n << number << "! = " << fact;
return 0;
}
Output is
Please type a number: 5
5! = 120

Notice how in function factorial we included a call to itself, but only if the argument passed
was greater than 1, since otherwise the function would perform an infinite recursive loop in
which once it arrived to 0 it would continue multiplying by all the negative numbers.
For n set to 3, this table provides a trace of the calls to
Factorial. The stack frames for these calls appear
sequentially on the runtime stack, one after the other.







A recursive function must have at least one termination
condition which can be satisfied. Otherwise, the function
will call itself indefinitely until the runtime stack
overflows.

Call n n==0 n*factorial(n-1) Return
First 3 0 3*factorial(2) 6
Second 2 0 2*factorial(1) 2
third 1 0 1*factorial(0) 1
Fourth 0 1 1
Default arguments
When declaring a function we can specify a default
value for each of the last parameters.
Default argument is a programming convenience which
removes the burden of having to specify argument values
for all of a functions parameters.
If a value for that parameter is not passed when the
function is called, the default value is used, but if a
value is specified this default value is ignored and the
passed value is used instead.

// default values in functions
#include <iostream>
using namespace std;
// In function divide, the default value of b is 2
int divide (int a, int b=2) {
int r;
r=a/b;
return (r);
}
int main () {
cout << divide (12) << \n;
cout << divide (20,4);
return 0;
}
Output is
6 5

As we can see in the body of the program there are two calls to function
divide.

In the first one: divide (12)
we have only specified one argument, but the function divide allows up to
two. So the function divide has assumed that the second parameter is 2
since that is what we have specified to happen if this parameter was not
passed (notice the function declaration, which finishes with int b=2, not
just int b). Therefore the result of this function call is 6 (12/2).

In the second call: divide (20,4)
There are two parameters, so the default value for b (int b=2) is ignored
and b takes the value passed as argument, that is 4, making the result
returned equal to 5 (20/4).


Command Line Arguments
Command-line arguments are given after the name
of a program in command-line operating systems like
DOS or Linux, and are passed in to the program from
the operating system.
In C it is possible to accept command line arguments
by a program which is being passed to main()
function by operating system.
For this we must first understand the full declaration
of the main() function
The full declaration of main looks like this:
int main ( int argc, char *argv[] )

Two parameters are passed into function main()

1. argc : An integer type parameter
It is the argument count. It is the number of arguments passed into the
program from the command line, including the name of the program.

2. argv : The array of character pointers

It is the listing of all the arguments. argv[0] is the name of the program,
or an empty string if the name is not available. After that, every element
number less than argc is a command line argument. You can use each
argv element just like a string, or use argv as a two dimensional array.
argv[argc] is a null pointer.

Command Line Arguments How to
use them?
Almost any program that wants its parameters to be
set when it is executed would use this.
One common use is to write a function that takes the
name of a file and outputs the entire text of it onto
the screen. Suppose the program is saved with name
myfile.cpp
To pass arguments to main() of this program, we will
execute the program as
myfile <<name of the file>>
// Use of command line arguments Example
#include <stdio.h>
int main ( int argc, char *argv[] ) {
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */ printf( "usage: %s filename",
argv[0] );
}
else {
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 ) {
cout >> "Could not open file\n" ;
}
else
{
int x;
/* read one character at a time from file, stopping at EOF, which indicates the end of
the file. Note that the idiom of "assign to a variable, check the value" used below
works because the assignment statement evaluates to the value
assigned. */

while ( ( x = fgetc( file ) ) != EOF ) {
printf( "%c", x );
}
fclose( file );
}
}
}
Explanation:
It first checks to ensure the user added the second argument,
theoretically a file name. The program then checks to see if
the file is valid by trying to open it. This is a standard
operation, and if it results in the file being opened, then the
return value of fopen will be a valid FILE*; otherwise, it will be
0, the NULL pointer. After that, we just execute a loop to print
out one character at a time from the file.

Inline functions
The point of making a function inline is to hint to the compiler
that it is worth making some form of extra effort to call the
function faster than it would otherwise - generally by
substituting the code of the function into its caller.

This does not change the behavior of a function itself, but is
used to suggest to the compiler that the code generated by
the function body is inserted at each point the function is
called, instead of being inserted only once and perform a
regular call to it, which generally involves some additional
overhead in running time.


Format
The format for its declaration is:

inline type name ( arguments ... )
{
instructions
...
}

The function prototype is simply prefixed by keyword inline

Call to an inline function

name()

Call is just like the call to any other function. You do not have to include the
inline keyword when calling the function
Motivation for inline functions
Inline expansion is used to eliminate the time
overhead when a function is called.
It is typically used for functions that execute
frequently. It also has a space benefit for very small
functions, and is an enabling transformation for
other optimizations.
Without inline functions, however, the compiler
decides which functions to inline.
The programmer has little or no control over which
functions are inlined and which are not.
Giving this degree of control to the programmer
allows for the use of application-specific knowledge
in choosing which functions to inline.
Macros V/S inline
Traditionally, in languages such as C, inline expansion was accomplished at
the source level using parameterized macros.

Macro invocations do not perform type checking, or even check that
arguments are well-formed, whereas function calls usually do.
In C, a macro cannot use the return keyword with the same meaning as a
function would do (it would make the function that asked the expansion
terminate, rather than the macro). In other words, you cannot make the
macro return something which is not the result of the last expression
invoked inside it.
Since C macros use mere textual substitution, this may result in
unintended side-effects and inefficiency due to re-evaluation of
arguments and order of operations.


Macros V/S inline
Compiler errors within macros are often difficult to
understand, because they refer to the expanded
code, rather than the code the programmer typed.
Many constructs are awkward or impossible to
express using macros, or use a significantly different
syntax. Inline functions use the same syntax as
ordinary functions, and can be inlined and un-inlined
at will with ease.
Debugging information for inlined code is usually
more helpful than that of macro-expanded code.


Run time Stack
Like many other modern programming languages,
C++ function call execution is based on a runtime
stack.
When a function is called, memory space is allocated
on this stack for the function parameters, return
value, and local variables, as well as a local stack area
for expression evaluation.
The allocated space is called a stack frame. When a
function returns, the allocated stack frame is
released so that it can be reused.
Program execution begins at the start of the main
function, of course.
The main function in this program has variables
Length, Width, Area, and Perim.
Space is saved for these variables in an area of main
memory called the run-time stack.
Section of the run-time stack for the main function is
shown below.

Note that there is more room available at the top end of this stack should
we need it. Since the main function begins by assigning values to variables
Length and Width, these values are shown in the drawing of the run-time
stack.

Next, the main function calls the FindArea function as follows:

FindArea(Length, Width, Area);

The variables Length, Width, and Area inside these parentheses are the
actual parameters. They correspond in order from left to right to the three
formal parameters found in the code for the function, shown below.

void FindArea(float Length, float Width, float & Area)
{
Area = Length * Width;
}

When a function call is reached, a stack frame is placed on the run-time
stack.

We will use a simplified picture of a stack frame that ignores
some of the technical details.
In our picture, the first item in the stack frame is the return
address, that is, the location in the code to return to when the
called function has completed.
In our example, program execution should continue on the
line following the function call. Since this return address is a
number indicating a location in the compiled machine code,
no attempt is made to show the number itself, as it will vary
from computer to computer and may even vary from one run
to another on the same computer.
The next items put into the stack frame are the
parameters. The last items would be local variables,
but our example has none

The first two formal parameters are non-reference (call-by-copy)
parameters. Thus, in the picture of the run-time stack below, you see that
the 3.4 and 1.2 have been copied into these formal parameters. The third
formal parameter, Area, is a reference parameter. No value is stored in a
reference parameter. Rather, it contains a pointer to the corresponding
actual parameter. In our example the formal parameter Area contains a
pointer to the variable also called Area in the main function section of the
stack. The pointer is essentially the main memory address of the item
pointed to, but is more conveniently drawn as an arrow instead of a
number.

You might also like