0% found this document useful (0 votes)
64 views16 pages

Chapter 5 - Web

This document discusses functions in C programming. It defines what a function is and explains key concepts like function prototypes, parameters, return values, scope, and calling functions. Functions allow code to be reused by grouping common tasks together and calling them from different parts of a program. Prototyping functions ensures the compiler understands what types of values a function expects and returns. Parameters pass information into functions, while local variables only exist within the function. Return values pass information back to the calling code. Together, these concepts allow for modular and organized C programming.

Uploaded by

Muzammil Ahmad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views16 pages

Chapter 5 - Web

This document discusses functions in C programming. It defines what a function is and explains key concepts like function prototypes, parameters, return values, scope, and calling functions. Functions allow code to be reused by grouping common tasks together and calling them from different parts of a program. Prototyping functions ensures the compiler understands what types of values a function expects and returns. Parameters pass information into functions, while local variables only exist within the function. Return values pass information back to the calling code. Together, these concepts allow for modular and organized C programming.

Uploaded by

Muzammil Ahmad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 16

Computer Programming & Problem Solving ( CPPS-1 )

Functions
Chapter # 5

 Functions
 Returning a value from a function
 Sending values to a function
 Arguments
 External Variables
 Preprocessor Directives
Functions

C provides functions, which are again similar, most languages. One difference is
that C regards main( ) as function. Also unlike some languages, such as Pascal,
C does not have procedures -- it uses functions to service both requirements.

Function Prototyping

Before you use a function C must have knowledge about the type it returns and
the parameter types the function expects.

The ANSI standard of C introduced a new (better) way of doing this than previous
versions of C. (Note: All new versions of C now adhere to the ANSI standard.)

The importance of prototyping is twofold.

 It makes for more structured and therefore easier to read code.


 It allows the C compiler to check the syntax of function calls.

How this is done depends on the scope of the function. Basically if a functions
has been defined before it is used (called) then you are ok to merely use the
function.

If NOT then you must declare the function. The declaration simply states the type
the function returns and the type of parameters used by the function.

It is usual (and therefore good) practice to prototype all functions at the start of
the program, although this is not strictly necessary.
Functions So Far

We have already come across the functions main, printf and scanf. When you
write a program of any size you will find that you can use functions to make life a
whole lot easier.

In the glazing program above we spend a lot of time checking the values of
inputs and making sure that they are in certain ranges. We have exactly the
same piece of code to check widths and heights. If we added a third thing to
read, for example frame thickness, we would have to copy the code a third time.
This is not very efficient, it makes the program bigger and harder to write. What
we would like to do is write the checking code once and then use it at each point
in the program. To do this you need to define a function to do the work for you.

Functions are identified by name and can return a single value. They act on
parameters, which are used to pass information into them. In our case we want a
function which is given the maximum and minimum values which something can
have, and returns a value in that range.

We need to tell the compiler the name of our function, what parameters it has,
and the type of information it returns.

Function Heading

We do all this in the function heading

float get_ranged_value ( float min, float max )

This tells the compiler that we are defining a function called get_ranged_value.
The first word, float, tells the compiler we are defining a function which will return
the value of a floating point number. The second item is the function name, i.e. a
name that we wish our function to be known by. You create a function name
using exactly the same rules as for a variable name.

The next item is a list of parameter names, enclosed in brackets. We have two
parameters, min and max. We must then tell the compiler the type of these two
parameters, in this case they are both floating point numbers.

Note that C does not do that much checking to make sure that you are giving the
right kinds of parameters in the correct order. If you get this wrong the program
will fail, probably in a very confusing way.
Function Body

We then follow this definition with the body of the function, which is in fact a
block, making our complete function as follows:

float get_ranged_value ( float min, float max )


{
float temp ;
do {
printf ( "Give the value : " ) ;
scanf ( "%f", &temp ) ;
} while ( (temp < min) || (temp > max) ) ;
return temp ;
}

return

The body of the function looks very like the code which we originally wrote,
however there is one additional line :

return temp ;

This is the means by which the function returns the value to whatever called it. If
our function has a type other than void it must return a value of the appropriate
type. You return a value by placing it in the program, after the return keyword.

You can return at any point during a function. This can be used as a very neat
"get the hell out of here".

Calling a Function

When the compiler sees get_ranged_value it knows that this refers to a


previously defined procedure. It takes the values MAX_WIDTH and MIN_WIDTH
and feeds them into the function. You can use max and min as variables within
the function, initially they are set to the values of the appropriate parameter. Any
changes to these parameters which you make inside the function are not passed
on to the outside world. When you reach the return line in the function this
causes the function to finish and pass back the value following the return. Of
course you must return something of the correct type, otherwise the compiler will
moan at you and nasty things might happen.

