What a Function Is: Definition, Call, Arguments, Return
Chapter Thirty-Two
Syllabus topic 2, "Basics of functions. User defined and Library functions"
Pages 150 to 154 of 222
In one line
A function is a named block with a list of parameters and a return type, which you call by name to get its work done and, if it returns one, its value.
Why programs are made of functions
Three reasons, and the third is the one that matters most in an examination.
To stop repeating yourself. Code written once is corrected once.
To give a piece of work a name. simple_interest(p, r, t) says what the line does; the same arithmetic written out does not.
To make a program you can reason about a piece at a time. A function has a small, stated interface: these values in, this value out. Once you trust it you can stop thinking about how it works, which is the only way anyone manages a program larger than a page. Chapter 6 called that modularity and put it fifth in the list of characteristics; in practice it is what makes the other four achievable.
The three parts
Every function you use involves three separate things, and confusing them is the commonest source of a compiler error in this topic.
1. The declaration, or prototype. Tells the compiler the name, the return type and the parameter types. Ends in a semicolon; has no body.
double area_of_circle(double radius);2. The definition. The same header, with the body. This is the function.
double area_of_circle(double radius)
{
return 3.14159 * radius * radius;
}3. The call. Uses it.
double a = area_of_circle(5.0);A function is declared as many times as you like and defined exactly once. Chapter 11 made the same distinction for variables.
A worked example, with the practical's program
MU's Practical 4(a) is the area of a square using a function. Here it is with the three parts labelled.
#include <stdio.h>
double area_of_square(double side); /* 1. declaration */
int main(void)
{
double side = 6.5;
double area = area_of_square(side); /* 3. call */
printf("a square of side %.2f has area %.2f\n", side, area);
printf("and of side 10, area %.2f\n", area_of_square(10.0));
return 0;
}
double area_of_square(double side) /* 2. definition */
{
return side * side;
}a square of side 6.50 has area 42.25
and of side 10, area 100.00Move the definition above main and the declaration becomes unnecessary, because the compiler will have read the real thing before it meets the call. Both arrangements are correct. The declaration is the one that keeps working when the program grows past one file, and it is the habit to form.
What happens when a function is called
Worth knowing in order, because it explains both the return value and chapter 40's whole subject.
- The arguments are evaluated. In an unspecified order, if there is more than one (chapter 20).
- Each argument's value is copied into the matching parameter.
- Control transfers to the function's body, which runs.
- A
returnhands a value back and control returns to the caller. - The call expression takes that value.
What a Function Is: Definition, Call, Arguments, Return
Step 2 is the sentence to hold on to: C passes arguments by value. The function gets a copy. Changing a parameter inside the function cannot change the caller's variable. Chapter 40 is the proof and the way round it.
return
return expression; /* in a function with a return type */
return; /* in a void function */return does two things at once: it ends the function and it supplies the value. A function may have several return statements, and the first one reached wins.
#include <stdio.h>
int larger(int a, int b)
{
if (a > b) {
return a; /* the function ends here */
}
return b;
}
void report(int n) /* returns nothing */
{
if (n < 0) {
printf("%d is negative, nothing to report\n", n);
return; /* an early exit, no value */
}
printf("%d has %d digit(s)\n", n, n < 10 ? 1 : n < 100 ? 2 : 3);
}
int main(void)
{
printf("larger of 12 and 47 is %d\n", larger(12, 47));
report(-5);
report(7);
report(842);
return 0;
}larger of 12 and 47 is 47
-5 is negative, nothing to report
7 has 1 digit(s)
842 has 3 digit(s)The value returned is converted to the function's return type. A function declared int that does return 3.7; returns 3.
Falling off the end of a non-void function without returning anything is undefined behaviour if the caller uses the value. main is the exception: reaching its closing brace returns 0.
void, in both of its places
void greet(void);The first void is the return type: this function gives nothing back, so its call cannot be used as a value. The second is the parameter list: it takes no arguments.
void greet(); is not the same thing in C17. An empty parameter list means the function takes an unspecified number of arguments, so the compiler checks nothing at the call and greet(1, 2, 3) compiles.
#include <stdio.h>
void takes_nothing(void);
void unspecified();
int main(void)
{
takes_nothing();
unspecified();
unspecified(1, 2, 3); /* compiles: the empty list checks nothing */
return 0;
}
void takes_nothing(void)
{
printf("declared (void): the compiler rejects any argument\n");
}
void unspecified()
{
printf("declared (): the compiler accepted three arguments it will ignore\n");
}declared (void): the compiler rejects any argument
declared (): the compiler accepted three arguments it will ignore
declared (): the compiler accepted three arguments it will ignoreAlways write (void). The empty list is a survival from the language before the first standard, and C23 has finally redefined it to mean (void). Until every compiler you meet is a C23 one, (void) is the form that gets your calls checked.
What a Function Is: Definition, Call, Arguments, Return
Parameters and arguments
Two words for two different things, and MU may ask for the distinction.
- A parameter is the name in the function's definition. It is a variable local to the function.
- An argument is the value in the call.
double area_of_square(double side) /* side is a PARAMETER */
...
area_of_square(6.5) /* 6.5 is an ARGUMENT */"Formal parameter" and "actual parameter" are the older names for the same pair, and some examiners use them. Parameter and argument are the standard's own words.
A function used inside an expression
Because a call is an expression, it can go anywhere a value can.
#include <stdio.h>
int square(int n)
{
return n * n;
}
int main(void)
{
printf("square(4) + square(3) = %d\n", square(4) + square(3));
printf("square(square(2)) = %d\n", square(square(2)));
printf("inside a condition : %s\n", square(5) > 20 ? "yes" : "no");
int a[3];
for (int i = 0; i < 3; i++) {
a[i] = square(i + 1);
}
printf("filled an array : %d %d %d\n", a[0], a[1], a[2]);
return 0;
}square(4) + square(3) = 25
square(square(2)) = 16
inside a condition : yes
filled an array : 1 4 9A void function cannot be used this way, because it has no value. printf("%d", greet()); does not compile.
What this does NOT mean
A declaration is not a definition. One promises the function exists, the other is the function.
A function does not have to return a value. A void function returns nothing, and its call cannot be used as a value.
Arguments are not shared with the caller. They are copied. A function cannot change the caller's variable through an ordinary parameter.
int f() is not int f(void) in C17. The first checks nothing at the call.
A function cannot be defined inside another function. C has no nested function definitions. Declarations may be nested, and definitions may not.
The order of the arguments' evaluation is not left to right. It is unspecified.
return is not only for the end. Several returns are normal and often clearer than one exit with a flag.
Quick revision
- A function has a name, a return type, a parameter list and a body.
- Declaration (prototype) ends in a semicolon; definition has the body; the call uses it.
- Declared many times, defined once.
- A call is an expression and may appear anywhere a value may.
- Arguments are evaluated in an unspecified order and copied into the parameters: C passes by value.
return expression;ends the function and supplies the value, converted to the return type.return;alone is for avoidfunction.voidas a return type means no value;(void)as a parameter list means no arguments.f()in C17 means an unspecified argument list and turns off checking. Writef(void).- Parameter is the name in the definition; argument is the value in the call.
- Functions cannot be nested in C.
What a Function Is: Definition, Call, Arguments, Return
Test yourself
1. What is the difference between a function declaration and a function definition?
A declaration gives the name, return type and parameter types and ends in a semicolon; it promises the function exists. A definition gives the same and the body; it is the function. One definition, any number of declarations.
2. Why does main usually need a prototype for a function defined below it?
Because the compiler reads the file once from the top, so at the call it must already know the return type and parameter types in order to compile and check the call.
3. What is the difference between void f() and void f(void) in C17?
f(void) takes no arguments and the compiler rejects any. f() says the argument list is unspecified, so the compiler checks nothing and f(1, 2) compiles. C23 makes the two the same.
4. Distinguish parameter from argument.
A parameter is the variable named in the function's definition. An argument is the value supplied in the call and copied into the parameter.
5. Can a function change the caller's variable through an ordinary parameter?
No. The argument's value is copied, so the function works on its own copy. A pointer parameter is the way round it, which is chapter 40.
6. How many return statements may a function have?
Any number. The first one reached ends the function.
7. What does a function declared int return if its body says return 2.9;?
- The value is converted to the return type, and conversion to an integer truncates.
What can be asked on this, and how to answer it
"What is a function? Explain its parts with an example." Define it, name the four parts of a definition, and give the three-part example: declaration, definition, call. Say that a function is declared many times and defined once, and that a call is an expression.
"Write a program to find the area of a square using a function." Give this chapter's program with the prototype above main and the definition below it. That layout is what the examiner expects, and it lets you explain why the prototype is there.
"What is a function prototype? Why is it needed?" A declaration giving the name, return type and parameter types, ending in a semicolon. It is needed because the compiler reads the file once and must know the function's interface at the point of the call in order to check and compile it.
What a Function Is: Definition, Call, Arguments, Return
"Distinguish between actual and formal parameters." The formal parameters are the names in the function's definition, which are local variables of the function. The actual parameters, or arguments, are the values in the call, which are copied into them. Add that C copies, so the function cannot change the caller's variables through them.
"Explain the return statement." It ends the function and supplies the value of the call, converted to the declared return type. return; with no value is for a void function. A function may have several, and the first reached takes effect.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.