5 Procedural Programming
A place for everything and everything in its place.
Reverend Charles Augustus Goodrich
We were told when writing a composition you begin by brainstorming your ideas. From there you create a basic outline of the main topics you would like to cover. You make this outline more detailed by adding subtopics and sub-subtopics. When you have the paper thoroughly outlined – and only then – you write the first draft – by hand. You edit and reedit the drafts until you are comfortable with the current draft. At that point – and not before – you start up the computer and begin typing the final copy.
Top-Down Design
Any task can be overwhelming when we only think of getting to the final result. But the reality is that all tasks actually consist of several smaller tasks each of which are more simple when addressed individually. An example is graduating from college.
As an example, every engineering student shares a common goal. To receive a degree in engineering. But how do we accomplish this?
Instead of thinking only of the final goal, break the task down into several smaller tasks. In this case graduating with degree in engineering can accomplished by successfully completing four tasks; successfully complete year one; successfully complete year two; successfully complete year three; and successfully complete year four.
The four subtasks do not explain how to perform the task just what has to be done. Instead we will select one and look at it in more depth – Successfully complete year two. And while you are in your second year there is no reason to be working on tasks that involve year three or year four.
Hierarchical Chart for Earning an Engineering Degree.
This is basis of top-down design; each task is broken down into the set of subtask that when combined complete the larger task. The subtasks are then broken down into the set of tasks that when completed will have completed the individual subtask. This is repeated until each item is trivial.
The diagram for earning an engineering degree in the figure is known as an hierarchical chart. It is a means of breaking down a task into all of its subtasks. It shows that while there may be a multitude of tasks that will have to be completed, at any single moment there is only one that is active at any given moment.
Top-down design provides a means to compartmentalize these processes so that we can plan what tasks will need to be done.
Hierarchical Chart
A means of planning the top-down design involves creating an hierarchical chart. The hierarchical chart is similar to a flow chart. But unlike a flow chart where the items show the sequence of steps that will be followed, the hierarchical chart lays out each task and its subtasks. It does not provide the order of running the tasks but instead it provides a means of planning identifying the tasks will have to be done.
Hierarchical Chart:
An hierarchical chart is a diagram in which each task is broken down into the smaller subtasks that comprise it.
Hierarchical Chart for Top-Down Programming.
Functions
- can be divided between many members of a development team. Each member might be responsible for only one function but when all joined into the program will provide the needed functionality.
- can be used multiple times. If a function only performs a single task, but that task is needed multiple times it only needs to be coded once.
- can be easily revised. It often occurs that a function will be have to be updated. When this occurs only a single portion fo the program will have to be changed.
-
can be more easily debugged. Since each function performs only a single task it will by its nature be a much smaller part of the program. If there is an error in it then the error is likely to be more easily found and corrected.
- Function Call
- To use a function you need to call it. The function call is a single line with the function handle, a set of of input variables, and a set of output variables
- Function Definition
- The function definition is the list of instructions or executable statements that are run when the function is called. For a local function it will start with the keyword function and finish with the keyword end.
Built-in Functions
Luckily for us there are a multitude of functions that are built into MatLab. We could not print without disp( … ) or fprintf( … ). We could not enter data into the program without input( … ). And without sqrt( … ) we would have to write our own code to calculate the square root of a number. These are examples of built-in functions.
Function Calls:
In MatLab, implementing a built-in function is done by making a function call as in the figure. The function call has three parts; the function name, the list of output variables, and the list of input parameters.
The output variable list and the input parameter list are optional. If the function does not return values to its driver function then there is no need for the output variables. Similarly, if the function does not require the driver to pass data to it for it to operate then > is no need for the input parameters. It is important that the parentheses be included even if the function does not require input data.
% Syntax of a MatLab Function Call
[output vars] = function_name(input vars);
>> date()
ans = 24-May-2019
Computational functions will more often have both inputs and outputs.
>> x = sqrt(42.0)
x=
6.4807
>>
function driver( )
% DRIVER driver( ) is the main or driver function for
the program
% Enter data
x = input('Enter the value for the square root: ');
s = sqrt(x);
fprintf('sqrt(%0.3f) = %0.3f\n', x, s);
end
>> driver()
Enter the value for the square root: 42
sqrt(42.000) = 6.481
Built-in Functions
MatLab has built-in functions that address many calculations. The basic trigonometry functions are listed in the table.
Function | Example | Description |
sin | y = sin(radians) | Sine of argument in radians |
cos | y = cos(radians) | Cosine of argument in radians |
tan | y = tan(radians) | Tangent of argument in radians |
sind | y = sind(degrees) | Sine of argument in degrees |
cosd | y = cosd(degrees) | Cosine of argument in degrees |
tand | y = tand(degrees) | Tangent of argument in degrees |
asin | radians = asin(y) | Inverse sine in radians |
acos | radians = acos(y) | Inverse cosine in radians |
atan | radians = atan(y) | Inverse tangent in radians |
asind | degrees = asind(y) | Inverse sine in degrees |
asind | degrees = acosd(y) | Inverse cosine in degrees |
atand | degrees = atand(y) | Inverse tangent in radians |
hypot | c = hypot(a, b) | Square root of the sum of squares (Pythagorean Theorem) |
Function | Example | Description |
exp | y=exp(x) | Base e exponential, y=ex |
log | y=log(x) | Natural logarithm |
log10 | y=log10(x) | Common logarithm (Base 10) |
log2 | y=log2(x) | Base 2 logarithm |
pow2 | y=pow2(x) | Base 2 power |
sqrt | y=sqrt(x) | Square root |
abs | y=abs(x) | Absolute value |
Overloaded Function:
An overloaded function is a function that while having a single function name performs different tasks depending upon the function signature.
function driver()
% DRIVER driver( ) is the main or driver function
for
the program
% Enter data
x = input('Enter the first leg: ');
y = input('Enter the second leg: ');
z = hypot(a, b);
fprintf('The right triangle has sides %f, %f, and %f\n', x, y, z);
end
>> driver()
Enter the first leg: 4
Enter the second leg: 3
The right triangle has sides 4.000, 3.000, and 5.000
Passing two values to a multivariate function
Function | Example | Description |
deg2rad | d = deg2rad(r) | Convert angle from degrees to radians |
rad2deg | r = rad2deg(d) | Convert angle from radians to degrees |
cart2pol | [theta rho] = cart2pol(x, y) | Transform Cartesian coordinates to polar or cylindrical – 2D |
cart2pol | [theta rho z] = cart2pol(x, y, z) | Transform Cartesian coordinates to polar or cylindrical – 3D |
cart2sph | [azimuth elevation r] = cart2sph(x, y, z) T | Transform Cartesian coordinates to spherical |
pol2cart | [x y] = pol2cart(theta rho) | Transform polar or cylindrical coordinates to Cartesian – 2D |
pol2cart | [x y z] = pol2cart(theta rho, z) | Transform polar or cylindrical coordinates to Cartesian – 3D |
sph2cart | [x, y, z] = sph2cart(azimuth, elevation, r) | Transform spherical coordinates to Cartesian |
There are two functions in the table that appear twice; cart2pol and pol2cart. These are overloaded functions; functions that have the same function name but depending upon the its function signature it does a different calculation or performs a different task. Each function has a unique signature consisting of the function name and the number of input parameters.
The number of output variables listed is the maximum number that can have values be returned from the function. It is possible to return fewer – or even zero – but the result may not be as expected. The function itself determines the number and type of values to return. It could be that a single variable in the output list could return a single value, or it could return a vector with multiple values, or could just result in a run time error.
Because of this, unless you know how the function will respond it is best to have the same number of variables as the function is designed to return.
function driver()
% DRIVER driver( ) is the main or driver function for
the program
% Enter data
x = input('Enter the x coordinate: ');
y = input('Enter the y coordinate: ');
[theta, radius] = cart2pol(x, y);
fprintf('\t\t(x, y)\t\tradius\t\tangle (rad)\n');
fprintf('\t(%0.2f, %0.2f) %10.2f %10.2f\n)', x, y, theta, radius);
end
>> driver()
Enter the x coordinates: 4
Enter the y coordinates: 3
(x, y) radius angle(rad)
-
(4.00, 3.00) 5.00 0.64
Returning different number of outputs values
While returning fewer values is useful, there is an issue. You cannot pick and choose which value to return. If you want the first only then you only need a single variable on the left of the assignment operator. But if you only want the second you must have two variables within the square brackets on the left. If you have only one – and even if you name with the second variable – it will receive the value in the first return variable.
Warning:
If you use fewer values than what is shown in the return variable list you may get unexpected results. Unless you know how it the function handles this it is best to provide variables for all of the return values.
Finding an appropriate built-in function
With the thousands of built-in functions that are available how do you 1. know what functions are available, and 2. know how to use the function?
MatLab provides you with many functions that are meant to be called from the command line, as compared to being coded into a script. Because of the way that they are commonly used these functions are usually given the moniker commands instead of functions. Two of these system command can help with finding and using built-in functions. They are lookfor and help.
lookfor:
lookfor is a system command that searches the function help files for a particular keyword.
Searching for a function
With the thousands of functions that are available how might you find the one that you need? lookfor is a system command for searching for a functions.
- % Syntax of the lookfor command
- >> lookfor keyword
Syntax of the lookfor command
Each built-in function contains a block of comments that are intended to provide help to the programming. The lookfor command functions by searching these help files for the keyword that you entered. If it finds the keyword then it returns the function name in which it was found and also a short description of the function (in the figure).
- >> lookfor cosine
- acosd Compute the inverse cosine in degrees for each element of X.
- cosd Compute the cosine for each element of X in degrees.
- acos Compute the inverse cosine in radians for each element of X.
- acosh Compute the inverse hyperbolic cosine for each element of X.
- cos Compute the cosine for each element of X in radians.
- cosh Compute the hyperbolic cosine for each element of X.
- >>
Example of the lookfor command
Help with a function
The lookfor command will provide you with a list of possible functions but it does not tell you how to implement the function in your script. What input parameters does it require? What are the outputs values? These can be found using the help command.
- % Syntax of the lookfor command
- >> help function name
Syntax of help command
-
>> help exp
-
exp Exponential.
-
exp(X) is the exponential of the elements of X, e to the X.
-
For complex Z = X+i*Y, exp(Z) = exp(X) * (COS(Y)+i*SIN(Y)).
-
See also expm1, log, log10, expm, expint.
-
Reference page exp
-
Other functions name exp
Example of the help command
Local Functions
“If you want it done right, do it yourself.”
-Napolean Bonaparte
Despite there being hundreds of built-in functions, and probably hundreds of thousands more that can be found in repositories, there is a need to be able to write your own.
Local Function:
A local function is a user defined function that is written outside of any other function. It can be called by any other function in the same script.
Top-down design demands that the program be broken down into a finite number of trivial tasks. These are not just tasks for which someone else has already written a function. These include specialized printing functions. Functions to perform inputs and error check those inputs. And most often, functions that simply perform some small set of calculations. It often makes sense to hide away the details of these functions and instead just use a function call.
Warning:
A common error in writing local functions is to embed them within another function. It is necessary that the entire local function, from the keyword function to the keyword end be completely outside of any other function. This includes the driver.
The most common type of the do-it-yourself function is a local function. This is a function whose function definition takes a form similar to that of the driver function. But the local function definition is written outside of the driver function or any other local function. Because of the importance of their being separate from all other functions, a common approach is to write each one after the current final keyword end of every other function.
A local function will have two parts; a function call and a function definition. The function definition is the set of executable statements for the function. It will take the same format as the driver function but must be completely outside of any other function.
Output Variables
The local function is very similar to the driver function that we have been using from the start. It begins with the keword function and concludes with the keyword end. On the first line, after the keyword function on the left side of the assignment operator is the list of output variables. There does not have to be an output variable and there is no upper limit to the number used. If there is not a return variable then it, and the = are omitted. This is the usual case in the driver function. If there is more than one then they listed separated by either commas or a space within a pair of square brackets.
[output vars] = function_name(input vars);
% Help comments for the local function
% Operations for the local function
end
Function Handle
Following the output variable list is the function name or what is known as the function handle.
Function Handle:
The function handle creates an association to the function. While it looks like variable name, the function handle is a structure that includes information about the function. This includes the function name, the type of function, and the file in which the function is written.
structure = functions(@f):
The built-in function functions returns the details of the function handle that is passed to the function. This includes function name, the type of function – whether built-in, local (scoped), nested, or anonymous, the file in which the function is stored, and the parent function for the function.
>> functions(function_handle)
function: 'function_handle'
type: 'scopedfunction'
file: 'functionsExample.m'
parentage: {'driver'}
Example of the functions command
Input Variables
There is no lower or upper limit on the number of parameters. You may create local functions that have no variables, or hundreds of variables, or any number in between. The figure Example of a local function shows a local function with two input parameters.
Input Variables:
The input variables do not currently exist but will be created when the local function is called. The values in these variables are copies of the values in the variables in the function call.
-
function driver( )
-
% DRIVER driver( ) is the main or driver function for
the program
-
% Input data
-
x = 5;
-
y = 3;
-
% Call the local function
-
z = local_function(y, x);
-
% Print the Results
-
fprintf('f(%f, %f) = %f\n', x, y, z);
-
end
-
% All local functions are written outside the driver
function r = local_function(base, power)
% LOCAL_FUNCTION r = local_function(s) is an example of a local
% function. Two values are passed in and one is returned
-
%Calculate the value of r
-
r = base.^(power);
-
end
-
>> driver( )
-
3.000 .^ 5.000 = 243.000
-
>>
Example of a local function
Comment:
It is not necessary that the variable names in the input parameter list be the same as the variables in the function call. It is often recommended that you provide different variable names for these variables to differentiate between the variable in the function call and the variable in the local function.
Output Functions
-
function driver( )
-
% DRIVER driver( ) is the main or driver function for
-
% the program
-
% Print the Splash Screen
-
print_header( );
-
end
-
% All local function definitions are written after the driver
-
function print_header( )
-
% PRINT_HEADER print_header( )
prints start up information
-
%Print the splash screen
-
fprintf('\n');
-
fprintf('This is the Splash Screen \n');
-
fprintf('It acknowledges the programmer and provides\n');
-
fprintf('distraction while
the program is loading\n');
-
end
-
>> driver()
-
This is the Splash Screen
-
It acknowledges the programmer
provides
-
distraction while
the program is loading
-
>>
Example of a splash screen function
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Set the inputs to the splash screen
-
name = 'Joe Bfstk';
-
current_date = '28 May 2019'
-
desc = 'Showing off the Splash Screen';
-
% Print the Splash Screen
-
print_header(name, current_date, desc);
-
end
-
% All local functions are written after the driver
-
function print_header(n, d, description)
-
% PRINT_HEADER print_header(n, d, desc)
prints start up information
-
%Print the splash screen
-
fprintf('\n');
-
fprintf('Name: %s\n', n);
-
fprintf('Date: %s\n', d);
-
fprintf('Desc: %s\n', desc);
-
fprintf('\n');
-
end
-
>> driver()
-
Name: Joe Bfstk
-
Date: 28 May 2042
-
Desc: Showing off the Splash Screen
-
>>
Splash screen function with input parameters
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Enter data
-
dist = 400.0;
-
vol = 28.0;
-
% Calculate the fuel efficiency
-
lpk = 100.*vol ./ dist;
-
% Print the results
-
print_results(dist, vol, lpk);
-
end
-
% Local functions are written after the driver
-
function print_results(d, f, e)
-
% PRINT_RESULTS print_results(dist, fuel, efficiency)
prints a formatted table
-
%Print the results as a table
-
fprintf('\n');
-
fprintf('Distance: %13.1f km\n', d);
-
fprintf('Fuel: %17.1f liters\n', f);
-
fprintf('Efficiency: %12.2f liters/100 km\n', e);
-
fprintf('\n');
-
end
-
>> driver( )
-
Distance: 425.3 km
-
Fuel: 29.7 liters
-
Efficiency: 6.98 liters/100 km
-
>>
Example of an output function.
Abstraction:
Abstraction is the process of reducing the complex nature of a program into smaller, and hopefully simpler steps. It is done using top-down design and the use of functions.
Input Functions
A means of entering data into a program has already been provided with the built-in function input. This function prompts the user and then receives the user’s data entry, storing it in s variable. It differentiates between numerical data and strings of text. It is, however, limited.
Wrapper Function:
A wrapper function is a function whose purpose is to call one or more other functions while performing a minimum of computation. It is a means of abstraction in that the implementation details are hidden from the outside.
The wrapper function can be used to combine multiple inputs into a single function while at the same time providing error checking all while keep the details out of the driver.
function driver( )
% DRIVER driver( ) is the main or driver function
% Enter data
distance = get_data('Distance driven: ');
volume = get_data('Fuel purchased: ');
% Call function to calculate efficiency
lpk = fuel_efficiency(distance, volume);
% Print the results
print_results(distance, volume, lpk);
end
% All local functions are written after the driver
function x = get_data(prompt)
% GET_DATA get_data(prompt) is a wrapper for input data
%Call the input function
x = input(prompt);
end
-
>> driver( )
-
Distance (km): 400.0
-
Fuel purchased (liters): 29.7
-
Distance: 425.3 km
-
Fuel: 29.7 liters
-
Efficiency: 6.98 liters/100 km
-
>>
As the example progressed we were able to remove details from the driver and replace them with simple function calls. By the end the driver did little more than just call other functions. All the details are handled in the local functions. This is the abstraction that was described earlier.
Local functions are are written outside of the driver function. This means that the function definition of a local function may not be within any other function. They are designed so they may be called from every other part of the program. This includes both the driver function – the function with the same name as the script file – and any other local function.
Nested Functions
There are programming applications in which applying abstraction suggests that you write a function, but the function has only a limited use. Perhaps it will only be used in a single function, or it requires input values that only exist within a function, or it uses parameters that must be defined before the function can even be defined. In these cases the use of a nested function can be useful.
Nested Function:
A function that is defined completely within another function is nested within that function. They are exist, and are thus callable, from within their parent function.
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Enter data
r = input('Enter the radius of the polygon (m): ');
-
% Nested function to calculate area
-
function a = areaPolygon(n)
-
% Area of a regular polygon
-
a = (r.^2) .* n .* sind(360 ./ n) ./ 2.0;
-
end
-
% Print areas
-
fprintf('Triangle: %10.2f m^2\n', areaPolygon(3));
-
fprintf('Square: %14.4f m^2\n', areaPolygon(4));
-
fprintf('Pentagon: %10.2f m^2\n', areaPolygon(5));
-
end
-
>> driver( )
-
Enter the radius of the polygon (m): 5
-
Triangle: 32.48 m^2
-
Square: 50.00 m^2
-
Pentagon: 59.44 m^2
-
>>
Anonymous Functions
There is a third type of function, that while often confused with nested functions, it is more like a local function. But in reality. they are really neither. These are anonymous functions.
function_handle = @(input parameters) expression;
Syntax of an anonymous function
An anonymous function is defined almost as if it were a single line expression. The difference is the addition of a declaration of a set of input parameters in the anonymous function.
Anonymous Function:
An anonymous function is a single executable line of code that is defined within another function.
Example
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Enter data
-
r = input('Enter the radius of the polygon (m): ' );
-
% Anonymous function to calculate area
-
areaPolygon = @(n, r) (r.^2) .* n .* sind(360 ./ n) ./ 2.0;
-
% Print areas
-
fprintf('Triangle: %10.2f m^2\n', areaPolygon(3));
-
fprintf('Square: %14.4f m^2\n', areaPolygon(4));
-
fprintf('Pentagon: %10.2f m^2\n', areaPolygon(5));
-
end
-
>> driver( )
-
Enter the radius of the polygon (m): 5
-
Triangle: 32.48 m^2
-
Square: 50.00 m^2
-
Pentagon: 59.44 m^2
-
>>
Example of an anonymous function
Anonymous functions or nested functions
Anonymous or Nested:
There are similarities and differences between anonymous functions and nested functions.
Similarites
- Defined within a parent function
- Only callable from the parent or from other nested or anonymous functions at the same level.
Differences
- Nested functions inherit any variables and their values from the parent function.
- Anonymous functions do not have access to variables in the parent function so the values must be passed to the function (encapsulation).
- Anonymous functions can be parameterized, that is any variable that is not passed to the function in the input variable list is a parameter that is fixed for the lifetime of the anonymous function.
Parameters in Anonymous Functions
-
function driver( )
-
% DRIVER driver( ) is the main or driver
function
-
% Enter data
-
a = input('Enter the first coefficient: ');
-
b = input('Enter the second coefficient: ' );
-
c = input('Enter the third coefficient: ' );
-
x = input('Enter the value of x: ' );
-
% Anonymous function to calculate quadratic
-
quadratic = @(x) a .* (x.^2) + b .* x + c;
-
% Print value of quadratic function
-
fprintf('f(%0.2f) = %0.2f n', x, quadratic(x));
-
end
-
>> driver()
-
Enter the first coefficient: 3
-
Enter the second coefficient: -2
-
Enter the third coefficient: 5
-
Enter the value of x: 3
-
f(3.00) = 26.00
-
>>
Example of parameters in an anonymous function
In the example in the figure Example of fixed parameters in an anonymous function the parameters for the quadratic equation are set before the function was defined. Since they do not appear in the variable list for the anonymous function they are made to be fixed parameters.
User entered anonymous functions
f = str2func(s):
When entering a function as a string of text it is necessary to create a function handle for this function. This is performed with the built-in function strcat. The input to this function is a string of text, s. The output is a function handle, f.
Example
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Get the anonymous function
-
f = getFunction( );
-
% Enter the input value
-
x = input('Enter the input value: ');
-
% Evaluate the anonymous function
-
y = f(x);
-
% Print results
-
fprintf('f(%0.2f) = %0.2f n', x, y);
-
end
-
function f = getFunction( )
-
% GETFUNCTION getFunction( ) is a local function that
-
% will allow the user to enter a string of text that can
-
% then be used as an anonymous function
-
%Enter the string
-
s = input('Enter the function expression: ', 's');
-
%Concatenate an @(x) on the front
-
s = strcat('@(x)', s);
-
%Transform s into a function handle
-
f = str2func(s);
-
end
-
>> driver( )
-
Enter the function expression: x.^2 - sin(x ./ 2)
-
Enter the input value: 2
-
f(2.00) = 3.16
-
>>
After the input parameters are concatenated onto the expression, the final step is for the string to be transformed into a function handle. This is performed with the built-in function str2func(string).
The ability to have the user enter the function at run time can be quite useful. Imagine that you have a program in which you estimate the first derivative of a function at at particular point. The problem is that you do not what the function will be until you run the program. It might be a quadratic, or a trig function, or something completely different. It would be useful to have the user enter the function after the program starts running and then it estimates the derivative of the function that was entered.
Passing Function Handles to Functions
Example
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Get the anonymous
function - use the function definition from before
-
f = get_function( );
-
%Enter the input value
-
x = input('Enter the tangent point: ');
-
-
% Estimate the derivative
-
fPrime = derivative(f, x);
-
% Print results
-
fprintf('f''(%0.2f) = %0.2f n', x, fPrime);
-
end
-
function m = derivative(f, x)
-
% DERIVATIVE m = derivative(f, x) is a local function
that estimates the derivative of a function. This
demonstrates passing a function to another function
-
dx = 0.01; % Small step size
-
m = (f(x + dx) - f(x)) ./ dx;
-
end
-
>> driver( )
-
Enter the function expression: x.^2
-
Enter the tangent point: 1
-
f'(1.00) = 2.01
-
>>
Estimating the derivative of a user entered function
Scope and Lifetime
When a function, whether it be a local function or a nested function, or an anonymous function, a block of memory is reserved for the function. This includes space for any variables that are created in the function. When the function exits, returning any values to the calling function the memory is erased and with it the function and its variables. The availability of the function to the program is a matter of its scope and its lifetime.
Scope
In terms of functions and variables the scope is much like a person’s scope. For each of us, our scope is where we can be accessed; where can someone speak with us or call us or send us a message. We can control our scope by setting where we will be allowed to be contacted. Perhaps you will allow someone to meet with you or call you in your office, but not at home. Your scope is then your office. Another term for the scope is the visibility.
With respect to a function the scope of the function is from where in the program the function be called. This is often refined to which other functions may call it. There is a clear difference between the scope of a local function and the scope of a nested function.
Recall that a local function can be called from the program driver or from any other local function. Thus the scope is any other local function or the main program driver function.
But nested functions can only be called from their parent function or other nested functions that are at the same level in the parent function. The scope for a nested function is thus its parent function and other nested functions in the parent function at the same level.
Scope of variables
So how is this different for variables?
Variables created within a local function or within the driver function are, by default, only accessible within the function. Thus their scope is the function in which they are declared.
Variables in nested functions are treated a bit differently. Recall that variables created in a function are available to any nested function that was defined within the function. Because of this a variable that is created in a function, whether it be a driver function, local function, or nested function, adds to its scope any nested functions that are defined within it.
Lifetime
For a person, scope is where the person can be contacted or is visible to those who want to contact them. Their lifetime is when they become visible to the time that they are no longer visible; or birth to death.
Lifetime:
The lifetime of a function or a variable is when it is visible. It is normally the time from when the function is defined or the variable is declared until either the end of the function of the end of the program.
This is similar for functions and variables. Whereas scope is the visibility, that is where it is available in the program, lifetime is when. It is a chronological measure. Scope is where the function or variable is visible, lifetime is when it is visible
Lifetime of a function
For a local function the lifetime of the function is the from when the program begins to when it ends. For a nested function the lifetime is from when the parent function is called until it returns.
Lifetime of a variable
The lifetime of a variable is much like the lifetime of a nested functions. The default behavior of variables are that they are created when they are first declared – that is memory is reserved and normally a value is stored in memory for the variable, and are deleted when the function in which they are declared returns. Thus their lifetime is from when the variable is created until the function in which it is created returns control to the calling function.
If the variable is declared in a local function and the function in turn calls another local function, the lifetime of the variable continues but not the scope. This is a result of the function no longer being active, having passed control to the other local function. But if the function calls a nested function then the variable continues with both its lifetime and its scope since variables are accessible within the parent’s nested function.
Encapsulation
Encapsulation:
While normally a term applied to object oriented programming, encapsulation is a mechanism for restricting access to variables that are created in a function. It requires that all outside data that is needed in a function be passed to the function through the input parameters, and all information be returned to the driver function through a return variable. It is also known as information hiding.
Local functions and anonymous functions operate on the concept of ecapsulation. This means that all variables are by default hidden within the function in which they are created. Further, they are inaccessible from outside of the function unless they are explicitly passed to another function.
In this description, which may seem like a scene out of Tron, the function is completely isolated from the rest of the program. The function cannot access the outside variables. Instead the function must wait until the calling function provides it with the values in the variable. At no point can the function read or write to the outside variables. This is known as passing by value.
Pass By Value:
A parameter is passed by value when the calling function has a variable that contains data. At the same time the function being called creates a new, separate and independent, variable. The value in the calling function variable is then copied into the new function variable. If the function modifies its local variable, the change has no effect on the calling function variable.
Local Variables
The new variable within the called function can have a different variable name than the variable in the calling function or it can have the same name. If you use the same variable name in the calling function as you do in the function that is being called, it is important to understand that there are now two separate variables with the same name but different scopes.
Note that the the variable x in the driver – whose value of is passed to the function – is a different variable than the variable x that is created to accept the value from the calling function.
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Enter data into the program
-
x = input( 'Enter a value for x: ');
-
%Call a local function
-
y = calculation_function(x);
-
% Print x and y
-
fprintf('Driver (x, y) = (%0.2f, %0.2f)\n', x, y);
-
end
-
function m = calculation_function(x)
-
% CALCULATION_FUNCTION m = calculation_function(x) is a local
-
% function that's purpose is to demonstrate that data that is
-
% passed by value creates separate variables
-
m = x.^2 - 3;
-
% Change x
-
x = x + 5;
-
% Print x and y
-
fprintf('Function (x, m) = (%0.2f, %0.2f)\n', x, m);
-
end
-
>> driver( )
-
Enter a value for x: 3
-
Function (x, m) = (8.00, 6.00)
-
Driver (x, y) = (3.00, 6.00)
-
>>
Demonstrating the separation of variables in pass by value
To avoid any confusion use a different variable name in the function from which the data is passed than the variable name in the parameter list of the function which is being called.
Global Variables
The default of making variables local is important in supporting the goal of encapsulation. By keeping variables within their own function creates data integrity. A function that uses a variable that may have the same name as that in another function cannot change the value of the second variable.
Global Variables:
A global variable is a variable whose value is retained in memory after the function returns control. The value can then be shared by several functions. Its scope is all of the functions in which is declared as global. Its lifetime is the life of the program.
But there are instances when relaxing the control created by encapsulation can be useful.
You are writing a program to calculate deflections in a beam. Regardless of the loading on the beam the modulus of elasticity and the area moment of inertia will remain the same throughout the program. All of the functions that use these parameters are fixed and must remain the same for the run. But they may change the next time that the program is run. To guarantee that all of the functions use the same value for the parameters you would like to make the variables that store the parameters available to several different local functions.
-
global var
-
var = value;
Syntax for Declaring a Global Variable
-
function driver( )
-
% DRIVER driver( ) is the main or driver function
-
% Create global variables
-
global E;
-
global I;
-
% Enter Dimensions and Load
-
a = input('Width of cross section (m): ');
-
L = input('Length of beam (m): ');
-
W = input('Load on beam (pounds): ');
-
% Set the parameters
-
E = 29.0e06;% Modulus
-
I = a.^4 ./ 12;% Moment of Inertia
-
%maximum deflection
-
dPoint = deflectionCenterLoad(W, L);
-
dUniform = deflectionUnifLoad(W, L);
-
fprintf('\n Deflection of a Beam\n');
-
fprintf('Point Load: %10.2f in\n', dPoint);
-
fprintf('Uniform Load: %8.2f in\n', dUniform);
-
end
-
function d = deflectionCenterLoad(w, length)
-
% DEFLECTIONCENTERLOAD d = deflectionCenterLoad(w, l)
-
% calculates the center deflection of a beam with
a center of the beam
-
% Global Parameters
-
global E;% Modulus
-
global I;% Moment of Inertia
-
% Deflection
-
d = w .* (length.^4) ./ (48 .* E .* I .* length);
-
end
-
function d = deflectionUnifLoad(w, length)
-
% DEFLECTIONUNIFLOAD d = deflectionUnifLoad(w, length)
-
% calculates the center deflection of a beam of length with
-
% load spread uniformly across beam
-
% Global Parameters
-
global E;% Modulus
-
global I;% Moment of Inertia
-
w = W ./ length;
-
% Deflection
-
d = 5 .* w .* (length.^4) ./ (384.*E.*I);
-
end
-
>> driver( )
-
Cross sectional width (m):
-
Length of beam (m):
-
Total load on beam (pounds):
-
Center Deflection of a Beam
-
Point Load: m
-
Uniform Load: m
-
>>
Using beam deflection calculations to demonstrate using a global variable as a parameter
-
global counter; % Set to zero the first time it is called
-
counter = counter + 1;
Creating a global variable counter
Summary