In our main program we would write something like :

width = get_ranged_value ( MIN_WIDTH, MAX_WIDTH ) ;


Local function variables

Note that inside our function we have declared a variable, temp. This is used to
hold the value which the user types in, so that we can compare it with the
maximum and minimum. This is a local variable. We only want to use temp
during this function, so we tell the compiler that it is only declared inside the
function. When get_ranged_value finishes the variable is discarded. This is
useful for two reasons:

It saves space. We are not reserving space for a variable when we are not going
to use it. temp only comes into existence when required and the memory it uses
is available at other times.

It reduces confusion. Because temp is only declared within get_ranged_value


that is the only place you can use it.

If I mention temp in another part of the program the compiler will say that it
cannot see it. This means that if someone else has written a function which uses
a local variable called temp there will be no confusion.

Scope

When talking about variables in this way you often hear the word scope. Any
variable has a given scope. You could describe the scope of a variable as that
portion of a program within which it is meaningful to use that variable.

If you declare a variable outside a function it is effectively accessible everywhere.


Such variables are often called global, i.e. their scope is the entire program. You
have to be careful when you make a variable global. The fact that it can be used
in any part of the program means that it can be corrupted in any part of the
program.

Up until now all our variables have been declared to be global. This is not good
practice. Only certain values are that important should be global. One part of
program design is deciding which of the variables need to be made global. This
is particularly valuable when several people are working on one project. If you
ever get involved with the writing of a large system the trick is to get together first
and decide what global variables to use, then decide on the overall structure,
what each section is going to do and how they are going to exchange data. You
can then go ahead and start writing your part of the system, secure in the
knowledge that you will not be causing anyone else problems.
As an example of variables and scope consider the following:

int fred ; |
void main ( ) |
{ |
float fred ; |
.... | scope of
.... | local fred
} |
|
void road ( ) | scope of
{ | global
int jim ; | fred
.... | scope of
.... | jim
} |

The global fred cannot be accessed by the function main, any reference to fred
refers to the local variable. Within main this variable is said to be scoped out.

I adopt a little convention when choosing variable names. If the variable is going
to be global I start the name with a capital letter, local variables are all lower
case, for example:

Window_Total
- would be a global variable whereas
counter
-would be local.

Variables Local to Blocks

You can extend the idea of little local variables even further, in that any block can
contain a variable definition, which will last for the duration of that block. When
that block finishes the variable disappears. This is especially useful if you need a
little counter for a job in the middle of a program:

This is a screen clear routine, which will work on any machine!


{
int i ;
for ( i=0 ; i < 25 ; i++ ) {
printf ( "\n" ) ;
}
}
The variable i only exists for the duration of the block, so this loop does not
interfere with any other variables called i which might be lying around your
program. If you have a sudden local need for a variable for a specific task it
makes very good sense to create one there and then to do the job. You could
argue that it is not very efficient to do this, because the variable is created each
time the block is entered, but it makes the program very much clearer and
reduces the chances of variable names clashing. Note that you must declare any
block variables at the very start of the block.

5.1 Function Basics

So what defines a function? It has a name that you call it by, and a list of zero or
more arguments or parameters that you hand to it for it to act on or to direct its
work; it has a body containing the actual instructions (statements) for carrying out
the task the function is supposed to perform; and it may give you back a return
value, of a particular type.

Here is a very simple function, which accepts one argument, multiplies it by 2,


and hands that value back:

int multbytwo(int x)
{
int retval;
retval = x * 2;
return retval;
}

On the first line we see the return type of the function (int), the name of the
function (multbytwo), and a list of the function's arguments, enclosed in
parentheses. Each argument has both a name and a type; multbytwo accepts
one argument, of type int, named x. The name x is arbitrary, and is used only
within the definition of multbytwo. The caller of this function only needs to know
that a single argument of type int is expected; the caller does not need to know
what name the function will use internally to refer to that argument. (In particular,
the caller does not have to pass the value of a variable named x.)

Next we see, surrounded by the familiar braces, the body of the function itself.
This function consists of one declaration (of a local variable retval) and two
statements. The first statement is a conventional expression statement, which
computes and assigns a value to retval, and the second statement is a return
statement, which causes the function to return to its caller, and also specifies the
value which the function returns to its caller.

