9.5 – Writing prototype and Anatomy of functions

by subbu on November 17, 2013

Need of prototype (function declaration), return type:

By default C compiler assumes that arguments sending to a function and the value returning from a function are of int types. For easy understanding in all the demonstrative programs so far, I have intentionally used int type of arguments and return value.

If we want other types to send as arguments and return value then needs to add prototype and return type to the function.

#include<stdio.h>
int main()
{
  int x,y,z;
  x=40,y=20;
  z=adding(x,y);
  printf("Sum of two numbers %d",z);
  return 0;
}
adding(int p,int q)
{
  return p+q;
}

Output:
Sum of two numbers 60

The above program executed successfully without writing any prototype and return type because here both arguments and returning value are int type.
Now we will see what happens if we send float type of arguments and return a float value in the next example

#include<stdio.h>
int main()
{
  float x,y,z;
  x=40,y=20;
  z=adding(x,y);
  printf("Sum of two numbers %f",z);
  return 0;
}
adding(float p,float q)
{
  return p+q;             /* returning float type */
}

Output:
Error: Type mismatch in redeclaration of ‘adding ‘

Oh!! it is giving error. To rectify the program, we need to add both the prototype and return type to the function definition.

Return type:

Generally, type of value a function is returning is written at the beginning of the function definition. It is optional to specify the return type when a function is returning nothing or int type value but, it is a good practice of writing return type for every function that we define. void is the keyword written as return type when a function doesn’t return any value.

Because the above function adding() is returning a float type of value, we must specify the return type as float at the beginning of the function definition

float adding(float p,float q)
{
  return p+q;             /* returning float type */
}

Prototype or function declaration statement:

It is the statement written either within or above the calling function. It informs the compiler regarding the arguments does the function accept and what it returns.

Writing prototype is optional in cases where

  1. A function accepts int type arguments or accepts no arguments
  2. A function returns int type value or returning nothing

But it as a good practice to write prototype for every function we define. It makes the compiler job easy to identify and understand a function.

syntax to prototype

Examples:

prototype to a sub function manip() that takes two float type arguments and returns nothing is

void manip(float,float);

Prototype to a sub function factorial() that takes one int argument and returns long type value  is

long factorial(int);

Prototype to a sub function sqrt() that takes two int arguments and returns double type value is

double sqrt(int,int);

prototype to a sub function adding() that takes two float type of arguments and returns a float value is

float adding(float,float);

Rectifying the program:

#include<stdio.h>
int main()
{
  float adding(float,float);      /* function declaration or prototype */
  float x,y,z;
  x=40,y=20;
  z=adding(x,y);
  printf("Sum of two numbers %f",z);
  return 0;
}
float adding(float p,float q)
{
  return p+q;
}

Output:
Sum of two numbers 60.000000

How to avoid of writing prototype:

We can avoid of writing prototype by defining the function above or before the calling function.

#include<stdio.h>
float adding(float p,float q)
{
  return p+q;
}
int main()
{
  float x,y,z;
  x=40,y=20;
  z=adding(x,y);
  printf("Sum of two numbers %f",z);
  return 0;
}

Output:
Sum of two numbers 60.000000

Nested function calls:

A function call can be placed as an argument in another function call. Here in this example sum(40,50) sends 40, 50 as arguments to the function sum() and get back 90 as return value. Now again sum(10,90) sends 10, 90 as arguments to the function sum(), get back 100 and assigns to the variable s. It would be printed as output.

#include<stdio.h>
int sum(int,int);
int main()
{
  int s;
  s=sum(10,sum(40,50));
  printf("Sum %d",s);
  return 0;
}
int sum(int x,int y)
{
  return x+y;
}

Output:
Sum 100

Order of arguments assigning:

Most of the times we no need to bother in what order the actual arguments are assigned to the formal arguments that are either left to right or right to left. In some cases where we use increment and decrement operators, it is important to know the order of arguments assigning.
Order of actual arguments assigning to the formal arguments is right to left.

#include<stdio.h>
void display(int,int,int);
int main()
{
int x=10;
display(++x,++x,x++);
return 0;
}
void display(int p,int q,int r)
{
printf("%d\t%d\t%d",p,q,r);
}

Output:
13   12   10

Here the order of assigning is from right to left x++, ++x, ++x (10 12 13). If it is from left to right then the output would have (++x, ++x, x++) 11 12 12

Anatomy of functions:

So far we have been using words like calling function, called by function, return type, prototype, calling statement, actual arguments and formal arguments etc. The following picture explains what is what.

anatomy of functions

Previous post:

Next post: