Uploaded by jpn.jayasankar

C Functions

advertisement
C FUNCTIONS
-INDEPENDENT ROUTINE WHICH DO A SPECIFIC
TASK(S)-
www.tenouk.com, ©
1/66
C FUNCTIONS
Some definition: A function is a named, independent section of C code that
performs a specific task and optionally returns a value to the calling program
or/and receives values(s) from the calling program.
 Basically there are two categories of function:
1. Predefined functions: available in C / C++
standard library such as stdio.h, math.h,
string.h etc.
2. User-defined functions: functions that
programmers create for specialized tasks
such as graphic and multimedia libraries,
implementation extensions or dependent
etc.
www.tenouk.com, ©
2/66
C FUNCTIONS

Let try a simple program example that using a simple user defined
function,
www.tenouk.com, ©
3/66
C FUNCTIONS

The following statement call cube() function, bringing
along the value assigned to the fInput variable.
fAnswer



=
cube(fInput);
When this statement is executed, program jump to the
cube() function definition.
After the execution completed, the cube() function returns
to the caller program (main()), assigning the returned
value, fCubeVolume to fAnswer variable for further
processing (if any).
In this program the scanf() and print() are examples
of the standard predefined functions.
www.tenouk.com, ©
4/66
C FUNCTIONS
 Basically a function has the following characteristics:
1. Named with unique name .
2. Performs a specific task - Task is a discrete job that the
program must perform as part of its overall operation, such
as sending a line of text to the printer, sorting an array into
numerical order, or calculating a cube root, etc.
3. Independent - A function can perform its task without
interference from or interfering with other parts of the
program.
4. May receive values from the calling program (caller) Calling program can pass values to function for processing
whether directly or indirectly (by reference).
5. May return a value to the calling program – the called
function may pass something back to the calling program.
www.tenouk.com, ©
5/66
C FUNCTIONS
Function Mechanism
 C program does not execute the statements in
a function until the function is called.
 When it is called, the program can send
information to the function in the form of one or
more arguments although it is not a mandatory.
 Argument is a program data needed by the
function to perform its task.
 When the function finished processing,
