0% found this document useful (0 votes)
4 views

Functions in C Programming Language

The document provides an overview of functions in C programming, explaining their purpose, structure, and the importance of prototypes. It discusses the concept of recursion, illustrating how functions can call themselves and the necessity of a base case to prevent infinite loops. Examples are provided to demonstrate function definitions, prototypes, and recursive calls, emphasizing the benefits of using functions for code efficiency and readability.

Uploaded by

kisherno.webster
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Functions in C Programming Language

The document provides an overview of functions in C programming, explaining their purpose, structure, and the importance of prototypes. It discusses the concept of recursion, illustrating how functions can call themselves and the necessity of a base case to prevent infinite loops. Examples are provided to demonstrate function definitions, prototypes, and recursive calls, emphasizing the benefits of using functions for code efficiency and readability.

Uploaded by

kisherno.webster
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Functions in C Programming Language

Additional information can be found in the texts,


Understanding Computer Science for Advanced
Level 3rd Edition Chapter 6 page 103 and C How to
Program 5th Edition Chapter 5 page 151.
Now that you should have learned about variables,
loops, and conditional statements it is time to learn
about functions. You should have an idea of their
uses as we have already used them and defined
one in the guise of main. Getchar is another
example of a function. In general, functions are
blocks of code that perform a number of pre-
defined commands to accomplish something
productive. You can either use the built-in library
functions or you can create your own functions.

Functions that a programmer writes will generally


require a prototype. Just like a blueprint, the
prototype gives basic structural information: it tells
the compiler what the function will return, what the
function will be called, as well as what arguments
the function can be passed. When I say that the
function returns a value, I mean that the function
can be used in the same manner as a variable
would be. For example, a variable can be set equal
to a function that returns a value between zero and
four.

1
For example:

#include <stdlib.h> /* Include rand() */

int a = rand(); /* rand is a standard function that all


compilers have */
Do not think that 'a' will change at random, it will
be set to the value returned when the function is
called, but it will not change again.

The general format for a prototype is simple:

return-type function_name ( arg_type arg1, ...,


arg_type argN );
arg_type just means the type for each argument --
for instance, an int, a float, or a char. It's exactly
the same thing as what you would put if you were
declaring a variable.

There can be more than one argument passed to a


function or none at all (where the parentheses are
empty), and it does not have to return a value.
Functions that do not return values have a return
type of void. Let's look at a function prototype:

2
int mult ( int x, int y );
This prototype specifies that the function mult will
accept two arguments, both integers, and that it
will return an integer. Do not forget the trailing
semi-colon. Without it, the compiler will probably
think that you are trying to write the actual
definition of the function.

When the programmer actually defines the


function, it will begin with the prototype, minus the
semi-colon. Then there should always be a block
(surrounded by curly braces) with the code that the
function is to execute, just as you would write it for
the main function. Any of the arguments passed to
the function can be used as if they were declared
in the block. Finally, end it all with a cherry and a
closing brace. Okay, maybe not a cherry.

Let's look at an example program:

#include <stdio.h>

int mult ( int x, int y );

