Introduction

In this my article you can read how to define, declare and call C functions. Before writing of large and complex programs, one should remember that our program should be readable, understandable, easily debugged and easily modified. Therefore the idea is to break a large problem into subproblems that can be handled more easily. If the subproblem is still a bit complex, it can be further divided it into smaller subproblems. This process continues until each subproblem can not be further divided. For example – in a magical matrixes problem, one module could read data items into matrix, one could display these data items, one could provides the result of two matrices, other may add diagonal elements of a matrix, and so on. These subproblems are referred to as modules.

Thus when a problem has been divided into subproblems or modules, it can be easily programmed to solve a problem. Each module performs a well-defined task. In C we refer these modules as functions. Therefore the concept is that functions are the basic building blocks in our C language.

C is basically a collection of functions in which main() is an essential function. The C functions you have used so far, such as printf and scanf, are built into the C libraries. However, in C you can also write our own functions to organize and simplify large and complex programs. This chapter describes how to define, declare and call C functions.

 

Function Types

A function is an independent collection of declarations and statements usually designed to perform a specific task. C supports two types of basic functions:

  1. Standard (library) functions
  2. User-defined functions

 

Standard Functions

The functions, which are already defined in the C libraries for the users, are called as standard functions. The standard functions are also called as library functions or ready made functions. You can use these standard functions in your program, but you can not change the statements of these standard functions. For instance, printf(), scanf(), gotoxy(), clrscr(), etc.  are some more commonly used standard functions.

 

User-defined Functions

The functions, which are defined by the user for its sake of convenience, are known as user-defined functions. You can write as many functions as you need.

 

The Function Definition

A function definition specifies the name of the function, the numbers and types of its formal argument and the declaration and statements that determine what it does. It can also specify the return type of the function. The function definition is the actual body of the function. The function definition starts with the function header and then comes the body of the function, or you can say the function block.

 

The general syntax of a typical function definition is as:

 

data-type func-name(list-of-formal-arguments & its declaration)

{

declaration of local variables, if any;

Statement-1;

Statement-2;

Statement-3;

Statement-n;

return (value);

}

Now let us discuss this. The very first line of the function definition is called as function header. The function header consists of three parts – return data type, function name and list of formal arguments. Here the data-type is type of data returned by this function to the calling function. The data-type can be either a basic data type or a user-defined data type.

The return data type given in the function definition must match the return type in the declaration of the function elsewhere in the program. If the type is not specified then its return type is an int by default. However, functions with other return data types must be defined or declared before they are called. Obviously a function’s return data type is used only when the function returns a value. Functions can not return arrays or functions rather they can return pointers to any data type, including arrays and functions.

After the return type, we have function name, func-name. The function name is any legal identifier followed by the function parenthesis without any spaces in between.

The arguments (or parameters) come inside the parenthesis, preceded by their types and separated by commas. The list-of-formal-arguments consists of one or more arguments. If the function does not use any parameter then the word void is used inside the parenthesis. No doubt, the empty parenthesis can be used.

And in curly brackets, after function parenthesis, we write the body of the function, which consists of local variables, if any, and statements. A function body is a compound statement containing the statements that define what the function does. It may also contain the local variables, which are used by these statements.

When the function is called, storage is created for the local variables and local initializations are performed. When the function is called the control is transferred to the function and the execution of function starts from the first statement in the compound statement and it will continue execution until a return statement is executed or the end of the function body is encountered. After the completion of execution of the program, the control is returned to the point at which the function was called.

 

Here are some examples of function definitions:

(i)

float sum(int a, float b)

{

….

}

(ii)

char lowercase(char ch)

{

….

}

The first definition tells that the sum() function receives two variables – one is integer and other is float, which are stored in two formal arguments a and b and after the execution of the function sum(), it returns a value whose type is float.

The second definition tells that the lowercase() function receives one character value in the formal argument ch and after its execution it returns a char value.

 

Actual and Formal Arguments

Before the discussion of functions in details, I want to clear your concept about the arguments. In C interfacing between functions are provided by actual arguments or by externally declared variables. Basically we have two types of arguments in using functions:

  • Actual arguments
  • Formal arguments

The variables given to a function in the call statement are called as actual arguments and the variables listed in the definition of a function are called as formal arguments. Communication between the calling function and the called function is carried through the use of two lists of parameters: the actual parameter list, which is in the calling statement of the function and the formal parameter list, which is specified in the function definition. When a function is executed, it uses the actual arguments given to it in the function call.

All actual arguments are passed by value. A copy of the actual arguments is assigned to the corresponding formal parameters. In this case the function uses this copy without affecting the variable from which it was originally derived.

As stated earlier, formal parameters are variables that receives values passed to a function by a function call. There are two ways of declaration of function’s formal parameters:

  • In the old form of a function definition, the formal parameters were declared following the closing parenthesis, immediately before the opening brace of the function body. In that form, the parenthesis consists of the name of each of the formal parameters and the order in which they receive the values in the function call.