The return statement can return the value of any expression, so we don't really
need the local retval variable; the function could be collapsed to
int multbytwo(int x)
{
return x * 2;
}
How do we call a function? We've been doing so informally since day one, but
now we have a chance to call one that we've written, in full detail. Here is a tiny
skeletal program to call multby2:

#include <stdio.h>

extern int multbytwo(int);

int main()
{
int i, j;
i = 3;
j = multbytwo(i);
printf("%d\n", j);
return 0;
}

This looks much like our other test programs, with the exception of the new line

extern int multbytwo(int);

This is an external function prototype declaration. It is an external declaration, in


that it declares something which is defined somewhere else. (We've already seen
the defining instance of the function multbytwo, but maybe the compiler hasn't
seen it yet.) The function prototype declaration contains the three pieces of
information about the function that a caller needs to know: the function's name,
return type, and argument type(s). Since we don't care what name the multbytwo
function will use to refer to its first argument, we don't need to mention it. (On the
other hand, if a function takes several arguments, giving them names in the
prototype may make it easier to remember which is which, so names may
optionally be used in function prototype declarations.) Finally, to remind us that
this is an external declaration and not a defining instance, the prototype is
preceded by the keyword extern.

The presence of the function prototype declaration lets the compiler know that we
intend to call this function, multbytwo. The information in the prototype lets the
compiler generate the correct code for calling the function, and also enables the
compiler to check up on our code (by making sure, for example, that we pass the
correct number of arguments to each function we call).
5.2 Function Prototypes

In modern C programming, it is considered good practice to use prototype


declarations for all functions that you call. As we mentioned, these prototypes
help to ensure that the compiler can generate correct code for calling the
functions, as well as allowing the compiler to catch certain mistakes you might
make.

Strictly speaking, however, prototypes are optional. If you call a function for which
the compiler has not seen a prototype, the compiler will do the best it can,
assuming that you're calling the function correctly.

If prototypes are a good idea, and if we're going to get in the habit of writing
function prototype declarations for functions we call that we've written (such as
multbytwo), what happens for library functions such as printf? Where are their
prototypes? The answer is in that boilerplate line

#include <stdio.h>

we've been including at the top of all of our programs. stdio.h is conceptually a
file full of external declarations and other information pertaining to the ``Standard
I/O'' library functions, including printf. The #include directive (which we'll meet
formally in a later chapter) arranges that all of the declarations within stdio.h are
considered by the compiler, rather as if we'd typed them all in ourselves.
Somewhere within these declarations is an external function prototype
declaration for printf, which satisfies the rule that there should be a prototype for
each function we call. (For other standard library functions we call, there will be
iother ``header files'' to include.) Finally, one more thing about external function
prototype declarations. We've said that the distinction between external
declarations and defining instances of normal variables hinges on the presence
or absence of the keyword extern. The situation is a little bit different for
functions. The ``defining instance'' of a function is the function, including its body
(that is, the brace-enclosed list of declarations and statements implementing the
function). An external declaration of a function, even without the keyword extern,
looks nothing like a function declaration. Therefore, the keyword extern is
optional in function prototype declarations. If you wish, you can write

int multbytwo(int);

and this is just as good an external function prototype declaration as

extern int multbytwo(int);

(In the first form, without the extern, as soon as the compiler sees the semicolon,
it knows it's not going to see a function body, so the declaration can't be a
definition.) You may want to stay in the habit of using extern in all external
declarations, including function declarations, since ``extern = external
declaration'' is an easier rule to remember.

********
Functions - C's Building Blocks

Some programmers might consider it a bit early to introduce the C function - but
we think you can't get to it soon enough. It isn't a difficult idea and it is incredibly
useful. You could say that you only really start to find out what C programming is
all about when you start using functions.

C functions are the equivalent of what in other languages would be called


subroutines or procedures. If you are familiar with another language you also
need to know that C only has functions, so don't spend time looking for the
definition of subroutines or procedures - in C the function does everything!

A function is simply a chunk of C code (statements) that you have grouped


together and given a name. The value of doing this is that you can use that
"chunk" of code repeatedly simply by writing its name. For example, if you want
to create a function that prints the word "Hello" on the screen and adds one to
variable called total then the chunk of C code that you want to turn into a
function is just:

printf("Hello");

total = total + l;

To turn it into a function you simply wrap the code in a pair of curly brackets to
convert it into a single compound statement and write the name that you want to
give it in front of the brackets:

demo()
{
printf("Hello");
total = total + 1;
}

Don't worry for now about the curved brackets after the function's name. Once
you have defined your function you can use it within a program:

