Chapter Four
Functions
By Tesfahun
N.
Outlines
What is function
Declaring ,defining and calling function
Global vs local variable ?
Scope operator
Automatic vs static variable
Function parameters and arguments
passing by values and reference
What is a function?
What is a function?
Function is a block of code designed to tackle a specific
problem.
Function Basics
One of the best ways to tackle a problem is to start with the
overall goal, then divide this goal into several smaller tasks.
If your program does a lot, break it into several functions. Each
function should do only one primary task.
cont.…
Summarized function basics.
C++ functions generally adhere to the following rules.
1. Every function must have a name, rules that apply to naming
variables are
They can contain up to 32 characters,
they must begin with a letter, and they can consist of letters, numbers,
and the underscore (_) character.
2. All function names have one set of parenthesis immediately
following them.
3 The body of each function, starting immediately after
parenthesis
Cont…
Syntax of function
return_type function_name(parameter_list)
{
// Function body
// Statements to perform the desired task
return return_value; // Optional if the function has
a
}
Declaring, defining and calling functions
Declaring function:
A function declaration specifies the function's name, return
type, and parameters (if any).
It's also known as the function prototype.
It consists of three entities:
The function return type. This specifies the type of value
the function returns. A function which returns nothing
should have a return type void.
The function name. this is simply a unique identifier
The function parameters (also called its signature). This is a
set of zero or more typed identifiers used for passing
values to and from the function.
Eg . int add(int a, int b);
cont.…
Defining a function:
A function definition consists of two parts: interface
(prototype) & body. The brace of a function contains the
computational steps (statements) that computerize the function.
The definition consists of a line called the decelerator.
If function definition is done before the main function, then
there is no need to put the prototype, otherwise the prototype
should be scripted before the main function starts.
eg . int add(int a, int b) {
return a + b;
}
Scenario 1: Function Definition Before main (No
Prototype Needed)
If you define the function before the main
function, the compiler already knows about the
function when it encounters a call to that function
in main, so a prototype is not necessary.
Example:
#include <iostream>
// Function definition
void greet() {
std::cout << "Hello, World!" << std::endl;
}
int main() {
greet(); // No need for a prototype, as greet() is defined
before main()
return 0;
}
• Scenario 2: Function Definition After main
(Prototype Needed)
• If you define the function after the main function,
you must declare a prototype before main so that
the compiler knows about the function when it is
called.
Cont…
#include <iostream>
// Function prototype
void greet();
int main() {
greet(); // Compiler knows about greet() because of the
prototype
return 0;
}
// Function definition
void greet() {
std::cout<< "Hello, World!" << std::endl;
}
cont…
Calling the function:
Calling a function means making the instruction of the function to be
executed.
A function call consists of the function name followed by the call
operator brackets‘()’, inside which zero or more comma-separated
arguments appear.
When a function call is executed, the arguments are first evaluated
and their resulting values are assigned to the corresponding parameters.
Eg . int result = add(5, 3);
cont…
#include <iostream>
// Function declaration (prototype)
int add(int a, int b);
int main() {
// Function call
int result = add(5, 3);
std::cout << "Result: " << result << std::endl;
return 0;
}
// Function definition
int add(int a, int b) {
return a + b;
}
cont…
#include <iostream.h> // function example
int addition (int a, int #include <iostream.h>
b);declaration int addition (int a, int b)
int main () {
{ int r;
r=a+b;
int z= addition (5,3);//call
return (r);
cout << "The result is " << z;
}
return 0; int main ()
} {
int addition (int a, int b)//definition int z= addition (5,3);
{ cout << "The result is " << z;
int r; return 0;
r=a+b; }
return (r);}
Global versus local variables
Global variables are visible (“known”) from their point of
definition down to the end of the program.
Variables defined within a local scope are visible to that
scope only.
Local Variables:
•Definition: A local variable is a variable that is
declared inside a function or a block and can only
be accessed within that function or block.
•Scope: Limited to the function or block in which it
is declared.
•Lifetime: Exists only during the execution of the
function/block and is destroyed when the
function/block finishes execution.
#include <iostream>
void printNumber() {
int x = 10; // Local variable
std::cout << "Inside printNumber function: " << x <<
std::endl;
}
int main() {
int x = 5; // Local variable
printNumber();
std::cout << "Inside main function: " << x << std::endl;
return 0;
}
2. Global Variables:
Definition: A global variable is a variable that is
declared outside of all functions and is accessible
from any function within the program.
Scope: Accessible throughout the entire program,
in all functions.
Lifetime: Exists for the entire duration of the
program's execution.
#include <iostream>
int globalVar = 20; // Global variable
void printGlobal() {
std::cout << "Inside printGlobal function: " << globalVar <<
std::endl;
}
int main() {
std::cout << "Inside main function: " << globalVar <<
std::endl;
globalVar = 50; // Modify global variable
printGlobal();
return 0;
}
Scope Operator
Because 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.
int num1;
void fun1(int num1)
{
//…
}
The global num1 is inaccessible inside fun1(), because it is
overridden by the local num1 parameter.
cont…
This problem is overcome using the scope operator ‘::’
which takes a global entity as argument.
int num1 = 2;
void fun1(int num1)
{
//…
num1=33;
cout<<num1; // the out put will be 33
cout<<::num1; //the out put will be 2 which is the global
if(::num1 != 0)//refers to global num1
//…
}
Automatic versus static variables
Automatic Variables:
Automatic variables are those declared inside a block or
function without the static keyword.
They are created when the block is entered and destroyed
when the block is exited.
They have automatic storage duration, meaning they exist only
within the scope in which they are declared.
Automatic variables are typically allocated on the stack.
Eg. void function() {
int x = 10; // automatic variable
// x exists only within the scope of this function
}
Automatic versus static variables
Static Variables:
Static variables are declared using the static keyword.
They have static storage duration, meaning they persist
throughout the program's execution.
Static variables are initialized only once before the program
starts execution, and they retain their value between function
calls.
They are typically allocated in the data segment of the
program's memory.
Static variables can be declared inside functions, in which case
they are local to the function and retain their value between calls
cont…
void function() {
static int count = 0; // static variable
count++; // retains its value between function calls
}
In summary, automatic variables are created and destroyed
automatically within the scope of a block or function, while
static variables persist throughout the program's execution and
retain their values between function calls
cont…
#include <iostream>
void function1() {// Function with automatic variable
int x = 10; // automatic variable
std::cout << "Inside function1, x = " << x <<
out put
std::endl;
}
void function2() {// Function with static variable
static int y = 5; // static variable Inside main, a = 20
y++; // increment each time the function is called
std::cout << "Inside function2, y = " << y << Inside function1, x = 10
std::endl;
} Inside function1, x = 10
int main() {
// Automatic variable Inside function2, y = 6
int a = 20; // automatic variable
std::cout << "Inside main, a = " << a << Inside function2, y = 7
std::endl;
function1(); // Call function1
function1(); // Call function1 again
function2(); // Call function2
function2(); // Call function2 again
return 0;
}
cont…
If static variables are not declared explicitly, they will be
declared to 0 automatically.
Eg. void my_fun()
{
static int num;
static int count = 2;
count=count*5;
num=num+4;
}
cont…
In the above example:
During the first call of the function my_fun(), the static variable count
will be initialized to 2 and will be multiplied by 5 at line three to have
the value 10. During the second call of the same function count will
have 10 and will be multiplied by 5.
During the first call of the function my_fun(), the static variable num
will be initialized to 0 (as it is not explicitly initialized) and 4 will be
added to it at line four to have the value 4. During the second call of
the same function num will have 4 and 4 will be add to it again.
N.B. if local variables are static, their values remain in case the
function is called again
Function Parameters and
arguments
The parameters of a function are list of variables used by the
function to perform its task and the arguments passed to the
function during calling of a function are values sent to the
function.
The arguments of function calling can be using either of the
two supported styles in C++: passing by value or passing by
reference.
Passing by value:
A value parameter receives a copy of only the value of the
argument passed to it. As a result, if the function makes any
changes to the parameters, this will not affect the argument.
For instance:
#include <iostream>
void modifyValue(int x) {
x = x + 10; // Modify the value of x
}
int main() {
int a = 5;
modifyValue(a);
std::cout << "a: " << a << std::endl; // Output: a: 5
return 0;
}
Passing by Reference:
A reference parameter, on the other hand,
receives the argument passed to it and works on
it directly.
Any change made by the function to a reference
parameter is in effect directly applied to the
argument.
Passing parameters in this way is called pass-by-
reference.
Taking the same example above:
• #include <iostream>
void modifyReference(int &x) {
x = 10; // Modify the value of x
}
int main() {
int a = 5;
modifyReference(a);
std::cout << "a: " << a << std::endl; // Output: a: 10
return 0;
}
cont.…
Inline function in C++
In C++, an inline function is a function that the compiler treats
differently than a regular function during the compilation process.
When you declare a function as inline, you're suggesting to the
compiler that you'd prefer to substitute the function call with the
actual body of the function at the call site rather than performing a
traditional function call.
The "inline" keyword is merely a hint to the compiler or development
environment.
inline returnType functionName(parameters) {
// Function body
}
Example
#include <iostream>
// Inline function to calculate the square of a number
inline int square(int x) {
return x * x;
}
int main() {
int num = 5;
// Calling the inline function
int result = square(num);
std::cout << "Square of " << num << " is: " << result << std::endl;
return 0;
}
Default arguments and function overloading
C++ has two capabilities that regular C doesn’t have. Default
arguments and function overloading.
4.9.1. Default arguments
In C++, default arguments allow you to provide default values for function
parameters.
This means that if a caller does not provide a value for a parameter, the
default value specified in the function declaration will be used instead.
Here's the syntax for defining a function with default arguments:
returnType functionName(type1 param1 = defaultValue1, type2 param2 =
defaultValue2, ...);
Cont
#include <iostream>
// Function with default arguments
void printMessage(std::string message = "Hello, World!") {
std::cout << message << std::endl;
}
int main() {
// Call the function without providing any arguments
printMessage(); // Output: Hello, World!
// Call the function with an argument
printMessage("Greetings!"); // Output: Greetings!
return 0;
}
#include…..
void Add_Display(int x=10, int y=20, int z=30)
{
cout<< (x+y+z);
}
void Mult_Dispaly (int x, int y=70)
{
cout<< (x*y);
}
void main()
{
int a=40, b=50, c=60;
Add_Display(a,b,c); //will print 150 (ie 40+50+60)
Add_Display(a,b); //will print 120 (ie 40+50+30)
Add_Display(a); //will print 90 (ie 40+20+30)
Add_Display(); //will print 60 (ie 10+20+30)
Mult_Display(a,b) //will print 2000 (40*50)
Mult_Display(a) //will print 2800 (40*70)
//Mult_Display() //is invalid as there is no default for x
getch();
}
Overloaded Functions
In C++, function overloading allows you to define multiple
functions with the same name but with different parameter
lists.
This means you can have multiple functions with the same
name as long as they have different parameters.
When you call an overloaded function, the compiler
determines which version of the function to call based on the
number and types of arguments provided.
Cont.…
int iabs(int i)
{
if(i<0)
Return (i*-1);
else
Return (i);
}
float fabs(float x)
{ if(x<0.0)
Return (x * -1.0);
else
Return (x);
}
float abs(float x);
int main()
{
…
ians = abs(i);//calling abs with int arguments
fans = abs(p);//calling abs with float arguments
…
}
int abs(int i)
{
if(i<0)
Return i*-1;
else
Return I;
}
float abs(flaot x)
{
if(x<0.0)
Return x*-1.0;
else
Return x;
}
Cont…
#include <iostream>
using namespace std;
// Function to add two integers
int add(int a, int b) {
return a + b;
}
// Function to add three integers
int add(int a, int b, int c) {
return a + b + c;
}
// Function to concatenate two strings
string add(string str1, string str2) {
return str1 + str2;
}
int main() {
int sum1 = add(5, 3); // Calls the first add function
int sum2 = add(2, 4, 6); // Calls the second add function
string combined = add("Hello, ", "world!"); // Calls the third add function
cout<<"Sum of 5 and 3 is: " <<sum1 << endl;
cout<< "Sum of 2, 4, and 6 is: " <<sum2 << endl;
cout << "Concatenated string: " <<combined <<endl;
return 0;
}
4.10. Recursion
A function which calls itself is said to be recursive.
Recursion is a general programming technique applicable to problems which
can be defined interms of themselves.
Take the factorial problem, for instance which is defined as:
- factorial of 0 is 1
- factorial of a positive number n is n time the factorial of n-1.
The second line clearly indicates that factorial is defined in terms of itself
and hence can be expressed as a recursive function.
int Factorial(unsigned int n )
{
return n = = 0 ? 1 : n * factrial(n-1);
}
.11. Recursion versus iteration
#include <iostream>
// Recursive function to calculate the factorial of a non-negative integer
unsigned long long factorial(int n) {
// Base case: factorial of 0 is 1
if (n == 0) {
return 1;
} else {
// Recursive case: factorial of n is n * factorial(n - 1)
return n * factorial(n - 1);
}
}
int main() {
int number;
std::cout << "Enter a non-negative integer: ";
std::cin >> number;
if (number < 0) {
std::cerr << "Factorial is not defined for negative numbers." << std::endl;
return 1;
}
unsigned long long result = factorial(number);
std::cout << "Factorial of " << number << " is: " << result << std::endl;
return 0;
}
• fibonacci() reading Assignment
Recursion versus iteration
Both iteration and recursion are based on control structure. Iteration
uses a repetition structure (such as for, while, do…while) and recursive
uses a selection structure (if, if else or switch).
Both iteration and recursive can execute infinitely-an infinite loop
occurs with iteration if the loop continuation test become false and
infinite recursion occurs id the recursion step doesn’t reduce the
problem in a manner that coverage on a base case.
Recursion has disadvantage as well. It repeatedly invokes the
mechanism, and consequently the overhead of method calls. This can
be costly in both processor time and memory space. Each recursive
call creates another copy of the method (actually, only the function’s
variables); this consumes considerable memory.
N.B: Use recursion if:
1. A recursive solution is natural and easy to understand
2. A recursive solution doesn’t result in excessive duplicate
computation.
3. the equivalent iterative solution is too complex and
4. of course, when you are asked to use one in the exam!
Thanks
?