program returns to the same location which
called the function.
www.tenouk.com, ©
6/66
C FUNCTIONS
 The following figure illustrates function calls (also the memory’s
stack record activation – construction & destruction.
www.tenouk.com, ©
7/66
C FUNCTIONS


Function can be called as many
times as needed as shown for
function_2(…).
Can be called in any order
provided that it has been
declared (as a prototype) and
defined.
www.tenouk.com, ©
8/66
C FUNCTIONS
Stack and Heap





Each process in a multi-tasking OS runs in its own memory area.
This area is the virtual address space, which in 32-bit mode, is always a
4GB block of memory addresses.
These virtual addresses are mapped to physical memory by page tables,
which are maintained by the OS’s kernel and consulted by the processor.
Each process has its own set of page tables.
More info at: Anatomy of program in memory.
www.tenouk.com, ©
9/66
C FUNCTIONS
 As an example, the standard program’s/executable’s/binary’s segment
layout in a Linux process is shown in the following figure.
 The bands in the address space are correspond to memory segments
like the heap, stack, and so on.
www.tenouk.com, ©
10/66
C FUNCTIONS








Stack and heap are two memory sections in the user mode space.
Stack will be allocated automatically for function call.
It grows downward to the lower address.
It is Last-in First-out (LIFO) mechanism (tally with the assembly
language’s push and pop instructions)
Meanwhile, heap will be allocated by demand or request using C
memory management functions such as malloc(), memset(),
realloc() etc.
It is dynamic allocation, grows upward to the higher memory
address.
By request means we need to release the allocation manually
using C functions such as free() and delete (if using new
keyword).
In a multi-threaded environment each thread will have its own
completely independent stack but they will share the heap as
needed.
www.tenouk.com, ©
11/66
C FUNCTIONS
 malloc() & free()
example
 malloc() without free()
example
www.tenouk.com, ©
12/66
C FUNCTIONS



By referring the previous function calls example, the stack should be in
the equilibrium condition.
By considering the stack area of memory, the following figure illustrates
the condition of stack for function call.
In this case, main() function has 3 function calls: function_1(),
function_2() and function_3().
www.tenouk.com, ©
13/66
C FUNCTIONS


The following is what a typical stack frame might look like.
Smaller numbered/lower memory addresses are on top.
www.tenouk.com, ©
14/66
C FUNCTIONS

This would be the contents of the stack if we have a
function MyFunct() with the prototype,
int MyFunct(int arg1, int arg2, int arg3) ;





and in this case, MyFunct() has two local int variables.
(We are assuming here that sizeof(int) is 4 bytes).
The stack would look like this if the main() function
called MyFunct() and control of the program is still
inside the function MyFunct().
main() is the "caller" and MyFunct() is the "callee".
The ESP register is being used by MyFunct() to point to
the top of the stack.
The EBP register is acting as a "base pointer".
www.tenouk.com, ©
15/66









C FUNCTIONS
The arguments passed by main() to MyFunct() and the local
variables in MyFunct() can all be referenced as an offset from the
base pointer.
The convention used here (cdecl) is that the callee is allowed to mess
up the values of the EAX, ECX and EDX registers before returning.
Depend on the calling convention used: cdecl, stdcall or
fastcall
So, if the caller wants to preserve the values of EAX, ECX and EDX, the
caller must explicitly save them on the stack before making the
subroutine call.
On the other hand, the callee must restore the values of the EBX, ESI
and EDI registers.
If the callee makes changes to these registers, the callee must save the
affected registers on the stack and restore the original values before
returning.
Parameters passed to MyFunct() are pushed on the stack.
The last argument is pushed first so in the end the first argument is on
top.
Local variables declared in MyFunct() as well as temporary variables
are all stored on the stack.www.tenouk.com, ©
16/66
C FUNCTIONS
www.tenouk.com, ©
17/66
C FUNCTIONS



Return values of 4 bytes or less are stored in the EAX
register.
If a return value with more than 4 bytes is needed,
then the caller passes an "extra" first argument to the
callee.
This extra argument is address of the location where
the return value should be stored. i.e., in C jargon the
function call,
x = MyFunct(a, b, c);

is transformed into the call,
MyFunct(&x, a, b, c);

Note that this only happens for function calls that
return more than 4 bytes.
www.tenouk.com, ©
18/66
C FUNCTIONS
Function Definition

Is the actual function body, which contains the code
that will be executed as shown below (previous
example).
int
{
cube(int fCubeSide)
// local scope (local to this function)
// only effective in this function 'body'
int
fCubeVolume;
// calculate volume
fCubeVolume = fCubeSide * fCubeSide * fCubeSide;
// return the result to caller
return
fCubeVolume;
}
www.tenouk.com, ©
19/66
C FUNCTIONS




First line of a function definition is called the function
header, should be identical to the function prototype,
except the semicolon.
Although the argument variable names (fCubeSide in this
case) were optional in the prototype, they must be included
in the function header.
Function body, containing the statements, which the
function will perform, should begin with an opening brace
and end with a closing brace.
If the function returns data type is anything other than void
(nothing to be returned), a return statement should be
included, returning a value matching the return data type
(int in this case).
www.tenouk.com, ©
20/66
C FUNCTIONS
The Function header

The first line of every function definition is called function header. It has 3
components, as shown below,
1. Function return type - Specifies the data type that the function should
returns to the caller program. Can be any of C data types: char, float,
int, long, double, pointers etc. If there is no return value, specify a
return type of void. For example,
int
float
void
calculate_yield(…) // returns an int type
mark(…)
// returns a float type
calculate_interest(…) // returns nothing
www.tenouk.com, ©
21/66
C FUNCTIONS
1. Function name - Can have any name as long as the
rules for C / C++ variable names are followed and
must be unique.
2. Parameter list - Many functions use arguments, the
value passed to the function when it is called. A
function needs to know the data type of
each argument. Argument type is provided in the
function header by the parameter list. Parameter list
acts as a placeholder.
www.tenouk.com, ©
22/66
C FUNCTIONS


For each argument that is passed to the function, the
parameter list must contain one entry, which specifies the
type and the name.
For example,
void myfunction(int x, float y, char z)
void yourfunction(float myfloat, char mychar)
int ourfunction(long size)


The first line specifies a function with three
arguments: type int named x, type float named y
and type char named z.
Some functions take no arguments, so the parameter list
should be void or empty such as,
long thefunction(void)
void testfunct(void)
int zerofunct()
www.tenouk.com, ©
23/66
C FUNCTIONS



Parameter is an entry in a function header. It serves as a
placeholder for an argument. It is fixed, that is, do not change
during execution.
The argument is an actual value passed to the function by the
caller program. Each time a function is called, it can be
passed with different arguments.
A function must be passed with the same number and type of
arguments each time it is called, but the argument values can
be different.
Function
example:
parameter and
argument
www.tenouk.com, ©
24/66
C FUNCTIONS
For the first function call:
Then, the second function call:






Each time a function is called, the different arguments are passed to
the function’s parameter.
z = half_of(y) and z = half_of(x), each send a different
argument to half_of() through the k parameter.
The first call send x, which is 3.5, then the second call send y, which
is 65.11.
The value of x and y are passed (copied) into the parameter k of
half_of().
Same effect as copying the values from x to k, and then y to k.
half_of() then returns this value after dividing it by 2.
www.tenouk.com, ©
25/66
The Function Body








C FUNCTIONS
Enclosed in curly braces, immediately follows the function header.
Real work in the program is done here.
When a function is called execution begins at the start of the
function body and terminates (returns to the calling program) when
a return statement is encountered or when execution reaches
the closing braces (}).
Variable declaration can be made within the body of a function.
Which are called local variables. The scope, that is the visibility
and validity of the variables are local.
Local variables are the variables apply only to that particular
function, are distinct from other variables of the same name (if any)
declared elsewhere in the program outside the function.
It is declared, initialized and use like any other variable.
Outside of any functions, those variables are called global
variables.
www.tenouk.com, ©
26/66
C FUNCTIONS

