Functions
Introduction
As with Scheme, a function or procedure in C is designed to perform a task. Several variations are possible, such as the following:
- The task may be self contained, or it it may depend upon some starting data.
- The task may or may not change its environment (e.g., the task might move the robot or print something to a terminal window).
- When the task finishes, data may or may not be computed and returned for use in the main program.
Altogether, a function or procedure performs some work. Variations arise in whether or not data are needed to start the work and whether or not computed results are returned to the main program.
In this class we examine how functions are created and used in the C
programming language. Some functions may take values as parameters,
as you are likely accustomed to in Scheme. Similarly, some functions
return values, while others are called for their side effect. When
such functions produce no value, their return type is called void.
Textbook Reading
Begin with a reading from your textbook:
- King: Sections 9.1-9.2, 9.4, pages 183-192, 201-202, or
- K&R: 1.7, 4.1-4.3
Examples
Using the textbook as background, examine the following programs.
quadratic
/* program to illustrate 4 functions related to the quadratic formula
given a, b, and c, the formula computes solutions to
a * x^2 +b * x + c = 0
if discriminate = sqrt (b*b - 4*a*c), a != 0, and discriminate > 0,
then the two real solutions of this equation are
(-b + discriminate) / (2.0 * a)
and
(-b - discriminate) / (2.0 * a)
compile using the math library with the line
gcc -lm -o quadratic quadratic.c
*/
#include
#include
/* print equation */
void printEqn(double coeff2, double coeff1, double coeff0)
{
printf("Equation: %lf*x^2 + %lf*x + %lf = 0\n", coeff2, coeff1, coeff0);
}
/* computation of the discriminate */
double disc(double r, double s, double t)
{
return sqrt(s*s - 4*r*t);
}
/* print roots of the quadratic formula */
void printRoots(double a, double b, double c)
{
double discriminate = disc(a, b, c);
double root1 = (-b + discriminate) / (2.0 * a);
double root2 = (-b - discriminate) / (2.0 * a);
printf(" Roots: %lf and %lf\n", root1, root2);
}
/* control processing for x^2 - 3*x + 2.0 = 0 */
void eqn1()
{
printEqn(1.0, -3.0, 2.0);
printRoots(1.0, -3.0, 2.0);
}
/* control processing for 2.0*x^2 - 7.0*x - 4.0 = 0 */
void eqn2()
{
printEqn(2.0, -7.0, -4.0);
printRoots(2.0, -7.0, -4.0);
}
int main ()
{
printf ("program illustrating functions and the quadratic formula\n");
eqn1();
eqn2();
return 0;
}
yoyo
/* program to use functions with value parameters to control a robot */
#include
#include
#include
/* yoyo illustrates:
function with 1 parameter: count
2 local variables: i, reps
1 return value
*/
int yoyo (int count)
{
int i;
int reps = 3*count;
/* repeat motion */
for (i = 0; i < reps; i++)
{
rForward (1, .5);
rBackward (1, .5);
}
sleep (3);
/* print local variables */
printf ("in yoyo: count = %d, reps = %d\n", count, reps);
return reps;
} // yoyo
int main ()
{
rConnect ("/dev/rfcomm0");
int repetitions, result;
repetitions = 2;
result = yoyo (repetitions);
printf ("repetitions = %d, result = %d\n", repetitions, result);
rDisconnect ();
}
value-params
/* value-params.c
*
* Demonstrates scoping of variable names and passing values into functions.
*/
#include
int procA (int a, int b)
{
printf ("procA1 a=%d, b=%d\n", a, b);
a = 5;
b = 6;
printf ("procA2 a=%d, b=%d\n", a, b);
return a + b;
}
void procB (int x, int y)
{
int z = procA (x, y);
printf ("procB1 x=%d, y=%d, z=%d\n", x, y, z);
x = 5;
y = 6;
printf ("procB2 x=%d, y=%d, z=%d\n", x, y, z);
}
int main ()
{
int x, y;
x = 2;
y = 3;
printf ("main1 x=%d, y=%d\n", x, y);
procB (y, x);
printf ("main2 x=%d, y=%d\n", x, y);
return 0;
}