main()
{
demo();
}
In this program the instruction demo (); is entirely equivalent to writing out all of
the statements in the function. What we have done is to create an new C function
and this, of course, is the power of functions. When you are first introduced to the
idea of functions, or their equivalent in other languages, it is easy to fall into the
trap of thinking that they are only useful when you want to use a block of code
more than once.

Functions are useful here but they have a more important purpose. If you are
creating a long program then functions allow you to split it into "bite-sized"
chunks which you can work on in isolation. As every C programmer knows,
"functions are the building blocks of programs."

Functions and Local Variables

Now that the philosophy session is over we have to return to the details -
because as it stands the demo function will not work. The problem is that the
variable total isn't declared anywhere. A function is a complete program sub-unit
in its own right and you can declare variables within it just as you can within the
main program. If you look at the main program we have been using you will
notice it is in fact a function that just happens to be called "main"! So to make
demo work we have to add the declaration of the variable total:

demo()
{
int total;
printf("Hello");
total=total+1;
}

Now this raises the question of where exactly total is a valid variable. You can
certainly use total within the function that declares it - this much seems
reasonable - but what about other functions and, in particular, what about the
main program? The simple answer is that total is a variable that belongs to the
demo function. It cannot be used in other functions, it doesn't even exist in other
functions and it certainly has nothing to do with any variable of the same name
that you declare within other functions.

This is what we hinted at when we said that functions were isolated chunks of
code. Their isolation is such that variables declared within the function can only
be used within that function. These variables are known as local variables and
as their name suggests are local to the function they have been declared in. If
you are used to a language where every variable is usable all the time this might
seem silly and restrictive - but it isn't. It's what makes it possible to break a large
program down into smaller and more manageable chunks.
The fact that total is only usable within the demo function is one thing - but
notice we said that it only existed within this function, which is a more subtle
point. The variables that a function declares are created when the function is
started and destroyed when the function is finished. So if the intention is to use
total to count the number of times the<B >demo function is used - forget it! Each
time demo is used the variable total is created afresh, and at the end of the
function the variable goes up in a puff of smoke along with its value. So no matter
how many times you run demo total will only ever reach a value of 1, assuming
that it's initialised to 0.

Making The Connections

Functions are isolated, and whats more nothing survives after they have finished.
Put like this a function doesn't seem to be that useful because you can't get data
values in, you can't get data values out, and they don't remember anything that
happens to them!

To be useful there has to be a way of getting data into and out of a function, and
this is the role of the curved brackets. You can define special variables called
parameters which are used to carry data values into a function. Parameters are
listed and declared in between the () brackets in the function's definition. For
example:

sum( int a, int b)


{
int result;
result=a + b;
}

defines a function called sum with two parameters a and b, both integers.
Notice that the result variable is declared in the usual way within the body of the
function. Also, notice that the parameters a and b are used within the function in
the same way as normal variables - which indeed they are. What is more, they
are still local variables and have nothing at all to do with any variables called a
and b defined in any other function.

The only way in which parameters are any different is that you can give them
initial values when the function starts by writing the values between the round
brackets. So sum(l,2);

is a call to the sum function with a set to 1 and b set to 2 and so result is set to
3. You can also initialise parameters to the result of expressions such as:
sum(x+2,z*10); which will set a equal to whatever x+2 works out to be and b
equal to whatever z*10 works out to be.
As a simpler case you can also set a parameter to the value in a single variable -
for example: sum(x,y); will set a to the value stored in x and b to the value
stored in y.

Parameters are the main way of getting values into a function, but how do we get
values out? There is no point in expecting the<B >result variable to somehow
magically get its value out of the sum function - after all, it is a local variable and
is destroyed when sum is finished. You might try something like:

sum(int a, int b, int result)


{
int result;
result = a + b;
}

but it doesn't work. Parameters are just ordinary variables that are set to an initial
value when the function starts running - they don't pass values back to the
program that used the function. That is: sum(l,2,r); doesn't store 1+2 in r
because the value in r is used to initialise the value in result and not vice versa.
You can even try sum(l,2,result); and it still will not work - the variable result
within the function has nothing to do with the variable result used in any other
program.

The simplest way to get a value out of a function is to use the return instruction.
A function can return a value via its name - it's as if the name was a variable and
had a value. The value that is returned is specified by the instruction: return
value; which can occur anywhere within the function, not just as the last
instruction - however, a return always terminates the function and returns control
back to the calling function. The only complication is that as the function's name
is used to return the value it has to be given a data type. This is achieved by
writing the data type in front of the function's name. For example:
int sum(a,b);

So now we can at last write the correct version of the sum function:

int sum(int a, int b)