Function program example: local and global variable

The function parameters are considered to be variable
declarations.
Function prototype normally placed before main() and your
function definition after main() as shown below.
For C++, the standard said that we must include the prototype but
not for C.


www.tenouk.com, ©
27/66
#include …
/* function prototype
*/
int funct1(int);
C FUNCTIONS
But it is OK if we directly declare and define the function
before main() as shown below.
#include …
int main()
{
/* function call
*/
int y =
funct1(3);
…
}
/* declare and define */
int funct1(int x)
{
…
}
int main()
{
/* function call */
int y = funct1(3);
…
}
/* Function
definition */
int funct1(int x)
{…}
Three rules govern the use of variables in functions:
1. To use a variable in a function, we must declare it in the function header or the
function body.
2. For a function to obtain a value from the calling program (caller), the value must be
passed as an argument (the actual value).
3. For a calling program (caller) to obtain a value from function, the value must be
explicitly returned from the called function (callee).
www.tenouk.com, ©
28/66
C FUNCTIONS
The Function Statements


Any statements can be included within a function, however a function may
not contain the definition of another function.
For examples: if statements, loop, assignments etc are valid statements.
Returning a Value







A function may or may not return a value.
If function does not return a value, then the function return type is said to
be of type void.
To return a value from a function, use return keyword, followed by C
expression.
The value is passed back to the caller.
The return value must match the return data type.
A function can contain multiple return statements.
Program example: multiple
return statement
www.tenouk.com, ©
29/66
C FUNCTIONS
The Function Prototype





Must be included for each function that will be defined, (required by
Standards for C++ but optional for C) if not directly defined before
main().
In most cases it is recommended to include a function prototype in
your C program to avoid ambiguity.
Identical to the function header, with semicolon (;) added at the
end.
Function prototype includes information about the function’s return
type, name and parameters’ list and type.
The general form of the function prototype is shown below,
function_return_type
type parameterN)

