1. Functions
Course Code: CSC1102 &1103
Dept. of Computer Science
Faculty of Science and Technology
Course Title: Introduction to Programming
Lecturer No: 9.2 Week No: 10 Semester: Spring 2024-2025
Course
Instructor:
Mashiour Rahman, Associate Professor,
mashiour@aiub.edu
2. Lectures 9: Outline
Functions
Functions and Arrays
Pointers as parameter
Return Pointer
Function Pointer
Inline Function
Recursive Functions
Function Overloading
3. Passing arrays as parameters
A whole array can be one parameter in a function
In the function declaration, you can then omit the specification of the
number of elements contained in the formal parameter array.
The compiler actually ignores this part of the declaration anyway; all the
compiler is concerned with is the fact that an array is expected as an argument
to the function and not how many elements are in it.
Example: a function that returns the minimum value from an array given as
parameter
int minimum (int values[10]);
We must modify the function definition if a different array size is needed !
int minimum (int values[]);
Syntactically OK, but how will the function know the actual size of the array ?!
int minimum (int values[], int numberOfElements);
4. // Function to find the minimum value in an array
#include <iostream>
using namespace std;
int minimum (int values[10], int numberOfElements){
int minValue, i;
minValue = values[0];
for ( i = 1; i < numberOfElements; ++i )
if ( values[i] < minValue )
minValue = values[i];
return minValue;
}
int main (void){
int array1[5] = { 157, -28, -37, 26, 10 };
int array2[7] = { 12, 45, 1, 10, 5, 3, 22 };
cout<<"array1 minimum: "<< minimum(array1, 5)<<endl;
cout<<"array2 minimum: "<< minimum(array2, 7)<<endl;
return 0;
}
int numberOfElements =
sizeof(values);
cout<<"array1 minimum: "<< minimum(array1)
<<endl;
cout<<"array2 minimum: "<< minimum(array2)
<<endl;
int values[ ]){
Example: Passing arrays as
parameters
OUTPUT:
array1 minimum: -
37
array2 minimum: 1
5. Array parameters are passed by reference !
Parameters of non-array type: passed by copying values
Parameters of array type: passed by reference
The entire contents of the array is not copied into the formal parameter array.
The function gets passed information describing where in the computer’s memory
the original array is located i.e. the starting location of the array. That is why we
only give the array name in the actual parameter.
int array1[5] = { 157, -28, -37, 26, 10 };
minimum(array1);
So, any changes made to the formal parameter array by the function are actually
made to the original array passed to the function, and not to a copy of the array.
This change remains in effect even after the function has completed execution and
has returned to the calling function.
6. Example: Array parameters are passed by
reference !
#include <iostream>
using namespace std;
void multiplyBy2(float array[], int n){
int i;
for ( i = 0; i < n; ++i ) array[i] *= 2;
}
int main(void){
float floatVals[4] = { 1.2f, -3.7f, 6.2f, 8.55f };
int i;
cout << "nBefore Function:n";
for ( i = 0; i < 4; ++i ) cout << floatVals[i] <<
"t";
cout << endl;
multiplyBy2(floatVals, 4);
cout << "nAfter Function:n";
for ( i = 0; i < 4; ++i ) cout << floatVals[i] <<
"t";
cout << endl;
OUTPUT:
Before Function:
1.2 -3.7 6.2
8.55
After Function:
2.4 -7.4 12.4
17.1
7. Pointers and Function Arguments
Recall that the C language passes arguments to functions by value. On exception are the
arrays where we only give the array name in the actual parameter.
Also, recall that the name of the array is a constant pointer which enables the called function
to change the values of the array of the calling function.
So, if we want the called function to alter a value of a variable in the calling function, we can
use pointer in the parameter which will pass the location of the variable.
/* interchange value of 2 variable */
void swap(int *x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
int main(void){
int a=3, b=5;
cout<<"before: a="<< a <<", b="<< b
<<endl;
swap(&a, &b);
cout<<"before: a="<< a <<", b="<< b
<<endl;
return 0;
OUTPUT:
Before: a=3, b=5
After: a=5, b=3
Main Memory
1000 2000
x =
&a=
y =
&b=
&1000 &2000
temp=3
3 5
5 3
*x=a
=
*y=b
=
a= b=
8. Example: Arrays & Pointers as parameters
void print1(int tab[], int N){
for(int i=0; i<N; i++)
cout<< tab[i] <<" ";
cout<<endl;
}
void print2(int tab[],int N){
for(int *ptr=tab; ptr<tab+N;
ptr++)
cout<< *ptr <<" ";
cout<<endl;
}
void print3(int *tab,int N){
for(int *ptr=tab; ptr<tab+N;
ptr++)
cout<< *ptr <<" ";
cout<<endl;
}
void print4(int *tab,int N){
for(int i=0; i<N; i++, tab++)
cout<< *tab <<" ";
cout<<endl;
int main(void) {
int a[5]={1,2,3,4,5};
print1(a,5);
print2(a,5);
print3(a,5);
print4(a,5);
return 0;
}
• The formal parameter can be declared as array
or pointer !
• In the body of the function, the array elements
can be accessed through indexes or pointers !
OUTPUT:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
9. Example: Arrays & Pointers as parameters
/* strLength: return length of string s */
int strLength(char *s){
int n;
for (n = 0; *s != '0'; s++)
n++;
return n;
}
char array[100]="Hello, world";
char *ptr="Hello, world";
cout<< strLength("Hello, world"); /* string constant */
cout<< strLength(array); /* char array[100]; */
cout<< strLength(ptr); /* char *ptr; */
The actual parameter can be declared as array or pointer !
10. Pointer as return type
A pointer can be returned from a function.
Allows the calling function to access and manipulate data of the called function.
Useful to return large data structures (ex: array) that cannot be returned by value.
Must be very careful about what/whose location is being returned
Do not return Pointers to Local Variables as they go out of scope once the function
exits, leading to undefined behavior if their addresses are returned.
Use Static or Dynamic Allocation: Use static variables or dynamically allocate
memory to ensure the pointer remains valid after the function returns.
Free Dynamically Allocated Memory: Always free dynamically allocated memory to
avoid memory leaks.
Function Declaration While Returning Pointer
dataType*
functionName(argument/parameter){
// function body
return ptr;
}
11. Example: Pointer as return type
int main(){
int *p;
p = fun1();
ShowIncrease(p,
"fun1");
p = fun2();
ShowIncrease(p,
"fun2");
delete p;
p = fun3();
ShowIncrease(p,
"fun3");
delete [] p;
p = fun4();
ShowIncrease(p,
"fun4");
return 0;
}
int* fun1(){
static int A = 10;
return &A;
}
int* fun2(){
int *B = new int(20); // *B =
20
return B;
}
int* fun3(){
int *C = new int[5]; //array
*C = 30; // C[0] = 30
return C;
}
int *fun4(){
int D = 40;
return &D;
}
void ShowIncrease(int *q, char
*f){
cout << f << "->" << *q <<
endl;
(*q)++;
cout << f< < "->" << *q <<
OUTPUT:
fun1->10
fun1->11
fun2->20
fun2->21
fun3->30
fun3->31
fun4-> error
main
*p=
fun1
A=10
fun2
B=
fun3
C=
fun4
D=40
30
*B=20
ShowIncrease(q,
f)
*q=p
*f="fun1"
*f="fun2"
*f="fun3"
*f="fun4"
A=11
*B=21
31
12. Function Pointer
Pointers that point to location of functions instead of variables.
They are used to store the address/location of a function definition and can be
used to call the function or pass it as an argument to another function.
In the declaration a function pointer, along with the pointer name, the return type and
parameter types of the function it points to need to be specified.
The syntax is as follows:
Example:
rType
(*functionPointer)(argument/parameter);
int subtract(int a, int b){
return a - b;
}
int add(int a, int b){
return a + b;
}
int multiply(int a, int b){
return a * b;
}
void Show1(char *s, int r){
cout << s << r << endl;
}
void Show2(char *s, int (*f)
(int,int)){
cout << s << f(15, 2) << endl;
}
int main() {
int (*funPtr) (int, int);
// Declaration
funPtr = add;// Reference
int r = funPtr(15, 2);//
r=add(15,2)
//Dereference and call the
function
cout << "Addition: " << r <<
endl;
funPtr = subtract;
r = funPtr(15,
2);//r=subtract(15,2)
Show1("Subtract: ", r);
Show1("Subtract: ",
funPtr(15,2));
Show1("Multiply: ",
OUTPUT:
Addition:
17
Subtract:
13
Subtract:
13
Multiply:
30
Multiply:
30
Addition:
17
13. When the function is short and fast, and when
we expect the function to be invoked very often,
it’s better (and more time effective) to write the
function code at each invocation.
A function compiled like this is called an inline
function by putting the keyword inline before
function header.
Asks the compiler to copy code into
program instead of making function call
Reduce function-call overhead
Compiler can ignore inline
Good for small, often-used functions
Inline functions
#include<iostream>
using namespace std;
inline int Fun(int p){
return (p * 2);
}
int main(void) {
int e = 1;
e = Fun( e ); // e =
2
e = Fun( e ); // e =
4
e = Fun( e ); // e =
8
cout << e <<endl;
return 0;
}
14. 14
Recursive & Recurrence
An object is recursive if it contains itself as part of it, or it is defined in terms of itself.
Recurrence relation
Mathematical Functions that defined by itself with one or more base cases –
Factorial numbers:
F1 = 1 (base case)
Fn = Fn-1 x n (recurrence relation)
Examples:
Fibonacci numbers:
F0 = 0 (base case 1)
F1 = 1 (base case 2)
Fn = Fn-1 + Fn-2 (recurrence relation)
Examples:
F4 = F3 + F2
F4 = F3 + F2 = F2 + F1 + F1 + F0 =
F4 = F3 + F2 = F2 + F1 + F1 + F0 = F1 + F0 + 1 + 1 + 0 =
F4 = F3 + F2 = F2 + F1 + F1 + F0 = F1 + F0 + 1 + 1 + 0 = 1 + 0+ 1 + 1 + 0 =
F4 = F3 x 3
F4 = F3 x 3 = F2 x 2 x 3 =
F4 = F3 x 3 = F2 x 2 x 3 = F1 x 1 x 2 x 3 =
F4 = F3 x 3 = F2 x 2 x 3 = F1 x 1 x 2 x 3 = 1 x 1 x 2 x 3
F4 = F3 x 3 = F2 x 2 x 3 = F1 x 1 x 2 x 3 = 1 x 1 x 2 x 3 = 6
F4 = F3 + F2 = F2 + F1 + F1 + F0 = F1 + F0 + 1 + 1 + 0 = 1 + 0+ 1 + 1 + 0 = 3
15. 15
Recursion Functions
Recursive functions
Functions that call themselves
Can only solve a base case
If not base case
Break problem into smaller problem(s)
Launch new copy of function to work on the smaller problem (recursive
call/recursive step)
Slowly converges towards base case
Function makes call to itself inside the return statement
Eventually base case gets solved
Answer works way back up, solves entire problem
16. int main(){
// factorial( i ) and display
result.
for ( int i = 0; i <= 3; i++ ){
unsigned long f =
factorial( i );
cout << i <<"! = "<< f <<endl;
}
OUTPUT:
0! = 1
1! = 1
2! = 2
3! = 6
Recursion Functions –
Example 1
// recursive definition of function
factorial
unsigned long factorial( unsigned long n )
{
if ( n <= 1 ) // base case
return 1;
else // recursive step
return n * factorial(n-1);
}
STACK
i=0;
f=factorial(0)
i=1;
f=factorial(1)
i=2;
f=factorial(2)
i=3;
f=factorial(3)
i=3; f=6
main() i=0; f=1
factorial(1)
1
i=1; f=1
factorial(0)
factorial(1)
factorial(2)
2
factorial(2) n=2;
2*factorial(1)
n=2; 2*1
factorial(0)
1
factorial(1)
1
factorial(1)
i=2; f=2
factorial(3)
6
factorial(3) n=3;
3*factorial(2)
n=2; 2*1
factorial(2)
factorial(1)
factorial(1)
1
n=2;
2*factorial(1)
factorial(2)
2
n=3; 3*2
main()
factorial(1)
factorial(2)
factorial(3)
factorial(0)
2*factorial(1
)
3*factorial(2
)
2*1
3*2
2*factorial(1
)
2*1
1
2
6
17. // recursive definition of function fibonacci
long fibonacci( long n ){
if ( n == 0 || n == 1 ) // base case
return n;
else // recursive step
return fibonacci(n-1) + fibonacci(n–2);
}
int main(){
// fibonacci( i ) and display result.
for ( int i = 0; i <= 5; i++ )
cout<<"Fibonacci("<<i<<") =
"<<fibonacci(i)<<endl;
return 0;
}
OUTPUT:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1
Fibonacci(3) = 2
Fibonacci(4) = 3
Fibonacci(5) = 5
Recursion Functions –
Example 2
18. // recursive definition of function gcd
int gcd( int u, int v ){
if ( v == 0 ) // base case
return u;
else // recursive step
return gcd(v, (u%v));
}
int main(){
cout<<"gcd(150, 35) = “ <<gcd(150, 35) <<endl;
cout<<"gcd(1026, 405) = "<<gcd(1026, 405)<<endl;
cout<<"gcd(83, 240) = “ <<gcd(83, 240) <<endl;
return 0;
}
OUTPUT:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1
Fibonacci(3) = 2
Fibonacci(4) = 3
Fibonacci(5) = 5
Recursion Functions –
Example 3
19. 19
Default Arguments
A default argument is a value provided for one or more parameter in a function declaration
that is automatically assigned by the compiler if no value is provided for those parameters in
function call.
If the value is passed for it, the default value is overwritten by the passed value.
If a function is declared and defined separately, the default values must be in the
declaration, not in definition.
In a function with multiple parameters, default values must be provided from the rightmost
parameter to the left. It means that if a parameter has a default argument, all parameters to
its right must also have default values.
Set defaults in function prototype
int myFunction( int x , int y = 2, int z = 3 );
myFunction(3)
x = 3, y and z get defaults (rightmost)
myFunction(3, 5)
x = 3, y = 5 and z gets default
myFunction(3, 5, 7)
x = 3, y = 5 and z = 7
20. Variable number of parameters
#include <iostream>
using namespace std;
int calc3(int x, int y, int z) {
return (x + y) / z;
}
int calc2(int x, int y) {
return calc3(x, y, 1);
}
int calc1(int x) {
return calc3(x, 10, 1);
}
int calc0(void) {
return calc3(20, 10, 1);
}
int main(void) {
cout << calc3( 30 , 20, 2 ) << endl;
cout << calc2( 30 , 20 ) << endl;
cout << calc1( 30 ) << endl;
cout << calc0( ) << endl;
return 0;
}
21. Default Parameters
#include <iostream>
using namespace std;
int calc(int x = 20, int y = 10, int z = 1) {
return (x + y) / z;
}
int main(void) {
cout << calc( 30 , 20, 2 ) << endl;
cout << calc( 30 , 20 ) << endl;
cout << calc( 30 ) << endl;
cout << calc( ) << endl;
return 0;
}
22. 22
Function Overloading
Function overloading
Functions with same name and different parameters
Should perform similar tasks
I.e., function to square ints and function to square floats
int square(int x) { return x * x; }
float square(float x) { return x * x; }
Overloaded functions distinguished by signature
Number of arguments
Argument types
Sequence of arguments
Not by the return type of the function
23. Functions with similar tasks
#include <iostream>
using namespace std;
int maximum_int(int x, int y) {
return x > y ? x : y;
}
long maximum_long(long x, long y) {
return x > y ? x : y;
}
double maximum_double(double x, double y) {
return x > y ? x : y;
}
float maximum_float(float x, float y) {
return x > y ? x : y;
}
int main(void) {
cout << maximum_int( 1 , 2 ) << endl;
cout << maximum_long( 1L , 2L ) << endl;
cout << maximum_float( 1.1F , 2.1F ) << endl;
cout << maximum_double( 1.1 , 2.1 ) << endl;
return 0;
}
24. Function Overloading
#include <iostream>
using namespace std;
int maximum(int x, int y) {
return x > y ? x : y;
}
long maximum(long x, long y) {
return x > y ? x : y;
}
double maximum(double x, double y) {
return x > y ? x : y;
}
float maximum(float x, float y) {
return x > y ? x : y;
}
int main(void) {
cout << maximum( 1 , 2 ) << endl;
cout << maximum( 1L , 2L ) << endl;
cout << maximum( 1.1F , 2.1F ) << endl;
cout << maximum( 1.1 , 2.1 ) << endl;
return 0;
}