Computer Programming
Computer Programming
Programming Fundamentals 1
Chapter 1
Function and parameter declarations
Returning values
Variable scope
Variabe storage classes
Pass-by-reference
Recursion
Passing arrays to functions
Pointers
The typedef declaration statement
Programming Fundamenta 2
Function and parameter declarations
User-defined program units are called subprograms.
In C++ all subprograms are referred to as functions.
Defining a Function
The lines that compose a function within a C++ program are
called a function definition.
Programming Fundamenta 3
A function definition consists of four parts:
A reserved word indicating the data type of the function’s return value.
The function name
Any parameters required by the function, contained within ( and ).
The function’s statements enclosed in curly braces { }.
Example 1:
Programming Fundamenta 4
How to call functions
You designate a data type for function since it will return a
value from a function after it executes.
Variable names that will be used in the function header line are
called formal parameters.
Programming Fundamenta 5
Function Prototypes
A function prototype declares to the compiler that you intend to use
a function later in the program.
If you try to call a function at any point in the program prior to its
function prototype or function definition, you will receive an error at
compile time.
Example 6.1.1
// Finding the maximum of three integers
#include <iostream.h>
int maximum(int, int, int); // function prototype
int main()
{
int a, b, c;
cout << "Enter three integers: ";
cin >> a >> b >> c;
cout << "Maximum is: " << maximum (a, b, c) << endl;
return 0;
}
Programming Fundamenta 6
// Function maximum definition
// x, y and z are parameters to the maximum function definition
int maximum( int x, int y, int z)
{
int max = x;
if ( y > max )
max = y;
if ( z > max )
max = z;
return max;
}
Programming Fundamenta 7
Passing by Value
If a variable is one of the actual parameters in a
function call, the called function receives a copy of
the values stored in the variable.
Programming Fundamenta 8
RETURNING VALUES
To actually return a value to a variable, you must
include the return statement within the called
function.
Programming Fundamenta 9
Inline function
For small functions, you can use the inline keyword to request
that the compiler replace calls to a function with the function
definition wherever the function is called in a program.
Example 6.2.1
// Using an inline function to calculate the volume of a cube.
#include <iostream.h>
inline double cube(double s) { return s * s * s; }
int main()
{
cout << "Enter the side length of your cube: ";
double side;
cin >> side;
cout << "Volume of cube with side "
<< side << " is " << cube(side) << endl;
return 0;
}
Programming Fundamenta 10
Function Overloading
C++ enables several functions of the same name to
be defined, as long as these functions have different
sets of parameters (at least their types are different).
This capability is called function overloading.
Programming Fundamenta 11
Example:
void showabs(int x)
{
if( x < 0)
x = -x;
cout << “The absolute value of the integer is “ << x << endl;
}
void showabs(double x)
{
if( x < 0)
x = -x;
cout << “The absolute value of the double is “ << x << endl;
}
The function call showabs(10);
causes the compiler to use the 1st version of the function
showabs.
Programming Fundamenta 12
Default arguments
C++ allows default arguments in a function call.
Programming Fundamenta 13
VARIABLE SCOPE
Programming Fundamenta 14
Example 6.3.1
#include <iostream.h>
int x; // create a global variable named firstnum
void valfun(); // function prototype (declaration)
int main()
{
int y; // create a local variable named secnum
x = 10; // store a value into the global variable
y = 20; // store a value into the local variable
cout << "From main(): x = " << x << endl;
cout << "From main(): y = " << y << endl;
valfun(); // call the function valfun
cout << "\nFrom main() again: x = " << x << endl;
cout << "From main() again: y = " << y << endl;
return 0;
}
Programming Fundamenta 15
void valfun() {
int y; // create a second local variable named y
y = 30; // this only affects this local variable's value
cout << "\nFrom valfun(): x = " << x << endl;
cout << "\nFrom valfun(): y = " << y << endl;
x = 40; // this changes x for both functions
return;
}
The output of the above program:
From main(): x = 10
From main(): y = 20
From valfun(): x = 10
From valfun(): y = 30
From main() again: x = 40
From main() again: y = 20
Programming Fundamenta 16
Scope Resolution Operator
When a local variable has the same name as a global
variable, all uses of the variable’s name within the
scope of the local variable refer to the local variable.
In such cases, we can still access to the global
variable by using scope resolution operator (::)
immediately before the variable name.
The :: operator tells the compiler to use the global
variable.
Programming Fundamenta 17
Example 6.3.3
#include <iostream.h>
float number = 42.8; // a global variable named number
int main()
{
float number = 26.4; // a local variable named number
cout << "The value of number is " << ::number << endl;
return 0;
}
The output of the above program:
The value of number is 42.8
Programming Fundamenta 18
VARIABLE STORAGE CLASS
The lifetime of a variable is referred to as the storage
duration, or storage class.
Four available storage classes: auto, static, extern and
register.
If one of these class names is used, it must be placed
before the variable’s data type in a declaration statement.
Examples:
auto int num;
static int miles;
register int dist;
extern float price;
extern float yld;
Programming Fundamenta 19
Local Variable Storage Classes
Local variables can only be members of the auto,
static, or register storage classes.
Default: auto class.
Automatic Variables
The term auto is short for automatic.
Automatic storage duration refers to variables that
exist only during the lifetime of the command block
(such as a function) that contains them.
Programming Fundamenta 20
Example 6.4.1
#include <iostream.h>
void testauto(); // function prototype
int main(){
int count; // count is a local auto variable
for(count = 1; count <= 3; count++)
testauto();
return 0;
}
void testauto(){
int num = 0; // num is a local auto variable
cout << "The value of the automatic variable num is "
<< num << endl;
The output of the above program:
num++;
The value of the automatic variable num is 0
return;
} The value of the automatic variable num is 0
The value of the automatic variable num is 0
Programming Fundamenta 21
Static local variables
In some applications, we want a function to
remember values between function calls. This is the
purpose of the static storage class.
A local static variable is not created and destroyed
each time the function declaring the static variable is
called.
Programming Fundamenta 22
Example 6.4.2
#include <iostream.h>
int funct(int); // function prototype
int main()
{
int count, value; // count is a local auto variable
for(count = 1; count <= 10; count++)
value = funct(count);
cout << count << ‘\t’ << value << endl;
return 0;
}
int funct( int x)
{
int sum = 100; // sum is a local auto variable
sum += x;
return sum;
}
Programming Fundamenta 23
The output of the above program:
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
10 110
Programming Fundamenta 24
Local static variable
A local static variable is not created and destroyed each time the
function declaring the static variable is called. Once created,
local static variables remain in existence for the life of the
program.
Example 6.4.2
#include <iostream.h>
int funct( int); // function prototype
int main()
{
int count, value; // count is a local auto variable
for(count = 1; count <= 10; count++)
value = funct( count);
cout << count << ‘\t’ << value << endl;
return 0;
}
Programming Fundamenta 25
int funct( int x)
{
static int sum = 100; // sum is a local auto variable
sum += x;
return sum;
}
The output of the above program:
1 101
2 103 Note:
3 106 1.The initialization of static variables is done
4 110 only once when the program is first
5 115 compiled. At compile time, the variable is
6 121 created and any initialization value is
7 128 placed in it.
8 136
9 145 2. All static variables are set to zero when no
10 155 explicit initialization is given.
Programming Fundamenta 26
Register Variables
Register variables have the same time duration as
automatic variables.
Register variables are stored in CPU’s internal
registers rather than in memory.
Examples:
register int time;
register double difference;
Programming Fundamenta 27
Global Variable Storage Classes
Global variables are created by definition statements
external to a function.
Once a global variable is created, it exists until the
program in which it is declared is finished executing.
Global variables may be declared as static or
external (but not both).
Programming Fundamenta 28
External global variables
//file1
int price; //file2
float yield; double interest;
static double coupon; int func3();
… {
.
int main(){
.
func1():
}
func2(): int func4();
func3(): {
func4(): .
} .
int func1(); }
{ //end of file2
…
} Although the variable price has been declared in
int func2(); file1, we want to use it in file2. Placing the statement
{ extern int price in file2, we can extend the scope of
… the variable price into file2.
}//end of file1
Programming Fundamenta 29
//file1 external double interest; //file2
int price; int func1(); double interest;
{ external int price;
float yield;
. int func3();
static double coupon; {
.
. .
}
. int func2(); .
int main(){ { }
. int func4();
func1():
. {
func2(): extern float yield;
}
func3(): //end of file1 .
func4(): .
} }
//end of file2
Note:
1. We cannot make static variables external.
2. The scope of a global static variable cannot extend beyond the file
in which it is declared.
Programming Fundamenta 30
PASS BY REFERENCE
Reference Parameters
Two ways to invoke functions in many programming languages
are:
- call by value
- call by reference
When an argument is passed call by value, a copy of the
argument’s value is made and passed to the called function.
Changes to the copy do not affect the original variable’s value
in the caller.
Programming Fundamenta 31
To indicate that the function parameter is passed-by-reference,
simply follow the parameter’s type in the function prototype of
function header by an ampersand (&).
For example, the declaration
int& count
in the function header means “count is a reference parameter
to an int”.
Example 6.5.1
#include <iostream.h>
int squareByValue( int );
void squareByReference( int & );
int main()
{
int x = 2, z = 4;
cout << "x = " << x << " before squareByValue\n"
<< "Value returned by squareByValue: "
<< squareByValue( x ) << endl
<< "x = " << x << " after squareByValue\n" << endl;
Programming Fundamenta 32
cout << "z = " << z << " before squareByReference" << endl;
squareByReference( z );
cout << "z = " << z << " after squareByReference" << endl;
return 0;
}
int squareByValue( int a )
{
return a *= a; // caller's argument not modified
}
void squareByReference( int &cRef )
{
cRef *= cRef; // caller's argument modified
}
Programming Fundamenta 33
RECURSION
In C++, it’s possible for a function to call itself. Functions that
do so are called seft-referential or recursive functions.
Example: To compute factorial of an integer
1! = 1
n! = n*(n-1)!
Example 6.6.1
#include <iostream.h>
#include <iomanip.h>
unsigned long factorial( unsigned long );
int main()
{
Programming Fundamenta 34
for ( int i = 0; i <= 10; i++ )
cout << setw( 2 ) << i << "! = " << factorial( i ) << endl;
return 0;
}
// Recursive definition of function factorial
unsigned long factorial( unsigned long number )
{
if (number < 1) // base case The output of the above
return 1; program:
else // recursive case 0! = 1
return number * factorial( number - 1 ); 1! = 1
} 2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
Programming Fundamenta 35
How the Computation is Performed
The mechanism that makes it possible for a C++ function to call
itself is that C++ allocates new memory locations for all function
parameters and local variables as each function is called.
There is a dynamic data area for each execution of a function.
This allocation is made dynamically, as a program is executed,
in a memory area referred as the stack.
A memory stack is an area of memory used for rapidly storing
and retrieving data areas for active functions. Each function call
reserves memory locations on the stack for its parameters, its local
variables, a return value, and the address where execution is to
resume in the calling program when the function has completed
execution (return address).
Programming Fundamenta 36
Thus, when the function call factorial(n) is made, a
data area for the execution of this function call is
pushed on top of the stack.
reserved for
returned value
return address
Figure 6.2 The data area for the first call to factorial
Programming Fundamenta 37
The progress of execution for the recursive function factorial
applied with n = 3 is as follows:
factorial(3) = 3*factorial(2)
= 3*(2*factorial(1))
= 3*(2*(1*factorial(0)))
= 3*(2*(1*1))
= 3*(2*1)
= 3*2
=6
factorial(0)
factorial(1) factorial(1) factorial(1)
factorial(2) factorial(2) factorial(2) factorial(2) factorial(2)
factorial(3) factorial(3) factorial(3) factorial(3) factorial(3) factorial(3) factorial(3)
Programming Fundamenta 38
PASSING ARRAYS TO FUNCTIONS
To pass an array to a function, specify the name of the array
without any brackets. For example, if array hourlyTemperature
has been declared as
int hourlyTemperature[24];
The function call statement
modifyArray(hourlyTemperature, size);
passes the array hourlyTemperature and its size to function
modifyArray.
For the function to receive an array through a function call, the
function’s parameter list must specify that an array will be
received.
Programming Fundamenta 39
For example, the function header for function modifyArray
might be written as
void modifyArray(int b[], int arraySize)
Notice that the size of the array is not required between the
array brackets.
Example 6.7.2
#include<iostream.h>
int linearSearch( int [], int, int);
void main()
{
const int arraySize = 100;
int a[arraySize], searchkey, element;
Programming Fundamenta 40
for (int x = 0; x < arraySize, x++) // create some data
a[x] = 2*x;
cout<< “Enter integer search key: “<< endl;
cin >> searchKey;
element = linearSearch(a, searchKey, arraySize);
if(element !=-1)
cout<<”Found value in element “<< element << endl;
else
cout<< “Value not found “ << endl;
}
int linearSearch(int array[], int key, int sizeofArray)
{
for(int n = 0; n< sizeofArray; n++)
if (array[n] = = key)
return n;
return –1;
}
Programming Fundamenta 41
POINTERS
A pointer is a special type of variable that stores the memory
address of other variables.
You declare a variable as a pointer by placing the indirection
operator (*) after the data type or before the variable name.
Examples:
int *pFirstPtr;
int *pSecondPtr;
You use the address-of operator (&) to assign to the pointer
variable the memory address of another variable.
Example:
double dPrimeInterest;
double *pPrimeInterest;
pPrimeInterest = &dPrimeInterest;
Programming Fundamenta 42
Note: If ptr is a pointer variable, *ptr means the contents of the
variable pointed to by ptr.
Example 6.8.1
#include<iostream.h>
void main()
{
int a;
The output of the above program:
int *aPtr;
// aPtr is a pointer to an integer
a = 7; The address of a is 0x0065FDF4
aPtr = &a; //aPtr set to address of a
cout << “The address of a is “ << &a The value of aPtr is 0x0065FDF4
<< “\nThe value of aPtr is “ << aPtr;
cout << “\n\nThe value of a is “<< a
The value of a is 7
<< “\nThe value of *aPtr is “ << *aPtr
<< endl; The value of *aPtr is 7
}
Programming Fundamenta 43
Calling Functions by Reference with Pointer
Arguments
In C++, programmers can use pointers and the
dereference operator to simulate call-by-reference.
When calling a function with arguments that should
be modified, the addresses of the arguments are
passed. This is normally achieved by applying the
address-of operator (&) to the name of the variable
whose value will be used.
A function receiving an address as an argument
must define a pointer parameter to receive the
address.
Programming Fundamenta 44
Example 6.8.2
// Cube a variable using call-by-reference with a pointer argument
#include <iostream.h>
void cubeByReference( int * ); // prototype
int main()
{
int number = 5;
cout << "The original value of number is " << number;
cubeByReference( &number );
cout << "\nThe new value of number is " << number << endl;
return 0;
}
void cubeByReference( int *nPtr )
{
*nPtr = (*nPtr) * (*nPtr) * (*nPtr); // cube number in main
} The output of the above propgram:
The original value of number is 5
The new value of number is 125
Programming Fundamenta 45
Pointers and Arrays
Notice that the name of an array by itself is equivalent to the
base address of that array. That is, the name z in isolation is
equivalent to the expression &z[0].
Example 6.8.3
#include<iostream.h>
void main()
{
int z[] = { 1, 2, 3, 4, 5};
cout << “The value return by ‘z’ itself is the addr “ << z << endl;
cout << “The address of the 0th element of z is “ << &z[0] << endl;
}
The output of the above program:
The value return by ‘z’ itself is the addr 0x0065FDF4
The address of the 0th element of z is 0x0065FDF4
Programming Fundamenta 46
Accessing Array Element Using Pointer and
Offset
If we store the address of grade[0] into a pointer named
gPtr, then the expression *gPtr refers to grade[0].
One unique feature of pointers is that offset may be
included in pointer expression.
For example, the expression *(gPtr + 3) refers to the
variable that is three (elements) beyond the variable
pointed to by gPtr.
The number 3 in the pointer expression is an offset. So
gPtr + 3 points to the element grade[3] of the grade array.
Programming Fundamenta 47
Example 6.8.4
#include <iostream.h>
int main()
{
int b[] = { 10, 20, 30, 40 }, i, offset; The output of the above
int *bPtr = b; // set bPtr to point to array b program:
Array b printed with:
cout << "Array b printed with:\n" Array subscript notation
<< "Array subscript notation\n"; b[0] = 10
b[1] = 20
for ( i = 0; i < 4; i++ ) b[2] = 30
cout << "b[" << i << "] = " << b[ i ] << '\n'; b[3] = 40
cout << "\nPointer/offset notation\n"; Pointer/offset notation
for ( offset = 0; offset < 4; offset++ ) *(bPtr + 0) = 10
cout << "*(bPtr + " << offset << ") = " *(bPtr + 1) = 20
<< *( bPtr + offset ) << '\n'; *(bPtr + 2) = 30
return 0; *(bPtr + 3) = 40
}
Programming Fundamenta 48
Pointers and Strings
We can scan through a string by using pointer.
The name of a string by itself is equivalent to the
base address of that string.
Example 6.8.5
/* Printing a string one character at a time using pointer */
#include<iostream.h>
void main( )
{ The output of the above
char strng[] = “Adams”; program:
char *sPtr;
sPtr = &strng[0];
cout << “\nThe string is: \n”;
The string is:
for( ; *sPtr != ‘\0’; sPtr++) Adam s
cout << *sPtr << ‘ ‘;
}
Programming Fundamenta 49
Passing Structures as Parameters
Complete copies of all members of a structure can be passed to a
function by including the name of the structure as an argument to
the called function.
The parameter passing mechanism here is call-by-value.
Example 6.8.6
#include <iostream.h>
struct Employee // declare a global type
{
int idNum;
double payRate;
double hours;
};
double calcNet(Employee); // function prototype
int main()
{
Programming Fundamenta 50
Employee emp = {6782, 8.93, 40.5};
double netPay;
netPay = calcNet(emp); // pass by value
cout << "The net pay for employee "
<< emp.idNum << " is $" << netPay << endl;
return 0;
}
double calcNet(Employee temp) // temp is of data
// type Employee
{
return (temp.payRate * temp.hours);
}
The output:
The net pay for employee 6782 is $361.665
Programming Fundamenta 51
Second way of passing a structure
An alternative to the pass-by-value function call, we can pass a
structure by passing a pointer.
Example 6.8.5
#include <iostream.h>
struct Employee // declare a global type
{
int idNum;
double payRate;
double hours;
};
double calcNet(Employee *); //function prototype
int main()
{
Programming Fundamenta 52
Employee emp = {6782, 8.93, 40.5};
double netPay;
netPay = calcNet(&emp); // pass an address
cout << "The net pay for employee "
<< emp.idNum << " is $" << netPay << endl;
return 0;
}
double calcNet(Employee* pt) //pt is a pointer
{ //to a structure of Employee type
return (pt->payRate * pt->hours);
}
The output is:
The net pay for employee 6782 is $361.665
Programming Fundamenta 53
THE typedef DECLARATION STATEMENT
The typedef declaration permits us to construct alternate
names for an existing C++ data type name. The syntax of a
typedef statement:
typedef data-type new-type-name
For example, the statement:
typedef float REAL;
make the name REAL a synonym for float. The name REAL can
now be used in place of float anywhere in the program after the
synonym has been declared.
The definition
REAL val;
is equivalent to float val;
Programming Fundamenta 54
Example: Consider the following statement:
typedef struct
{
char name[20];
int idNum;
} EMPREC;
The declaration EMPREC employee[75]; is equivalent to
struct
{
char name[20];
int idNum;
} employee[75];
Example: Consider the statement:
typedef double* DPTR;
Programming Fundamenta 55