function_name(type parameter1, type parameter2,…,
An example of function prototype,
long cube(long);
www.tenouk.com, ©
30/66
C FUNCTIONS
 Function prototype provides the C compiler the name and arguments of
the functions and must appear before the function is used or defined.
 It is a model for a function that will appear later, somewhere in the
program.
 From the previous prototype example, 'we' know the function is named
cube, it requires a variable of the type long, and it will return a value of
type long.
 Then, the compiler can check every time the source code calls the
function, verify that the correct number and type of arguments are being
passed to the function and check that the return value is returned
correctly.
 If mismatch occurs, the compiler generates an error message enabling
programmers to trap errors.
 A function prototype need not exactly match the function header.
 The optional parameter names can be different, as long as they are the
same data type, number and in the same order.
 But, having the name identical for prototype and the function header
makes source code easier to understand.
www.tenouk.com, ©
31/66
C FUNCTIONS
 Normally placed before the start of main() but must
be before the function definition.
 Provides the compiler with the description of a function
that will be defined at a later point in the program.
 Includes a return type which indicates the type of
variable that the function will return.
 And function name, which normally describes what the
function does.
 Also contains the variable types of the arguments that
will be passed to the function.
 Optionally, it can contain the names of the variables
that will be returned by the function.
 A prototype should always end with a semicolon ( ; ).
www.tenouk.com, ©
32/66
C FUNCTIONS
Passing Arguments to a Function


In order function to interact with another functions or
codes, the function passes arguments.
The called function receives the values passed to it and
stores them in its parameters.
List them in parentheses following the function name.

Program example: passing arguments

www.tenouk.com, ©
33/66
C FUNCTIONS




The number of arguments and the type of each argument must match
the parameters in the function header and prototype.
If the function takes multiple arguments, the arguments listed in the
function call are assigned to the function parameters in order.
The first argument to the first parameter, the second argument to the
second parameter and so on as illustrated below.
Basically, there are two ways how we can pass something to
function parameters,
1. Passing by value.
2. Passing by reference using array and pointer.
www.tenouk.com, ©
34/66
C FUNCTIONS
Macros and Inline Functions



If the same sequence of steps or instructions is required in several different
places in a program, you will normally write a function for the steps and call the
function whenever these steps are required. But this involves time overhead.
Also can place the actual sequence of steps wherever they are needed in the
program, but this increase the program size and memory required to store the
program. Also need retyping process or copying a block of program.
Use function if the sequence of steps is long. If small, use macros or inline
function, to eliminate the need for retyping and time overhead.
Macros

Need #define compiler directive. For example, to obtain just the area of a
triangle, we could create a macro,
www.tenouk.com, ©
35/66
C FUNCTIONS

Then, we can use it anywhere in the program e.g.,
printf("\nArea = %f\n", area(4.0, 6.0));

Example for finding an average of 4 numbers (a, b, c and
d),
#define avg(x, y) (x + y)/2.0

Then in the program we can define something like this,
avg1 = avg(avg(a, b), avg(c, d))

Doing the substitution,
avg4 = ((a + b)/2.0 + (c + d)/2.0) / 2.0

The drawback: nesting of macros may result in code that
difficult to read.
www.tenouk.com, ©
36/66
C FUNCTIONS
Program example: macro





Inline Function
Is preferred alternative to the macro since it provides most of the features of
the macro without its disadvantages.
Same as macro, the compiler will substitute the code for the inline function
wherever the function is called in the program.
Inline function is a true function whereas a macro is not.
The best time to use inline functions is when:
1.There is a time critical function
2.That is called often
3.And is respectfully small
Use keyword __inline which is placed before the function.
Program example: inline function
www.tenouk.com, ©
37/66
C FUNCTIONS
Header Files and Functions


Header files contain numerous frequently used functions that programmers
can use without having to write codes for them.
Programmers can also write their own declarations and functions and store
them in header files which they can include in any program that may require
them (these are called user-defined header file which contains user defined
functions).
Standard Header File




To simplify and reduce program development time and cycle, C provides
numerous predefined functions.
These functions are normally defined for most frequently used routines.
These functions are stored in what are known as standard library which
consist of header files (with extension .h, .hh etc).
In the wider scope, each header file stores functions, macros, enum,
structures (struct) , types etc. that are related to a particular application or
task.
www.tenouk.com, ©
38/66
C FUNCTIONS


We need to know which functions that are going to use,
how to write the syntax to call the functions and which
header files to be included in your program.
Before any function contained in a header file can be
used, you have to include the header file in your
program. You do this by writing,
#include <header_filename.h>


This is called preprocessor directive, normally placed at
the top of your program.
You should be familiar with these preprocessor
directives, encountered many times in the program
examples previously discussed.
www.tenouk.com, ©
39/66
C FUNCTIONS
Using Predefined Functions from Header File


Complete information about the functions and the header file
normally provided by the compiler’s documentation.
For your quick reference: C standard library reference.
User-defined Header Files


We can define program segments (including functions) and store
them in files.
Then, we can include these files just like any standard header file in
our programs.
Program example:
user defined
function
www.tenouk.com, ©
40/66
C FUNCTIONS


Next, let convert the user defined function to header file.
Step: Add new header file to the existing project.
www.tenouk.com, ©
41/66
C FUNCTIONS

Step: Put the header file name.
www.tenouk.com, ©
42/66
C FUNCTIONS

Step: Cut the function definition from the source file
and paste it into the header file.
// a function definition
float Convert(float TempFer)
{
// return the result to the calling program
return ((TempFer - 32) * 5) / 9;
}
www.tenouk.com, ©
43/66
C FUNCTIONS


Step: Next, include the header file at the top, just after the #include
<stdio.h>.
Use double quotes because the header file is under the project
folder/sub folder instead of the default or VC++ ..\include sub
folder.
#include "tempconverter.h"
www.tenouk.com, ©
44/66
C FUNCTIONS

Step: Re-build and re-run the project.


Next, we are going to use < > instead of " ".
To accomplish this, we need to put the header file
under the VC++ include folder/sub folder.
www.tenouk.com, ©
45/66
C FUNCTIONS


The VC++ include sub folder can be found in VC++
Directories Options settings.
Step: Select Tools menu > Select Options sub-menu.
www.tenouk.com, ©
46/66
C FUNCTIONS
 Step: When you have found your VC++ include sub folder, copy the
header file (tempconverter.h) into the VC++ include sub folder.
 Step: The header file can be found under the project folder/sub folder.
www.tenouk.com, ©
47/66
C FUNCTIONS
www.tenouk.com, ©
48/66
C FUNCTIONS
 Step: Now, change the double quotes (" ") to less-thangreater-than brackets (< >) brackets.
#include <tempconverter.h>
www.tenouk.com, ©
49/66
C FUNCTIONS
 Step: Then, we can delete the header file in the project.
www.tenouk.com, ©
50/66
C FUNCTIONS
 Step: Re-build and re-run the project.
www.tenouk.com, ©
51/66
C FUNCTIONS
Recursive Function




We cannot define function within function, but we can call the same
function within that function.
A recursive function is a function that calls itself either directly or
indirectly through another function.
Classic example for recursive function is factorial, which used in
mathematics.
Program example: recursive function
www.tenouk.com, ©
52/66
C FUNCTIONS
Passing an array to a function
#include <stdio.h>
// function prototype
void Wish(int, char[ ]);
void main(void)
{
Wish(5, "Happy");
}
What are the output and
the content of num &
mood variables after
program execution was
completed?
www.tenouk.com, ©
53/66
C FUNCTIONS
1. What are the two values passed to Wish()?
2. In Wish(), what becomes the value of num? What becomes the value of
mood? Write them in the provided boxes.
3. Notice that in both the prototype and the definition of Wish(), there is no
number in the brackets, giving the number of cells of mood[ ]. Can you
think why omitting this number makes the function more flexible for use in
other instances?
4. How can we tell that "Happy" is a character string? How can we tell that
mood[ ] should also be a character string?
5. If Wish() were called from main() with this statement, Wish(3,
"Excited"); , then what would be the output?
1.
2.
3.
4.
An integer 5 and a string "Happy".
num is an integer of 5 and mood is a string of "Happy".
This unsized array make the system decide the actual size needed for storage.
"Happy" is a character string because it is enclosed in the double quotes and an
array mood[ ] has been declared as a char type.
5. Only the first 3 alphabets from "Excited" will be displayed that is "I wish I'm Exc".
www.tenouk.com, ©
54/66
C FUNCTIONS
#include <stdio.h>
Build this program, show
the output & what it do?
void Rusted(char[ ]);
void main(void)
{
// all work done in function Rusted()...
Rusted("Test Test");
printf("\n");
}
void Rusted(char x[ ])
{
int j;
printf("Enter an integer: ");
scanf_s("%d", &j);
for(; j != 0; --j)
printf("In Rusted(), x = %s\n", x);
}
A function call from main() that passes a character string and
callee will print the number of character string based on the user
input.
www.tenouk.com, ©
55/66
C FUNCTIONS
Function, Array and Pointers






Functions in C cannot return array types however they can
return pointers to arrays or a reference.
When you pass in the array, you're only passing in a pointer. So
when you modify the array's data, you're actually modifying the
data that the pointer is pointing at.
Functions shall not have a return type of type array or function,
although they may have a return type of type pointer or
reference to such things.
So, there shall be no arrays of functions, although there can be
arrays of pointers to functions.
Since arrays are not objects, you can't pass them in and out of
functions.
Pointers are objects, so you can pass a pointer to the first
element of an object.
www.tenouk.com, ©
56/66








C FUNCTIONS
Functions (including main()) are constructed automatically
on the 'stack' memory.
When functions return, the stack will be destroyed/rewound.
Hence, local variables, including array, will be destroyed,
leaving a garbage.
Program example: passing arrays to a function using array
notation.
Program example: passing arrays to a function using
pointer notation.
Program example: passing arrays to a function & returning
a pointer to the first element of the array + global variable.
Program example: passing arrays to a function & returning
a pointer to the first element of the array + static
keyword.
Program example: passing arrays to a function using
pointer & return the array’s content.
www.tenouk.com, ©
57/66
C FUNCTIONS
Output samples
www.tenouk.com, ©
58/66
C FUNCTIONS
Function and Pointers (Function Pointers)





We can use pointers to point to C functions because C
function have its memory address.
When we can point to it, then it is another way to invoke
it.
Function pointers are pointer variables which point to
functions.
Function pointers can be declared, assigned values and
then used to access the functions they point to.
The following is an example of function pointer
declaration,
int

(*functptr)();
Here, functptr is declared as a pointer to a function
that returns int data type.
www.tenouk.com, ©
59/66
C FUNCTIONS



It is a de-referenced value of functptr, that is
(*funptr) followed by () which indicates a function,
which returns an integer data type.
The parentheses are essential in the declarations because
of the operators’ precedence.
The declaration without the parentheses as the following,
int * functptr();



Will declare a function functptr that returns an integer
pointer that is not our intention in this case.
In C, the name of a function, which used in an expression
by itself, is a pointer to that function.
For example, if a function, testfunct() is declared as
follows,
int
testfunct(int
xIntArg);
www.tenouk.com, ©
60/66
C FUNCTIONS
 The name of this function, testfunct is a
pointer to that function.
 Then, we can assign the function name to a
pointer variable functptr, something like this:
functptr = testfunct;
 The function can now be accessed or called, by
dereferencing the function pointer,
/* calls testfunct() with xIntArg as an argument
then assign the returned value to nRetVal */
nRetVal = (*funptr)( xIntArg);
 Program example: function pointers
www.tenouk.com, ©
61/66
C FUNCTIONS
www.tenouk.com, ©
62/66
C FUNCTIONS



Function pointers can be passed as parameters in function calls and can be
returned as function values.
It’s common to use typedef with complex types such as function pointers
to simplify the syntax (typing).
For example, after defining,
typedef


(*functptr)();
The identifier functptr is now a synonym for the type of 'a pointer to a
function which takes no arguments and returning int type'.
Then declaring pointers such as pTestVar as shown below, considerably
simpler,
functptr

int
pTestVar;
Another example, you can use this type in a sizeof() expression or as a
function parameter as shown below,
/* get the size of a function pointer */
unsigned
pPtrSize = sizeof (int (*functptr)());
/* used as a function parameter */
void
signal(int (*functptr)());
www.tenouk.com, ©
63/66
C FUNCTIONS
 The following table summarizes the various
ways of using functions.
 We can categorize functions by whether or not
arguments are passed to them.
 Or we can categorize them by whether or not
values are received from them.
 Intersecting these two methods of categorizing
functions, we come up with four basic methods
of writing and using functions.
www.tenouk.com, ©
64/66
C FUNCTIONS
Do not pass argument
void main(void)
{
TestFunct();
...
}
No return
void TestFunct(void)
{
// receive nothing
// and nothing to be
// returned
}
void main(void)
{
x = TestFunct();
...
}
With a return
int TestFunct(void)
{
// received/passed
// nothing but need to
// return something
return 123;
}
Do pass arguments
void main(void)
{
TestFunct(123);
...
}
void TestFunct(int i)
{
// receive something and
// the received/passed
// value just
// used here. Nothing
// to be returned.
}
void main(void)
{
x = TestFunct(123);
...
}
int TestFunct(int x)
{
// received/passed something
// and need to return something
return (x + x);
}
www.tenouk.com, ©
65/66
END of C
FUNCTIONS
More exercises can be found at:
tenouk's C lab worksheet
www.tenouk.com, ©
66/66
Download