3
int main()
{
int x;
int y;

printf( "Please input two numbers to be


multiplied: " );
scanf( "%d", &x );
scanf( "%d", &y );
printf( "The product of your two numbers is %d\
n", mult( x, y ) );
getchar();
}

int mult (int x, int y)


{
return x * y;
}
This program begins with the only necessary
include file. Next is the prototype of the function.
4
Notice that it has the final semi-colon! The main
function returns an integer, which you should
always have to conform to the standard. You
should not have trouble understanding the input
and output functions if you've followed the
previous tutorials.

Notice how printf actually takes the value of what


appears to be the mult function. What is really
happening is printf is accepting the value returned
by mult, not mult itself. The result would be the
same as if we had use this print instead

printf( "The product of your two numbers is %d\n",


x * y );
The mult function is actually defined below main.
Because its prototype is above main, the compiler
still recognizes it as being declared, and so the
compiler will not give an error about mult being
undeclared. As long as the prototype is present, a
function can be used even if there is no definition.
However, the code cannot be run without a
definition even though it will compile.

Prototypes are declarations of the function, but


they are only necessary to alert the compiler about
the existence of a function if we don't want to go
ahead and fully define the function. If mult were

5
defined before it is used, we could do away with
the prototype--the definition basically acts as a
prototype as well.

Return is the keyword used to force the function to


return a value. Note that it is possible to have a
function that returns no value. If a function returns
void, the return statement is valid, but only if it
does not have an expression. In other words, for a
function that returns void, the statement "return;"
is legal, but usually redundant. (It can be used to
exit the function before the end of the function.)

The most important functional (pun semi-intended)


question is why do we need a function? Functions
have many uses. For example, a programmer may
have a block of code that he has repeated forty
times throughout the program. A function to
execute that code would save a great deal of
space, and it would also make the program more
readable. Also, having only one copy of the code
makes it easier to make changes. Would you rather
make forty little changes scattered all throughout a
potentially large program, or one change to the
function body? So would I.

Another reason for functions is to break down a


complex program into logical parts. For example,
take a menu program that runs complex code
when a menu choice is selected. The program

6
would probably best be served by making functions
for each of the actual menu choices, and then
breaking down the complex tasks into smaller,
more manageable tasks, which could be in their
own functions. In this way, a program can be
designed that makes sense when read. And has a
structure that is easier to understand quickly. The
worst programs usually only have the required
function, main, and fill it with pages of jumbled
code.

Recursion
Recursion is a programming technique that allows
the programmer to express operations in terms of
themselves. In C++, this takes the form of a
function that calls itself. A useful way to think of
recursive functions is to imagine them as a process
being performed where one of the instructions is to
"repeat the process". This makes it sound very
similar to a loop because it repeats the same code,
and in some ways it is similar to looping. On the
other hand, recursion makes it easier to express
ideas in which the result of the recursive call is
necessary to complete the task. Of course, it must
be possible for the "process" to sometimes be
completed without the recursive call. One simple
example is the idea of building a wall that is ten
feet high; if I want to build a ten foot high wall,

7
then I will first build a 9 foot high wall, and then
add an extra foot of bricks. Conceptually, this is
like saying the "build wall" function takes a height
and if that height is greater than one, first calls
itself to build a lower wall, and then adds one a
foot of bricks.
A simple example of recursion would be:

void recurse()
{
recurse(); /* Function calls itself */
}

int main()
{
recurse(); /* Sets off the recursion */
return 0;
}
This program will not continue forever, however.
The computer keeps function calls on a stack and
once too many are called without ending, the
program will crash. Why not write a program to see
8
how many times the function is called before the
program terminates?

#include <stdio.h>

void recurse ( int count ) /* Each call gets its own


copy of count */
{
printf( "%d\n", count );
/* It is not necessary to increment count since
each function's
variables are separate (so each count will be
initialized one greater)
*/
recurse ( count + 1 );
}

int main()
{

9
recurse ( 1 ); /* First function call, so it starts at
one */
return 0;
}
This simple program will show the number of times
the recurse function has been called by initializing
each individual function call's count variable one
greater than it was previous by passing in count +
1. Keep in mind that it is not a function call
restarting itself; it is hundreds of function calls that
are each unfinished.

The best way to think of recursion is that each


function call is a "process" being carried out by the
computer. If we think of a program as being carried
out by a group of people who can pass around
information about the state of a task and
instructions on performing the task, each recursive
function call is a bit like each person asking the
next person to follow the same set of instructions
on some part of the task while the first person
waits for the result.

At some point, we're going to run out of people to


carry out the instructions, just as our previous
recursive functions ran out of space on the stack.
There needs to be a way to avoid this! To halt a
series of recursive calls, a recursive function will

10
have a condition that controls when the function
will finally stop calling itself. The condition where
the function will not call itself is termed the base
case of the function. Basically, it will usually be an
if-statement that checks some variable for a
condition (such as a number being less than zero,
or greater than some other number) and if that
condition is true, it will not allow the function to call
itself again. (Or, it could check if a certain condition
is true and only then allow the function to call
itself).

A quick example:

void count_to_ten ( int count )


{
/* we only keep counting if we have a value less
than ten
if ( count < 10 )
{
count_to_ten( count + 1 );
}
}
int main()
11
{
count_to_ten ( 0 );
}
This program ends when we've counted to ten, or
more precisely, when count is no longer less than
ten. This is a good base case because it means
that if we have an input greater than ten, we'll stop
immediately. If we'd chosen to stop when count
equaled ten, then if the function were called with
the input 11, it would run out of memory before
stopping.

Notice that so far, we haven't done anything with


the result of a recursive function call. Each call
takes place and performs some action that is then
ignored by the caller. It is possible to get a value
back from the caller, however. It's also possible to
take advantage of the side effects of the previous
call. In either case, once a function has called itself,
it will be ready to go to the next line after the call.
It can still perform operations. One function you
could write could print out the numbers
123456789987654321. How can you use recursion
to write a function to do this? Simply have it keep
incrementing a variable passed in, and then output
the variable twice: once before the function
recurses, and once after.

12
void printnum ( int begin )
{
printf( "%d", begin );
if ( begin < 9 ) /* The base case is when
begin is no longer */
{ /* less than 9 */
printnum ( begin + 1 );
}
/* display begin again after we've already
printed everything from 1 to 9
* and from 9 to begin + 1 */
printf( "%d", begin );
}
This function works because it will go through and
print the numbers begin to 9, and then as each
printnum function terminates it will continue
printing the value of begin in each function from 9
to begin.

This is, however, just touching on the usefulness of


recursion. Here's a little challenge: use recursion to
write a program that returns the factorial of any
number greater than 0. (Factorial is number *

13
(number - 1) * (number - 2) ... * 1).

Hint: Your function should recursively find the


factorial of the smaller numbers first, i.e., it takes a
number, finds the factorial of the previous number,
and multiplies the number times that
factorial...have fun. :-)

14

You might also like