C Programming Module4 Tenouk
C Programming Module4 Tenouk
FUNCTIONS
Receive nothing, return nothing-receive nothing, return something-
receive something, return something-receive something, return nothing
And they do something. That is a function!
Abilities
- Most computer programs that solve real-world problem are large, containing thousand to million lines
of codes and developed by a team of programmers.
- The best way to develop and maintain large programs is to construct them from smaller pieces or
modules, each of which is more manageable than the original program.
- These smaller pieces are called functions. In C++ you will be introduced to Class, another type smaller
pieces construct.
- The function and class are reusable. So in C / C++ programs you will encounter and use a lot of
functions. There are standard (normally called library) such as maintained by ANSI C / ANSI C++,
ISO/IEC C, ISO/IEC C++ and GNU’s glibc or other non-standard functions (user defined or vendors
specific or implementations or platforms specific).
- If you have noticed, in the previous Modules, you have been introduced with many functions, including
the main(). main() itself is a function but with a program execution point.
- Functions are very important construct that marks the structured or procedural programming approach.
- In general terms or in other programming languages, functions may be called procedures or routines
and in object oriented programming, methods may be used interchangeably with functions.
- Some definition: A function is a named, independent section of C / C++ code that performs a specific
task and optionally returns a value to the calling program.
- So, in a program, there are many calling function codes and called functions (normally called callee).
- There are basically two categories of function:
- You will encounter a lot of the predefined functions when you proceed from Module to Module of this
Tutorial. Here we will try to concentrate on the user-defined functions (also apply to predefined
function), which basically having the following characteristics:
www.tenouk.com Page 1 of 41
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. A function is independent.
A function can perform its task without interference from or interfering with other parts of the
program. The main program, main() also a function but with an execution point.
- Let try a simple program example that using a simple user defined function:
long cube(long);
//function prototype, explained later
void main()
{
long input, answer;
//function definition
long cube(long x)
{
//local scope (to this function) variable
long x_cubed;
Output:
- The following statement is calling cube() function, bringing along the value assigned to the input
variable.
www.tenouk.com Page 2 of 41
- When this statement is executed, program jump to the cube() function definition:
- After finished the execution, the cube() function returns to the calling code, where in this case, assign
the return value, x_cubed to an answer variable.
- main(), scanf(), print() are examples of the standard predefined functions.
- A C / C++ program does not execute the statements in a function until the function is called by another
part of the program.
- When C / C++ function is called, the program can send information to the function in the form of one
or more what is called arguments although it is not a mandatory.
- Argument is a program data needed by the function to perform its task.
- When the function finished its processing, program returns to the same location that called the function.
- The following figure illustrates a function call.
Arrow Means
→ Calling function with data (argument) if any
← Return to the next statement or execution with data if any
www.tenouk.com Page 3 of 41
- When a program calls a function, executions passed to the function and then back to the calling
program’s code.
- Function can be called as many times as needed as shown for function2() in the above figure, and
can be called in any order provided that it has been declared (as a prototype) and defined.
- Is the actual function body, which contains the code that will be executed as shown below:
long cube(long x)
{
//local scope (to this function) variable
long x_cubed;
- 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 (x 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 (long in this case).
3. Reusability.
Repeated tasks or routines can be accomplished using functions. This can overcome the
redundancy of code writing, for same tasks or routines, it can be reused, no need to rewrite
the code, or at least only need a little modification.
- Advantages: Can save programmers’ time and a function written can be reused (reusability).
- Structured program requires planning, before we start writing a single line of code.
- The plan should be a list of the specific tasks that the program performs.
- Imagine that you are planning to create a program to manage a name and address list of students.
Planning: Roughly the algorithm normally written in pseudo code might be (not in order):
www.tenouk.com Page 4 of 41
- So, the program is divided into 4 main tasks, each of which can be assigned to a function.
- Next, if needed, we still can divide these tasks into smaller tasks called subtasks.
- For example, as a common sense, for the "Enter new names and addresses" we can divide to the
following subtasks:
- Then if needed, "Modify existing entries" task still can be subdivided to the following subtasks:
- Finally we can see that there are two common subtasks: "Reading from disk and saving to disk"
- So, one function can be called by both the "Enter new names and address" function and the "Modify
existing entries" function. No redundancy or repetition and the functions created and tested can be
reused later on by programs that need the same tasks.
- Same for the subtask "Save the updated list to disk".
- Structured programming method results in a hierarchical or layered program structure, as depicted in
figure 4.1:
- Using structured programming, C/C++ programmers take the top-down approach as in the previous
figure. So, program’s structure resembles an inverted tree, from the root then to the trunk then to the
branch and finally to the leafs.
- From the main() program, subdivide the task to smaller tasks (subtasks). Then these smaller subtasks
are divided again if needed, to smaller subtasks and so on.
- Every subtask then assigned to the specific functions.
- You can see that most of the real work of the program is performed by the functions at the “tip of the
branches”.
- The functions closer to the trunk primarily are direct program execution among these functions.
- So, main body of the program has a small amount of code and every function acts independently. To
see how this approach been implemented, check Example #13 at the end of this Module.
- The first step is to know what task the function should perform. Then, detail the function declaration
and definition.
www.tenouk.com Page 5 of 41
- When you create functions or use the pre-defined functions, for debugging and testing, you may
convert each function to main() program, to test it individually, because function cannot be run
individually.
- Next, when you have satisfied with the execution of each separate main() program, re convert these
separate main() programs to the respective functions and call the functions from within one main()
program. Keep in mind that main() is also a function but with execution point. Let discussed the
details how to write a function.
- The first line of every function is called function header. It has 3 components, as shown below:
2. Function name
Can have any name as long as the rules for C/C++ variable names are followed and must be
unique.
3. Parameter list
Many functions use arguments, the value passed to the function when it is called. A
function needs to know what kinds of arguments to expect, that is, the data type of
each argument. A function can accept any of C/C++ basic data types. Argument type
information is provided in the function header by the parameter list. This parameter list just
acts as a placeholder.
- For each argument that is passed to the function, the parameter list must contain one entry, which
specifies the data type and the name of the parameter.
- For example:
- The first line specifies a function with three arguments: a type int named x, a type float named y
and a type char named z.
- Some functions take no arguments, so the parameter list should be void such as:
long thefunction(void)
void testfunct(void)
int zerofunct()
- 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.
www.tenouk.com Page 6 of 41
- The argument is an actual value passed to the function by the calling program. Each time a function is
called, it can be passed with different arguments through the parameters.
- 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.
- In function, using the corresponding parameter name accesses the argument.
- Program example:
//main() function
void main()
{
float x = 3.5, y = 65.11, z;
float half_of (float);
//In this call, x is the argument to half_of().
z = half_of(x);
//function definition
float half_of(float k)
{
//k is the parameter. Each time half_of() is called,
//k has the value that was passed as an argument.
return (k/2);
}
Output:
www.tenouk.com Page 7 of 41
- 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, contain a value of 3.5, then the second call send y, contain a value of 65.11.
- The value of x and y are passed 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.
- We can depict this process graphically as follows:
int function1(int y)
{
Int a, b=10; // local variable
Float rate; // local variable
Double cost=12.55; // local variable, been initialized
}
- Program example:
www.tenouk.com Page 8 of 41
Output:
- The function parameters are considered to be variable declaration, so, the variables found in the
functions parameter list are also available.
- 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.
#include …
/*function prototype;*/
int funct1(int);
int main()
{
/*function call*/
int y = funct1(3);
…
}
/*Function definition*/
int funct1(int x)
{…}
- But it is OK if we directly declare and define the function before main() as shown below. This
becomes an inline function.
#include …
int main()
{
/*function call*/
int y = funct1(3);
…
www.tenouk.com Page 9 of 41
}
- Or you will find later that we can declare, define and implement the functions in other files.
- Three rules govern the use of variables in functions:
1. To use a variable in a function, the programmer must declare it in the function header or the
function body.
2. For a function to obtain a value from the calling program, the value must be passed as an
argument (the actual value).
3. For a calling program to obtain a value from function, the value must be explicitly returned
from the function.
- Any statements can be included within a function, with one exception: a function may not contain the
definition of another function.
- For examples: if statements, loop, assignments etc are valid statements.
- The return value must match the return data type. For the above code segment, x must be an integer.
- A function can contain multiple return statements. The first return executed is the only one that has any
effect.
- An efficient way to return different values from a function may be the example below.
//Function prototype
int larger_of(int, int);
void main()
{
int x, y, z;
z=larger_of(x, y);
//Function definition
int larger_of(int a, int b)
{
//return a or b
www.tenouk.com Page 10 of 41
if(a > b)
return a;
else
return b;
}
Output:
- Must be included for each function that it uses, (required by Standards for C++ but not for C) if not
directly declare and define 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’ type.
- The general form of the function prototype is shown below,
long cube(long);
- Provides the C/C++ compiler with the name and arguments of the functions contained in the program
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.
- So, for the above prototype, the function is named cube, it requires a variable of the type long, and it
will return a value of type long.
- So, 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.
- 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.
www.tenouk.com Page 11 of 41
- Optionally, it can contain the names of the variables that will be returned by the function.
- A prototype should always end with a semicolon ( ; ).
- For example (can’t be executed):
- 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:
#include <iostream.h>
#include <stdlib.h>
//function prototype
void prt(int);
Output:
www.tenouk.com Page 12 of 41
- 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 three ways how we can pass something to function parameters:
- 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.
4.7.1 Macros
- Need #define compiler directive. For example, to obtain just the area of a triangle, we could use the
directive:
- When we have defined the above macro, you can use it anywhere in the program as shown below:
www.tenouk.com Page 13 of 41
- Substitution:
- The drawback: nesting of macros may result in code that difficult to read.
- 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.
- Includes the keyword inline placed before the function.
- Program example:
int main()
{
float b, h, a;
b = 4;
h = 6;
a = triangle_area(b, h);
cout<<"Area = (0.5*base*height)"<<endl;
cout<<"where, base = 4, height = 6"<<endl;
//compiler will substitute
//the inline function code.
cout<<"\nArea = "<<a<<endl;
system("pause");
return 0;
}
Output:
- 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 that
contains user defined functions).
- To simplify and reduce program development time and cycle, C / 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 such as ANSI C (ISO/IEC C), ANSI
C++ (ISO/IEC C++) and GNU glibc header files etc. or not so standard (implementation dependent)
www.tenouk.com Page 14 of 41
header files (with extension .h, .hh etc) and some just called this collection as C/C++ libraries. For
template based header files in C++ there are no more .h extension (refer to Module 23).
- In the wider scope, each header file stores functions, macros, structures (struct) and types that are
related to a particular application or task.
- This is one of the skills that you need to acquire, learning how to use these readily available functions
in the header files and in most C/C++ books, courses or training, this part is not so emphasized. So,
you have to learn it by yourself, check your compiler documentation where normally, they also contain
program examples.
- You have to know which functions you 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 including the:
#include <header_filename.h>
- This is called preprocessor directive, normally placed before the main() function of your program.
- You should be familiar with these preprocessor directives, encountered many times in the program
examples presented in this Tutorial such as:
#include <stdio.h>
#include <iostream.h>
int main()
{ return 0; }
- Every C/C++ compiler comes with many standard and non-standard header files. Header files, also
called include files; provide function prototype declarations for functions library, macros and types.
Data types and symbolic constants used with the library functions are also defined in them.
- Companies that sold compilers or third party vendors, normally provide the standard function libraries
such as ISO/IEC C, their own extension or other special header files, normally for specific applications
such as for graphics manipulation, engineering applications and databases. These non standard headers
are implementation dependent.
- For example, the following table is a partial list of an ANSI C, ANSI C++ and non-standard header
files.
- There may be new header files introduced from time to time by Standard and Non-standard bodies and
there may be obsoletes header files.
- Some may be implementation dependant so check your compiler documentation.
Note: The middle column indicates C++ header files, header files defined by ANSI C or non-standard header files
(-). Standard C++ header files (template based) don’t have the .h anymore. For more information please read
Module 23.
www.tenouk.com Page 15 of 41
Contains structures, macros, and functions for working with
dir.h - directories and path names. Example: chdir(),
getcurdir(), mkdir(), rmdir().
Defines structures, macros, and functions for dealing with
direct.h -
directories and path names.
Declares functions and structures for POSIX directory
dirent.h - operations. Example: closedir(), opendir(),
readdir().
Defines various constants and gives declarations needed for
dos.h - DOS and 8086-specific calls. Example: bdos(),
_chmod(), getdate(), gettime().
errno.h ANSI C Defines constant mnemonics for the error codes.
except.h C++ Declares the exception-handling classes and functions.
excpt.h - Declares C structured exception support.
Defines symbolic constants used in connection with the
fcntl.h -
library routine open. Example: _fmode(), _pipe().
file.h C++ Defines the file class.
Contains parameters for floating-point routines.
float.h ANSI C
Declares the C++ stream classes that support file input and
fstream.h C++
output.
generic.h C++ Contains macros for generic class declarations.
Contains structures and declarations for low-level
io.h - input/output routines. Example: access(), create(),
close(), lseek(), read(), remove().
Declares the C++ streams I/O manipulators and contains
iomanip.h C++
templates for creating parameterized manipulators.
iostream.h C++ Declares the basic C++ streams (I/O) routines.
Contains environmental parameters, information about
limits.h ANSI C
compile-time limitations, and ranges of integral quantities.
Declares functions that provide country- and language-
locale.h ANSI C specific information. Example: localeconv(),
setlocale().
malloc.h - Declares memory-management functions and variables.
Declares prototypes for the math functions and math error
math.h ANSI C handlers. Example: abs(), cos(), log(), pow(),
sin(), tan().
Declares the memory-manipulation functions. (Many of these
mem.h - are also defined in string.h.). Example: memccpy(),
movedata(), memset(), _fmemmove(), memchr().
memory.h Contains memory-manipulation functions.
new.h C++ Access to _new_handler, and set_new_handler.
Contains structures and declarations for the spawn... and
process.h - exec... functions. Example: abort(), exit(),
getpid(), wait().
Declares functions for searching and sorting. Example:
search.h -
bsearch(), lfind(), qsort().
Declares the functions longjmp and setjmp and defines a
setjmp.h ANSI C type jmp_buf that these functions use. Example:
longjmp(), setjmp().
Defines parameters used in functions that make use of file-
share.h -
sharing.
Defines constants and declarations for use by the signal and
signal.h ANSI C
raise functions. Example: raise(), signal().
Defines macros used for reading the argument list in
stdarg.h ANSI C functions declared to accept a variable number of arguments
(such as vprintf, vscanf, and so on).
stddef.h ANSI C Defines several common data types and macros.
Defines types and macros needed for the standard I/O
package defined in Kernighan and Ritchie and extended
under UNIX System V. Defines the standard I/O predefined
stdio.h ANSI C
streams stdin, stdout, stdprn, and stderr and
declares stream-level I/O routines. Example: printf(),
scanf(), fgets(), getchar(), fread().
stdiostr.h C++ Declares the C++ (version 2.0) stream classes for use with
www.tenouk.com Page 16 of 41
stdio FILE structures. You should use iostream.h for
new code.
Declares several commonly used routines such as conversion
stdlib.h ANSI C routines and search/sort routines. Example: system(),
time(), rand(), atof(), atol(), putenv().
Declares several string-manipulation and memory-
string.h ANSI C manipulation routines. Example: strcmp(), setmem(),
_fstrcpy(), strlen().
Declares the C++ stream classes for use with byte arrays in
strstrea.h C++
memory.
sys\locking.h - Contains definitions for mode parameter of locking function.
Defines symbolic constants used for opening and creating
sys\stat.h -
files.
Declares the function ftime and the structure timeb that
sys\timeb.h -
ftime returns.
sys\types.h - Declares the type time_t used with time functions.
thread.h C++ Defines the thread classes.
Defines a structure filled in by the time-conversion routines
asctime, localtime, and gmtime, and a type used by
time.h ANSI C
the routines ctime, difftime, gmtime, localtime,
and stime. It also provides prototypes for these routines.
typeinfo.h C++ Declares the run-time type information classes.
Declares the utime function and the utimbuf struct
utime.h -
that it returns.
Defines important constants, including machine
values.h -
dependencies; provided for UNIX System V compatibility.
Definitions for accessing parameters in functions that accept
varargs.h - a variable number of arguments. Provided for UNIX
compatibility; you should use stdarg.h for new code.
Table 4.1: List of the standard and non standard header files
- Many of the functions in the standard (ANSI, ISO/IEC, Single UNIX Specification, GNU glibc etc.)
header files were used throughout this tutorial. You have to learn how to use these readily available
functions in the specific header file and must know how to write the syntax to call these functions. Do
not reinvent the wheels :o).
- Complete information about the functions and the header file normally provided by the compiler
documentation. They also may have program examples that you can try.
- Don’t forget also there are also tons of the non standard predefined header files available from the
compiler vendors, for specific machine/platform or third party.
- For Borland, Microsoft and other implementations, the functions contained in the non standard header
files normally begin with underscore ( _ ) such as _chmod() but using the similar function name.
- If you wrongly use or the include path is incorrect, normally the compiler will generates error
mentioning the file cannot be found/opened or can’t recognize the function names used in your
program.
- In reality the include files just act as an interface for our programs. The definition of the include files
actually already loaded into the system memory area as a library files (mainly for the standard header
files) typically with the .lib extension.
- Another error normally done by programmers is using wrong types, number and order of the function
parameters.
- 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.
- For example:
#include "myfile.h"
// enclosed with " ", instead of < >
// because it is located in the same folder/directory
// as the main() program instead of the standard path of
// of the include files set during the compiler installation.
www.tenouk.com Page 17 of 41
int main()
{ return 0; }
- Here, myfile.h is a user-defined header file, located in the same folder as the main() program.
- All the program segments contained in myfile.h are accessible to the function main().
- An example is given at the end of this Module how to create and use the user-defined function.
- This is the concept that is quite similar to the Object Oriented Programming using the classes that
contain methods which you will learn in Tutorial #3.
- ANSI C (ISO/IEC C) defines syntax for declaring a function to take a variable number or type of
arguments. Such functions are referred to as varargs functions or variadic functions.
- However, the language itself provides no mechanism for such functions to access their non-required
arguments; instead, you use the variable arguments macros defined in stdarg.h.
- The example of variadic function used in Standard ANSI C is printf() function. If you have
noticed, printf() can accept variable number or type of arguments.
- Many older C dialects provide a similar, but incompatible, mechanism for defining functions with
variable numbers of arguments, using varargs.h header file.
- Ordinary C functions take a fixed number of arguments. When you define a function, you specify the
data type for each argument.
- Every call to the function should supply the expected number of arguments in order, with types that can
be converted to the specified ones. Thus, if a function named let say testfunc() is declared like the
following:
- Then you must call it with two arguments, an integer number (int) and a string pointer (char *).
- But some functions perform operations that can meaningfully accept an unlimited number of
arguments.
- In some cases a function can handle any number of values by operating on all of them as a block. For
example, consider a function that allocates a one-dimensional array with malloc() to hold a specified
set of values.
- This operation makes sense for any number of values, as long as the length of the array corresponds to
that number. Without facilities for variable arguments, you would have to define a separate function
for each possible array size.
- The library function printf() is an example of another class of function where variable arguments
are useful. This function prints its arguments (which can vary in type as well as number) under the
control of a format template string.
- These are good reasons to define a variadic function which can handle as many arguments as the caller
chooses to pass.
4.8.4.2 Definition
1. Define the function as variadic, using an ellipsis ('...') in the argument list, and using special
macros to access the variable arguments.
2. Declare the function as variadic, using a prototype with an ellipsis ('...'), in all the files which
call it.
3. Call the function by writing the fixed arguments followed by the additional variable arguments.
- A prototype of a function that accepts a variable number of arguments must be declared with that
indication. You write the fixed arguments as usual, and then add an '...' to indicate the possibility of
additional arguments.
- The syntax of ANSI C requires at least one fixed argument before the '...'. For example:
www.tenouk.com Page 18 of 41
int varfunc(const char *a, int b, ...)
{ return 0; }
- Outlines a definition of a function varfunc which returns an int and takes two required arguments, a
const char * and an int. These are followed by any number of anonymous arguments.
- Ordinary fixed arguments have individual names, and you can use these names to access their values.
But optional arguments have no names that are nothing but '...'. How can you access them?
- The only way to access them is sequentially, in the order they were written, and you must use special
macros from stdarg.h in the following three step process:
1. You initialize an argument pointer variable of type va_list using va_start. The
argument pointer when initialized points to the first optional argument.
2. You access the optional arguments by successive calls to va_arg. The first call to
va_arg gives you the first optional argument; the next call gives you the second, and so
on. You can stop at any time if you wish to ignore any remaining optional arguments. It
is perfectly all right for a function to access fewer arguments than were supplied in the
call, but you will get garbage values if you try to access too many arguments.
3. You indicate that you are finished with the argument pointer variable by calling
va_end.
- Steps 1 and 3 must be performed in the function that accepts the optional arguments. However, you can
pass the va_list variable as an argument to another function and perform all or part of step 2 there.
- You can perform the entire sequence of the three steps multiple times within a single function
invocation. If you want to ignore the optional arguments, you can do these steps zero times.
- You can have more than one argument pointer variable if you like. You can initialize each variable with
va_start when you wish, and then you can fetch arguments with each argument pointer as you wish.
- Each argument pointer variable will sequence through the same set of argument values, but at its own
pace.
- There is no general way for a function to determine the number and type of the optional arguments it
was called with. So whoever designs the function typically designs a convention for the caller to tell it
how many arguments it has, and what kind.
- It is up to you to define an appropriate calling convention for each variadic function, and write all calls
accordingly.
- One kind of calling convention is to pass the number of optional arguments as one of the fixed
arguments. This convention works provided all of the optional arguments are of the same type.
- A similar alternative is to have one of the required arguments be a bit mask, with a bit for each possible
purpose for which an optional argument might be supplied. You would test the bits in a predefined
sequence; if the bit is set, fetch the value of the next argument, and otherwise use a default value.
- A required argument can be used as a pattern to specify both the number and types of the optional
arguments. The format string argument to printf() is one example of this.
- You don't have to write anything special when you call a variadic function. Just write the arguments
(required arguments, followed by optional ones) inside parentheses, separated by commas, as usual.
- But you should prepare by declaring the function with a prototype, and you must know how the
argument values are converted.
- In principle, functions that are defined to be variadic must also be declared to be variadic using a
function prototype whenever you call them. This is because some C compilers use a different calling
convention to pass the same set of argument values to a function depending on whether that function
takes variable arguments or fixed arguments.
- Conversion of the required arguments is controlled by the function prototype in the usual way: the
argument expression is converted to the declared argument type as if it were being assigned to a
variable of that type.
www.tenouk.com Page 19 of 41
4.8.4.7 Argument Access Macros
- The following Table list the descriptions of the macros used to retrieve variable arguments. These
macros are defined in the stdarg.h header file.
- The following is an example of a function that accepts a variable number of arguments. The first
argument to the function is the count of remaining arguments, which are added up and the result
returned.
- This example just to illustrate how to use the variable arguments facility.
/*variadic function*/
#include <stdarg.h>
#include <stdio.h>
sum = 0;
for (i = 0; i < count; i++)
/*Get the next argument value.*/
sum += va_arg (ap, int);
/*Clean up.*/
va_end (ap);
return sum;
}
int main(void)
{
/*This call prints 6.*/
printf("%d\n", sum_up(2, 2, 4));
Output:
www.tenouk.com Page 20 of 41
Program Examples and Experiments
Example #1
//main program...
void main()
{
cout<<"I'm in main()..."<<endl;
system("pause");
return; //return nothing or just omit this 'return;' statement
}
void FunctOne()
{
//do nothing here just display the
//following text...
cout<<"\nNow I'm in FunctOne()!..."<<endl;
cout<<"Receives nothing, return nothing..."<<endl;
//return to main, without any returned value
//return; optionally can put this empty 'return;'
}
double FunctTwo()
{
//receive nothing but do some work here...
double p = 10.123;
cout<<"\nNow I'm in FunctTwo()!\nmay do some work here..."
<<"\nReceives nothing but return something"
<<"\nto the calling function..."<<endl;
//and return something...
return p;
}
int FunctThree(int z)
{
//receive something...do some work...
//and return the something...
www.tenouk.com Page 21 of 41
int a = z + 100;
cout<<"\nThen, in FunctThree()!..."<<endl;
cout<<"Receive something from calling function\ndo some work here and"
<<"\nreturn something to the calling function...\n"<<endl;
//then return to main, with return value
return a;
}
void FunctFour(int s)
{
//received something but return nothing...
int r = s - 20;
cout<<"\nNow, in FunctFour()..."<<endl;
cout<<"Received something, but return nothing..."<<endl;
cout<<"The value processed = "<<r<<endl;
//return; optionally can put this empty 'return;'
}
Output:
Example #2
int main()
{
USHORT lengthOfYard;
USHORT widthOfYard;
USHORT areaOfYard;
www.tenouk.com Page 22 of 41
cout<< areaOfYard;
cout<< " square meter\n\n";
system("pause");
return 0;
}
Output:
long FindArea(long length, long width); // returns long, has two parameters
void PrintMessage(int messageNumber); // returns void, has one parameter
int GetChoice(); // returns int, has no parameters
char BadFunction(); // returns char, has no parameters
#include <iostream.h>
#include <stdlib.h>
//function prototype
float Convert(float);
int main()
{
float TempFer;
float TempCel;
TempCel = Convert(TempFer);
cout<<"\n";
cout<<TempFer<<" Fahrenheit = "<<TempCel<<" Celcius"<<endl;
system("pause");
return 0;
}
//function definition
float Convert(float TempFer)
www.tenouk.com Page 23 of 41
{
//local variable....
float TempCel;
Output:
#include <iostream.h>
#include <stdlib.h>
//function prototype
void myFunction();
int main()
{
cout<<"x = 5, y = 7, global scope\n";
cout<<"\nx within main: "<<x<<"\n";
cout<<"y within main: "<<y<<"\n\n";
cout<<"Then function call....\n";
myFunction();
void myFunction()
{
//local scope variable
int y = 10;
cout<<"\ny = 10, local scope\n"<<"\n";
cout<<"x within myFunction: "<<x<<"\n";
cout<<"y within myFunction: "<<y<<"\n\n";
}
Output:
www.tenouk.com Page 24 of 41
Example #7 Variable scope within a block
//demonstrates variables
//scope within a block
#include <iostream.h>
#include <stdlib.h>
//function prototype
void myFunc();
int main()
{
int x = 5;
cout<<"\nIn main x is: "<<x;
myFunc();
cout<<"\nBack in main, x is: "<<x<<endl;
system("pause");
return 0;
}
void myFunc()
{
//local scope variable
int x = 8;
Output:
www.tenouk.com Page 25 of 41
Example #8
//function prototype
void swap(int x, int y);
int main()
{
int x = 5, y = 10;
cout<<"In main. Before swap, x: "<<x<<" y: "<<y<<"\n";
cout<<"\nThen calling function swap(x, y)...\n";
swap(x, y);
cout<<"\n...back to main. After swap, x: "<<x<<" y: "<<y<<"\n";
system("pause");
return 0;
}
Output:
Example #9
#include <iostream.h>
#include <stdlib.h>
//function prototype
long int Doubler(long int AmountToDouble);
result = Doubler(input);
www.tenouk.com Page 26 of 41
}
Output:
Example #10
//function prototype
//width = 25 and height = 1, are default values
int AreaOfCube(int length, int width = 25, int height = 1);
int main()
{
//Assigning new values
int length = 100;
int width = 50;
int height = 2;
int area;
area = AreaOfCube(length);
//width = 25, height = 1, default values
cout<<"Third time function call, area = "<<area<<"\n";
system("pause");
return 0;
}
Output:
www.tenouk.com Page 27 of 41
Example #11
int main()
{
int target;
target = Doubler(target);
cout<<"First time function call, Target: "<<target<<endl;
target = Doubler(target);
cout<<"Second time function call, Target: "<<target<<endl;
target = Doubler(target);
cout<<"Third time function call, Target: "<<target<<endl;
system("pause");
return 0;
}
Output:
Example #12
int main()
{
int i;
www.tenouk.com Page 28 of 41
}
Output:
- This part will show you the process of defining function, storing in header files and using this function
and header file.
- Assume that we want to create simple functions that do the basic calculation: addition, subtraction,
division and multiplication of two operands.
- Firstly, we create the main() program, then we create header file named arithmet.h to store these
frequently used function.
- Note the steps of this simple program development. Firstly we create a simple program skeleton.
Compile and run. Make sure there is no error; warning is OK because this just as an exercise.
//function prototype
float AddNum(float, float);
//main program
void main(void)
{
cout<<"The function body..."<<endl;
cout<<"This just program skeleton..."<<endl;
system("pause");
}
//Function definition
float AddNum(float , float)
{
float x = 0;
return x;
}
Output:
#include <iostream.h>
#include <stdlib.h>
//function prototype
float AddNum(float, float);
void main(void)
{
//global (to this file) scope variables
float p, q, r;
www.tenouk.com Page 29 of 41
//Prompt for user input
cout<<"Enter two numbers separated by space: "<<endl;
cin>>p>>q;
//function call
r = AddNum(p, q);
//Function definition
float AddNum(float p, float q)
{
return (p + q);
}
#include <iostream.h>
#include <stdlib.h>
//function prototypes
float AddNum(float, float);
float SubtractNum(float, float);
float DivideNum(float, float);
float MultiplyNum(float, float);
void main(void)
{
//local (to this file) scope variables
float p, q, r, s, t, u;
//Prompt for user input
cout<<"Enter two numbers separated by space: "<<endl;
cin>>p>>q;
//Function call
r = AddNum(p, q);
s = SubtractNum(p, q);
t = DivideNum(p, q);
u = MultiplyNum(p, q);
//Function definition
float AddNum(float p, float q)
{
return (p + q);
}
www.tenouk.com Page 30 of 41
return (p - q);
}
- Our next task is to create header file, let named it arithmet.h and put all the function declaration
and definition in this file and save it in same folder as the main program.
- No need to compile or run this file, just make sure no error here.
#include <iostream.h>
#include <stdlib.h>
float x, y;
//Function prototypes
float AddNum(float, float);
float SubtractNum(float, float);
float DivideNum(float, float);
float MultiplyNum(float, float);
www.tenouk.com Page 31 of 41
}
#include <iostream.h>
#include <stdlib.h>
#include "arithmet.h" //notice this!
void main(void)
{
//local scope (to this file) variables…
int r, s, t, u;
r = AddNum(p, q);
s = SubtractNum(p, q);
t = DivideNum(p, q);
u = MultiplyNum(p, q);
- Compile and run this main program, you will get the same output but this main() program is simpler
and our header file arithmet.h can be reusable.
#include <iostream.h>
#include <stdlib.h>
#include "arithmet.h"
void main(void)
{
www.tenouk.com Page 32 of 41
//cout<<"Addition: "<<p <<" + "<<q<<" = "<<r<<endl;
//cout<<"Subtraction: "<<p <<" - "<<q<<" = "<<s<<endl;
cout<<"Division: "<<p <<" / "<<q<<" = "<<t<<endl;
cout<<"Multiplication: "<<p <<" * "<<q<<" = "<<u<<endl;
system("pause");
}
Output:
#include <iostream.h>
#include <stdlib.h>
#include <arithmet.h>
//using <arithmet.h> instead of "arithmet.h"
void main(void)
{
//local scope (to this file) variable
int t, u;
Output:
- If we want to add functionalities, add them in header file once and then, it is reusable.
- How to debug the functions if you have to create many independent functions stored in many header
files other than directly include the functions in our main program?
- Firstly create the function with their own specific task independently as main() program, compile and
run the main() function independently.
www.tenouk.com Page 33 of 41
- Then, when you have satisfied with the result of the independent main() program, convert each
main() program to respective function and call all the functions from one main() program.
- The main problems encountered here normally related to the passing the improper arguments, returning
the improper value, mismatch types and variables scope.
- Remember that the main() program just a normal function but with execution point.
- 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, used in mathematics.
- For example:
#include <iostream.h>
#include <stdlib.h>
int main()
{
int p;
cout<<"Calculating factorial using recursive function"<<endl;
cout<<"----------------------------------------------\n"<<endl;
system("pause");
return 0;
}
Output:
www.tenouk.com Page 34 of 41
//Demonstrates recursive Fibonacci function
//the formula, fibonacci(n) = fibonacci(n-1)+fibonacci(n-2)
#include <iostream.h>
#include <stdlib.h>
long fibonacci(long);
int main()
{
int p;
cout<<"Simple fibonacci using recursive function"<<endl;
cout<<"-----------------------------------------\n"<<endl;
Output:
int main()
{
int c;
www.tenouk.com Page 35 of 41
//using lower bound and upper bound
int num1 = 200 + random(700-200);
printf("\nRandom number between 200 700 = %d\n", num1);
Output:
int main(void)
{
struct tm *time_now;
time_t secs_now;
time_t t;
char str[80];
time(&t);
//dispaly current time and date...
//using ctime()
printf("Today's date and time: %s", ctime(&t));
www.tenouk.com Page 36 of 41
time_t first, second;
//Gets system time
first = time(NULL);
//Waits 5 secs
sleep(5);
//Gets system time again
second = time(NULL);
printf("The difference is: %f seconds\n", difftime(second, first));
Output:
int main(void)
{
time_t t;
struct tm *gmt, *area;
putenv(tzstr);
tzset();
t = time(NULL);
area = localtime(&t);
printf("The local time is: %s", asctime(area));
gmt = gmtime(&t);
printf("The GMT is: %s", asctime(gmt));
//wait 10 seconds...
sleep(10);
return 0;
}
Output:
www.tenouk.com Page 37 of 41
int main()
{
struct tm time_check;
int year, month, day;
Output:
#include <cstdio>
#include <ctime>
int main(void)
{
struct tm *time_now;
time_t secs_now;
time_t t;
char str[80];
time(&t);
//dispaly current time and date...
//using ctime()
printf("Today's date and time: %s\n", ctime(&t));
www.tenouk.com Page 38 of 41
getchar();
//Gets system time again
second = time(NULL);
printf("The difference is: %f seconds\n", difftime(second, first));
Output:
ModuleZ, Section Z.5 discusses the relationship between function call and memory allocation (stack
frame).
The following are program examples compiled using gcc.
/*main program...*/
int main()
{
printf("-----PLAYING WITH A FUNCTION-----\n");
printf("All call by value ONLY!!!\n");
printf("Starting: I'm in main()...\n");
void FunctOne()
{
/*do nothing here just display the*/
/*following text...*/
printf("\nNow I'm in FunctOne()!...\n");
www.tenouk.com Page 39 of 41
printf("Receives nothing, return nothing...\n");
/*return to main, without any returned value*/
}
double FunctTwo()
{
/*receive nothing but do some work here...*/
double p = 10.123;
printf("\nNow I'm in FunctTwo()!\nmay do some work here..."
"\nReceives nothing but returns something"
"\nto the calling function...\n");
/*and return something...*/
return p;
}
int FunctThree(int z)
{
/*receive something...do some work...*/
/*and return the something...*/
int a = z + 100;
printf("\nThen, in FunctThree()!...\n");
printf("Receives something from calling function\ndo some work here and"
"\nreturn something to the calling function...\n");
/*then return to main, with return value*/
return a;
}
void FunctFour(int s)
{
/*received something but return nothing...*/
int r = s - 20;
printf("\nNow, in FunctFour()...\n");
printf("Received something, but return nothing...\n");
printf("The value processed here = %d\n", r);
printf("Then within FunctFour, call FunctOne()...\n");
FunctOne();
printf("Back in FunctFour()....\n");
}
Back in main()...
Then, in FunctThree()!...
Receives something from calling function
do some work here and
return something to the calling function...
Back in main()...
Display the returned value from FunctThree = 200
Now, in FunctFour()...
Received something, but return nothing...
The value processed here = 30
Then within FunctFour, call FunctOne()...
www.tenouk.com Page 40 of 41
2. For this Module purpose, you can check the standard libraries of these various standards of C/C++.
Explore and compare the standard functions and their variation if any in the libraries. You can download
or read online the specification at the following links. (ISO/IEC is covering ANSI and is more general):
i. ISO/IEC 9899 (ISO/IEC 9899:1999) - C Programming languages.
ii. ISO/IEC 9945:2002 POSIX standard.
iii. ISO/IEC 14882:1998 on the programming language C++.
iv. ISO/IEC 9945:2003, The Single UNIX Specification, Version 3.
v. Get the GNU C library information here.
vi. Read online the GNU C library here.
www.tenouk.com Page 41 of 41