Vous êtes sur la page 1sur 11

2011

Subprograms

Functions
There are many useful operations which

DELEGATING TASKS

are not part of the basic instruction set of


the computer
C has many libraries containing such
functions for our use. We have seen some
of these intrinsic or predefined functions
such as

Subprograms
Nathan Friedman

sqrt(x), exp(x), fabs(x)

We shall see that C also allows us to define

our own functions

2011

Subroutines

2011

Subprograms

Advantages of Using Functions

A Factorial Function

Functions are like small programs that we can

int factorial(int n) {
int fact;

use to define specific tasks


They support top down program design to
simplify developing complex programs

fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

Breaking a large problem down into smaller subtasks

simplifies the design of a program


They allow for independent testing of subtasks
They allow us to develop reusable code

2011

Subprograms

Syntax of a Function Definition

2011

A Factorial Function

type function-name (parameter list)


{
[local declarations]
[statements]
}

int factorial(int n) {
int fact;
fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

A function definition looks very much like the

definition of main
In fact, main is a function which is automatically
invoked when the program is executed

2011

2011

Subprograms

Subprograms

Syntax of a Function Definition


type function-name (parameter list)
{
[local declarations]
[statements]
}

A Factorial Function
int factorial(int n) {
int fact;
fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

Generally functions compute a value to be used

in the program (e.g. factorial)


We must specify the type of value to be

computed

Subprograms

If no value is computed the type can be void

2011

Subprograms

Syntax of a Function Definition

2011

int factorial(int n) {
int fact;
fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

We must give the function a name when we

define it
This is the name used to refer to the function
elsewhere in the program

2011

2011

A function with more parameters


int minof3 (int x, int y, int z) {
if (x <= y && x <= z)
return x;
else if (y <= x && y <= z)
return y;
else return z;
}

10

A Factorial Function

type function-name (parameter list)


{
[local declarations]
[statements]
}

Subprograms

Subprograms

11

Subprograms

12

Syntax of a Function Definition


type function-name (parameter list)
{
[local declarations]
[statements]
}
A function has 0 or more formal parameters
If there are 1 or more parameters we must

specify their types and give them a name so that


they can be referred to inside the function

2011

Subprograms

13

A Factorial Function

2011

Subprograms

14

Syntax of a Function Definition

int factorial(int n) {
int fact;

type function-name (parameter list)


{
[local declarations]
[statements]
}

fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

We declare any variables other than the parameters that

will be used in computing the function


In general, these variables can only be used inside the

function
Their names can be the same as names in other parts of

the program but they will denote different variables

2011

Subprograms

A Factorial Function
int factorial(int n) {
int fact;
fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;
}

15

2011

Subprograms

16

Syntax of a Function Definition


type function-name (parameter list)
{
[local declarations]
[statements]
}
The statements are the instructions for evaluating the

function
If the function returns a value, there must be at least one

return statement of the form return expression;


They type of the expression must be compatible with the

type of the function

2011

Subprograms

17

2011

Subprograms

18

Defining vs. Using Functions

Using Functions

As mentioned some functions (e.g. sqrt) have

User-defined function are used in the same way

been predefined for us


We have seen how to define new functions that
are not predefined
We can think of a definition being placed in a
library to be used whenever we want
We only have to define a function once and then
we can use it as often as we wish
How do we use the function we defined?

as library functions.

They can appear as part of any expression


When we use them, we must provide values for

the arguments

If the type of the function is not void, the function

returns a value of the specified type

That value is used in evaluating the rest of the

expression

Functions of type void do not return values and

are not embedded in larger expressions

2011

Subprograms

19

2011

Subprograms

20

The Semantics of Using Functions

The Semantics of Using Functions

If func is the name of a function with parameters

What happens when the program evaluates


func(e1, e2, e3)?

p1, p2 and p3, we can write func(e1, e2, e3) in


an expression
This invokes the function
The function then does the defined computation
Any value returned is then used in the expression
Think of how we have used intrinsic functions like
sqrt and others

The arguments e1, e2 and e3 are evaluated


These values are used to initialize the parameters
The computer evaluates the function, using the body of

the function definition with the values of the parameters


The return command sends the value back to be used

in the expression
If the function is of type void, there is no value returned

2011

Subprograms

21

2011

Subprograms

Some Caveats

Using a Function

There are a couple of requirements for the


evaluation of func(e1, e2, e3)to make
sense

#include <stdio.h>
int factorial(int n) {
int fact;
fact = 1;
while (n > 0) {
fact = n * fact;
n = n-1;
}
return fact;

The number of parameters and arguments must be

equal.
The type of the corresponding arguments and

22

parameters must be the same


The arguments can be constants, variables or more
general expressions.

void main() {
int n;
scanf("%d",&n);
printf ("The factorial of %d = %d\n", n, factorial(n));
}

2011

Subprograms

23

2011

Subprograms

24

Call by Value

Summary of Function Calls

When a function is used, the argument values are

When a function is invoked


1. arguments are evaluated
2. parameter-argument associations are made using
call-by-value
3. function body executes until it executes the return
statement
4. all temporary storage is released
5. the value of the expression in the return statement is
used where the function was invoked

used to initialize the parameters


The way this is done is not as simple as it might
seem
It varies from language to language and is very
different in C than some other languages such as
Fortran
The method used in C is often called call by
value
The parameters are initialized with the value of
the arguments before the function is executed

2011

Subprograms

25

2011

Subprograms

A Simple Example

Average of Three Numbers

We define and use a function that evaluates the

#include <stdio.h>

average of three real numbers


Notice that the arguments do not have to have

the same names as the parameters


In fact, they can be expressions in general and

not just variables

26

float averageof3 (float a, float b, float c) {


float ave;
ave = (a + b + c)/3.0;
return ave;
}
void main() {
float x, y, c, mean;
scanf ("%f%f%f", &x, &y, &c);
mean = averageof3 (x, y, c);
printf ("The average of %f, %f and %f is %f\n",
x, y, c, mean);
}

2011

Subprograms

27

2011

Subprograms

28

Where do function definitions go?

Prototypes

Function definitions appear in the same file as the main

It is often preferable to place function definitions

program
It is possible to link definitions from different files but we
will not look at that in this course
C requires that every name be defined before it is used in
the program
This is done in order to make it easier to check that the
name is being used properly
Function definitions must appear before the function is
used

after the main program


The main program is the core of the solution to a

problem and the functions used are auxiliary


It may be difficult to follow the logic if the main

program appears later, especially in large


programs
In order to allow this and still follow the
requirement that all definitions of names precede
their use, C provides the concept of a prototype

2011

Subprograms

29

2011

Function Prototypes

Example

Before using a function C must know the type it returns


and the parameter types.
Function prototypes allow us to specify this information
before actually defining the function
A function prototype consists of the type and name of the
function followed by a list of the parameter types.
The names of the parameters do not have to be specified
This allows more structured and therefore easier to read
code.
It also allows the C compiler to check the syntax of function
calls
It is good practice to prototype all functions at the beginning
of a program file

#include <stdio.h>

2011

2011

Subprograms

31

Subprograms

30

float averageof3 (float, float, float)


void main() {
float x, y, c, mean;
scanf ("%f%f%f", &x, &y, &c);
mean = averageof3 (x, y, c);
printf ("The average of %f, %f and %f is %f\n",
x, y, c, mean);
}
float averageof3 (float a, float b, float c) {
float ave;
ave = (a + b + c)/3.0;
return ave;
}

Subprograms

32

Two Function Example

Prime Numbers

#include <stdio.h>
#include <math.h>

Applications that use cryptography, random


number generators, simulation, hashing and
others require prime numbers
What is a prime number?
A positive integer is prime if it has no proper
divisors (i.e. the only divisors are 1 and the
number itself)
For example 2, 3, 5, 29, 67, 83, 97, 21257787-1

int bigger (int p, int q);


float geo_mean (int, int);
void main() {
int x, y;
scanf ("%d%d", &x, &y);
printf ("Larger value = %d\n", bigger(x,y));
printf ("Geometric Mean = %f\n", geo_mean(x,y));
}
int bigger (int a, int b) {
return a >= b ? a : b;
}
float geo_mean (int x, int y) {
return sqrt((float)(x*y));
}

2011

Subprograms

33

2011

Subprograms

34

Listing Prime Numbers

Top Down Program Design

We will write a program to list all prime numbers


less than a given value, n for n 2
Some facts:

We begin by writing a program that has missing pieces to

2 is a prime number
If we could determine whether a given number is

prime or not, we could write a program that tests each


odd number between 2 and n

Subprograms

We assume that we are able to obtain and validate the

range

All primes greater than 2 are odd

2011

be filled in later
We want to list all primes in a given range

35

We also assume that we can determine whether a given

number is a prime
Leaving these two issues aside for now, we can develop

our main program

2011

Subprograms

36

Main Program

The missing pieces

void main() {
int range, count=1, number;

We now have to develop functions to fill in the missing

range = get_range();
printf ("Prime number #%d = 2\n", count);
number = 3;
while (number <= range) {
if (prime(number)) {
count = count + 1;
printf ("Prime number #%d = %d\n",
count, number);
}
number = number + 2;
}
printf ("There are %d prime numbers less than %d\n",
count, range);

pieces
The first function is get_range, which has no arguments

but which obtains and validates the input. If an input is


invalid a loop keeps prompting for a valid input
The second function is prime, which has one parameter. If
the argument is a prime number it returns 1 (true).
Otherwise it returns 0 (false)

2011

Subprograms

37

2011

Subprograms

38

Obtain and Validate the Input

Is a number N prime?

int get_range (){


int n;
printf ("Please enter the range of values.\n");

If N=2 it is prime.
If N>2 check whether it has any proper divisors
If it is even it has the divisor 2
If it is odd we use a loop to check potential divisors:Look
for divisors less than N, where M>2
We need a loop that checks goes the potential divisors

do {
scanf ("%d",&n);
if (n >= 2) break;
printf ("Please a number >= 2.\n");
printf ("You entered %d. Please try again.\n", n);
}
while (1);

Potential divisors are odd numbers, 3, 5, 9, 11,


For each one check whether it divides N evenly

return n;

A clever observation: We only have to check for divisors up


to the square root of N
That is divisor*divisor must be less than N

2011

Subprograms

39

2011

Subprograms

Testing for Primality

The Complete Program (1)

int prime (int num) {


int div;
if (num == 2) return 1;
if (num % 2 == 0) return 0;
div = 3;
while (div*div <= num && num%div != 0)
div = div + 2;
if (num%div == 0)
return 0;
else
return 1;
}

#include <stdio.h>
int get_range ();
int prime (int);

40

void main() {
int range, count=1, number;
range = get_range();
printf ("Prime number #%d = 2\n", count);
number = 3;
while (number <= range) {
if (prime(number)) {
count = count + 1;
printf ("Prime number #%d = %d\n", count, number);
}
number = number + 2;
}
printf ("There are %d prime numbers less than %d\n",
count, range);
}

10

2011

Subprograms

41

The Complete Program (2)

2011

Subprograms

42

The Complete Program (3)


#include <stdio.h>

int get_range (){


int n;
printf ("Please enter the range of values.\n");
do {
scanf ("%d",&n);
if (n >= 2) break;
printf ("Please a number >= 2.\n");
printf ("You entered %d. Please try again.\n", n);
}
while (1);
return n;
}

int prime (int num) {


int div;
if (num == 2) return 1;
if (num % 2 == 0) return 0;
div = 3;
while (div*div <= num && num%div != 0)
div = div + 2;
if (num%div == 0)
return 0;
else
return 1;
}

11

Vous aimerez peut-être aussi