int get_students(void);
Without function prototypes, a program like:
#include <stdio.h> main() { float x; float y; x = 12; y = square(x); printf("%f %f\n", x, y); } float square(float x) { return x * x; }
main()
it finds a use of the function
square()
which it hasn't seen before.
In order to complete the compiling of
main()
the compiler
must assume some default characteristics for the function
square()
.
Sometimes the defaults are ok, and sometimes they're just plain
wrong.
Here, they're wrong.
(In particular, the default return type is integer, but here it is
floating.)
On top of that, even if the default return type is right, the default
specifies that no checking of the number or type of the arguments is
to be done.
So the compiler won't tell you if you've given the function the wrong
number or the wrong type of arguments.
The answer to this problem is to give
main()
a glimpse
into the future, a view of what functions are to come.
That is what the prototype is for.
The prototype for
square()
would look like:
float square(float x);
float square(float);
However, there are several advantages of readability given by including
the variable names.)
We've seen that any of the data types that are valid for variables
are also valid for function return types and for parameter types.
(This is only partially true as we'll see in
Lesson
5
.)
We've also seen examples where a special "type" is used for the function
return type or for the whole argument list.
That type is
void
.
When we have a return type of
void
as in:
void print_integer(int x);
y = print_integer(x);
y
.
When we use
void
for the parameter list as in:
int get_choice(void);
selection = get_choice();
selection = get_choice(x);