Following function definition shows this old-style definition:

 

swap (a, b)

int a, b;

{

…. /* Statements */

}

In the new form of a function definition, the formal parameters declaration specify the types, sizes, and identifiers of value stored in the formal parameters. Each identifier in the formal parameter list must be preceded by its appropriate type specifier. This type of function definition is called as function prototype definition because the parenthesis following the function name contains the complete declaration of the function’s formal parameters. Later on we will discuss about function prototypes.

Following function definition shows function prototype definition:

 

swap (int a, int b)

{

…. /* Statements */

}

Here one should remember that the types of the actual arguments in calls to a function must be assigned compatible with the types of the corresponding formal parameters. A formal parameter can have any basic data type, structures, unions, arrays or pointer type.

Function Calls

A function is called in much the same way it is declared. Any function is called through a function call. A function call is an expression that transfers the control and actual arguments, if any, to a function. The syntax of a typical function call is:

 

func-name (list-of-actual-arguments);

 

Here the func-name is the name of the function to be called and the list-of-actual-arguments contains a list of the actual arguments (separated by commas) passed to the function. If the function takes no argument, the list-of-actual-arguments can be empty. The first argument in the list is always correspond to the first formal parameter of the function, the second one corresponds to the second formal parameter and so on through the list.

After the execution of the function call, the control is transferred to the first statement in the function. The control is returned back from the called function to the caller when the called function encounters a return statement. If no return statement is executed, the control is returned back after the execution of the last statement of the called function. In such cases, the return value is undefined.

One main point to note here is that when the called function uses the copies of the actual arguments, any change it makes to the formal arguments do not affect the values of the variables from which the copies may have been made.

 

The return of a Function

A function’s return type is used only when the function returns a value. A function returns a value when a return statement containing an expression is executed. Generally the function block ends with the return statement. The general syntax of the return statement is

 

return(expression);

 

Here the parenthesis is optional. If the return statement does not contain an expression, the return value is undefined. Let us see some examples of return statements:

 

return area;

return (a*b);

 

If the function does not return any value then no return statement is used.

Since main() function does not return any value, therefore no type is specified in its header. But some compilers (like Turbo C or Turbo C++) give a warning if you do not use the return statement at the end of the main block. You can avoid this warning by writing main function as:

 

main()

{

….

….

return (0);

}

 

You can also avoid the warning message by writing its return type void as:

 

void main()

{

….

….

}

However in some other books, you may also run across programs with the main function declared as:

 

void main(void)

{

….

….

}

User-defined Functions Types

There are four types of user defined functions:

  • Functions with no arguments and no return value
  • Function with no arguments but return value
  • Functions with arguments but no return value
  • unction with arguments and return value

Now we will discuss these types one by one.

 

Functions with no arguments and no return value

The functions that neither receives any argument from the calling function nor returns any value to the calling function are known as functions with no arguments and no return value. Look at the following example:

/* Program - lohit1.c */

 

#include 

main()

{

printf("\nWelcome.");

sample();

printf("\nBye.");

}

sample()

{

int a, b, c;

printf("\nEnter any two numbers : ");

scanf("%d %d", &a, &b);

c = a+b;

printf("Addition of two numbers: %d", c);

}

The output of this program is as:

Welcome

Enter any two numbers: 10 20

Addition of two numbers: 30

Bye

In this program we call a function sample() in function main(), with no arguments. Here main() is known as the calling function and sample() is known as called function. In function main(), when we call the function sample(), the control is transferred to the function sample() from the function main(). And after the execution of called sample() function, the control is transferred back to the calling function at the point from where the control was transferred to the called function. Since we are not passing any arguments to the function sample(), so there will be no formal arguments.

In a C program, we may have one or more than one function in which main() is an essential function because main() is a function, which tells the C compiler that the execution of the program starts from here. There is no restriction on the number of functions that might be present in the C program. And note that the functions would execute in the order in which they are called, not in the order in which they are written. We may define any function anywhere in the program and in any function we can call any function. But it is a good habit to define the functions in the same order in which they are called.

If a function takes no argument or contains the keyword void in its declaration then the compiler expects zero argument in function call and zero formal arguments in function definition. These four functions do not return any value to the function main(). If any function do not return any value then we must use the keyword void as a function’s return type.

 

Functions with no arguments but return values

In this category we include those functions, which do not receive any type of arguments but returns some value. Look at the following program in which we have called function sum() and multiply() that receive no arguments but return a value.

/* Program – lohit2.c */

 

#include 

main()

{

int item;

item = sum();

printf("The addition of two numbers : ", item);

item = multiply();

printf("The multiplication of two numbers : ", item);

}

sum()

{

int a , b , c ;

printf("\nEnter any two integers for addition : ");

scanf("%d  %d", &a, &b);

c = a+b;

return (c);

}

multiply()

{

int a , b , c ;

printf("\nEnter any two integers for multiplication : ");

scanf("%d  %d", &a, &b);

c = a*b;

return (c);

}

 