{
int result;
result = a + b;
return result;
}

and to use it you would write something like:

r=sum(1,2);
which would add 1 to 2 and store the result in r. You can use a function anywhere
that you can use a variable. For example,

r=sum(1,2)*3

is perfectly OK, as is

r=3+sum(1,2)/n-10

Obviously, the situation with respect to the number of inputs and outputs of a
function isn't equal. That is you can create as many parameters as you like but a
function can return only a single value. (Later on we will have to find ways of
allowing functions to return more than one value.)
So to summarise: a function has the general form:

type FunctionName(type declared parameter list)


{
statements that make up the function
}

and of course a function can contain any number of return statements to specify
its return value and bring the function to an end.

There are some special cases and defaults we need to look at before moving on.
You don't have to specify a parameter list if you don't want to use any parameters
- but you still need the empty brackets! You don't have to assign the function a
type in which case it defaults to int. A function doesn't have to return a value and
the program that makes use of a function doesn't have to save any value it does
return. For example, it is perfectly OK to use:

sum(1,2);

which simply throws away the result of adding 1 to 2. As this sort of thing offends
some programmers you can use the data type void to indicate that a function
doesn't return a value. For example:

void demo();

is a function with no parameters and no return value.

void is an ANSI C standard data type.

The break statement covered in a previous section can be used to exit a


function. The break statement is usually linked with an if statement checking for
a particular value. For example:
if (x==1) break;

If x contained 1 then the fuction would exit and return to the calling program.

Functions and Prototypes

Where should a function's definition go in relation to the entire program - before


or after main()? The only requirement is that the function's type has to be known
before it is actually used. One way is to place the function definition earlier in the
program than it is used - for example, before main(). The only problem is that
most C programmers would rather put the main program at the top of the
program listing. The solution is to declare the function separately at the start of
the program. For example:

int sum();
main()
{
etc...

declares the name sum to be a function that returns an integer. As long as you
declare functions before they are used you can put the actual definition anywhere
you like.

By default if you don't declare a function before you use it then it is assumed to
be an int function - which is usually, but not always, correct. It is worth getting
into the habit of putting function declarations at the start of your programs
because this makes them easier to convert to full ANSI C.

What is ANSI C?

When C was first written the standard was set by its authors Kernighan and
Ritche - hence "K&R C". In 1990, an international ANSI standard for C was
established which differs from K&R C in a number of ways.

The only really important difference is the use of function prototypes. To allow the
compiler to check that you are using functions correctly ANSI C allows you to
include a function prototype which gives the type of the function and the type of
each parameter before you define the function. For example, a prototype for the
sum function would be:

int sum(int,int);
meaning sum is an int function which takes two int parameters. Obviously, if you
are in the habit of declaring functions then this is a small modification. The only
other major change is that you can declare parameter types along with the
function as in:

int sum(int a, int b);


{
rather than:
int sum(a,b)
int a,b;
{

was used in the original K&R C. Again, you can see that this is just a small
change. Notice that even if you are using an ANSI compiler you don't have to use
prototypes and the K&R version of the code will work perfectly well.
The Standard Library Functions

Some of the "commands" in C are not really "commands" at all but are functions.
For example, we have been using printf and scanf to do input and output, and
we have used rand to generate random numbers - all three are functions.

There are a great many standard functions that are included with C compilers
and while these are not really part of the language, in the sense that you can re-
write them if you really want to, most C programmers think of them as fixtures
and fitings. Later in the course we will look into the mysteries of how C gains
access to these standard functions and how we can extend the range of the
standard library. But for now a list of the most common libraries and a brief
description of the most useful functions they contain follows:

 stdio.h: I/O functions:


 getchar() returns the next character typed on the keyboard.
 putchar() outputs a single character to the screen.
 printf() as previously described
 scanf() as previously described

 string.h: String functions


 strcat() concatenates a copy of str2 to str1
 strcmp() compares two strings
 strcpy() copys contents of str2 to str1

 ctype.h: Character functions


 isdigit() returns non-0 if arg is digit 0 to 9
 isalpha() returns non-0 if arg is a letter of the alphabet
 isalnum() returns non-0 if arg is a letter or digit
 islower() returns non-0 if arg is lowercase letter
 isupper() returns non-0 if arg is uppercase letter

 math.h: Mathematics functions


 acos() returns arc cosine of arg
 asin() returns arc sine of arg
 atan() returns arc tangent of arg
 cos() returns cosine of arg
 exp() returns natural logarithim e
 fabs() returns absolute value of num
 sqrt() returns square root of num

You might also like