The output of this program is as….

Enter any two integers for addition:10 20

The addition of two numbers : 30

Enter any two integer for multiplication: 15 30

The multiplication of two numbers : 450

In this program we have called two functions add() and multiply(). These functions have local variables, such as ‘a’, ‘b’ and ‘c’, declaration within it. These variables are accessible only with in the block in which they are defined. In these function we are returning the value stored in variable ‘c’ to the calling function. When a function returns some value then it must be stored in some variable. In this program we have used a variable ‘c’ to store this returning value. We have already studied that the return statement is used to return a value from the calling function to the called function. The return statement is used to return a single value only.

 

Functions with arguments but no return value

In this category we include those functions, which transfer actual arguments in formal arguments but no value is returned from the calling function to the called function. Look at the following program-chap1205.c, in which we have called function sum() and multiply() with two actual arguments a and b that are collected in two formal arguments x and y respectively but both these function do not return any value.

/* Program – lohit3.c */

 

#include 

main()

{

int  a , b , c ;

printf("\nEnter any two integers for addition : ");

scanf("%d  %d",&a, &b);

sum(a,b) ;

printf("\nEnter any two integers for multiplication : ");

scanf("%d  %d",&a, &b);

multiply(a, b);

}

sum(int x, int y)

{

int  z;

z = x+y ;

printf("\nThe addition of two numbers : %d", z);

}

multiply(int x, int y)

{

int  z ;

z = x*y ;

printf("\nThe multiplication of two numbers : %d", z);

}

 

The output of this program is as….

Enter any two integers for addition:10 20

The addition of two numbers : 30

Enter any two integer for multiplication: 15 30

The multiplication of two numbers : 450

 

Functions passing arguments with some return value

The function that passes a list of parameters to calling functions and returns some value from calling function to the called function comes under this category.

 

Following program illustrates this concept.

/* Program – lohit4.c */

 

#include 

main()

{

int a, b, c;

printf("\nEnter any two integers for addition: ");

scanf("%d  %d", &a, &b);

c = sum(a, b) ;

printf("The addition of two numbers : %d", c);

printf("\nEnter any two integers for multiplication: ");

scanf("%d  %d", &a, &b);

c = multiply(a, b);

printf("The multiplication of two numbers : %d",c);

}

sum(int x, int y)

{

int z;

z = x+y;

return z;

}

multiply(int x, int y)

{

int z;

z = x*y;

return z;

}

The output of this program is as….

Enter any two integers for addition:10 20

The addition of two numbers : 30

Enter any two integer for multiplication: 15 30

The multiplication of two numbers : 450

 

In this we have called two functions sum() and multiply() using two call statements:

 

c = sum(a,b)  ;   and

c = multiply(a,b) ;

 

After the execution of both these functions, they return an integer value which is stored in variable ‘c’ in main function.

Now look at the following program.

/* Program – lohit5.c */

 

#include 

main()

{

int a, b, c;

float x, y, z;

printf(“\nEnter any two integers for addition: ”);

scanf(“%d  %d”,&a, &b);

c = addint(a, b);

printf(“The addition of two integers :  %d”, c);

printf(“\nEnter any two real numbers for addition: ”);

scanf(“%f  %f”, &x, &y);

z = addfloat(x, y);

printf(“The addition of two real numbers :  %d”, z);

}

addint(int aa, int bb)

{

int cc;

cc = aa+bb;

return cc;

}

addfloat(float xx, float yy)

{

int zz;

zz = xx+yy;

return zz;

}

 

In this program we call two functions addint() and addfloat() which receives two integer values and real values respectively and returns the result of addition of these two variables.

The output of this program is as….

Enter any two integers for addition: 10 20

The addition of two integers :  30

Enter any two real numbers for addition: 15.0 35.0

The addition of two real numbers : 50.0

This is perfectly right. But what will happen if you pass 15.3 and 35.1 to addfloat() function. In this case, you will expect the following output:

Enter any two integers for addition: 10 20

The addition of two integers :  30

Enter any two real numbers for addition: 15.3 35.1

The addition of two real numbers : 50.4

 

But when you run your program with these real values, you will get following output:

Enter any two integers for addition: 10 20

The addition of two integers :  30

Enter any two real numbers for addition: 15.3 35.1

The addition of two real numbers : 50.0

 

It happened so because the formal parameter xx and yy receives values 15.3 and 35.1 respectively. And when these values are added we get 50.4. Till now nothing is wrong. But the problem comes in return statement. Here in function definition we are not including any data type before the function name addfloat() and by default any return statement returns an integer value. Thus 50.4 is converted into integer value 50 and returned back and stored in variable z. Since z is a float variable, therefore the integer value 50 is converted into 50.0. That’s why we get 50.0 as output of addition of two real numbers. To overcome this limitation we can use function declaration or function prototype. Which we use in next article.

 

 

 


Like it on Facebook, Tweet it or share this article on other bookmarking websites.

No comments