Functions

Introduction 

A function is a self contained program segment that carries out some specific, well defined task. Every C program consists of one or more functions. Every C program must have main function. Execution of program will always begin by carrying out the instructions in main. Generally, a function will process information that is passed to it from the calling portion of the function, and return a single value. Information is passed to the function via special identifiers called arguments.

Function Prototype (Function Declaration)

 Function declaration tells what function looks like. It represents signature (return type, name, type and number of arguments) of a function. Function prototypes are usually written at the beginning of a program. The general form of function prototype is: datatype functionname(datatype 1 arg 1,datatype 2 arg 2,……………..,datatype n arg n); OR datatype functionname(datatype 1, datatype 2,……………..,datatype n); Here datatype represents the type of data that is returned by the function, functionname represents the name of the function, and datatype 1, datatype 2,.....,datatype n represents the data types of the arguments arg 1, arg 2,…….,arg n. For example, int sum(int x, int y); OR int sum(int, int);

Function Definition

 What a function does is called function definition. The first line of a function definition contains the type of the value returned by the function, followed by the function name, and (optionally) a set of arguments, separated by commas and enclosed in parentheses. An empty pair of parentheses must follow the function name if the function definition does not include any arguments. Its general form is: datatype functionname(datatype 1 arg 1,datatype 2 arg 2,……………..,datatype n arg n) { function body } These arguments are called formal arguments, because they represent the names of the data items that are transferred into the function from the calling portion of the program. They are also known as parameters or formal parameters. The corresponding arguments in the function call are called actual arguments, since they define the data items that are actually transferred. The remainder of the function definition is a compound statement that defines the action to be taken by the function. This compound statement is sometimes referred to as the body of the function. It can include one or more return statements, in order to return a value to the calling portion of the program.

 Function Call (Accessing a Function) 

A function can be called (i.e. accessed) by specifying its name, a list of arguments enclosed in parentheses separated by commas, and followed by semicolon. Its general form is:
functionname(arg1, arg2,…, arg n); The arguments appearing in the function call are referred to as actual arguments, in contrast to the formal arguments that appear in the first line of the function definition. Example:

(Program to find sum of two numbers using function) 

#include<stdio.h>
 #include<conio.h>
 void main()
 { int x,y,sum; int add(int x, int y); // function declaration
 clrscr();
printf("Enter two numbers:\n");
 scanf("%d %d",&x,&y);
sum = add(x,y); // function call (x and y are actual arguments)
 printf("Sum = %d",sum);
getch();
}
 int add(int a, int b) //Function definition (a and b are formal arguments)
{
int z;
 z = a + b;
 return z;
 }

 Information is returned from the function to the calling portion of the program via the return statement. The return statement also causes the program logic to return to the point from which the function was accessed. In general terms, the return statement is written as return expression; Here, the value of the expression is returned to the calling portion of the program. The expression is optional. If the expression is omitted, the return statement simply causes control to revert back to the calling portion of the program, without any transfer of information.

Advantages of using Function

1. Writing function avoids rewriting the same code over and over. We can call the same function many times.
2. Using function, it becomes easier to write programs and keep track of what they are doing.
3. Function helps to divide a large program into number of parts, which makes it easier to understand, modify, and debug.

Example: (Program that shows the call of same function more than one time)
 #include<stdio.h>
 #include<conio.h>
 void main() 
int a,b,c,d,l;
 int find_larger(int , int ); 
clrscr();
 printf(“\nEnter two numbers “);
scanf(“%d %d”,&a,&b); l = find_larger(a,b);
 printf(“\nlarger = %d”,l); 
printf(“\nEnter two numbers “); 
scanf(“%d %d”,&c,&d);
 l = find_larger(c,d);
printf(“\nlarger = %d”,l);
 getch();
 }
 int find_larger(int x, int y)
{
 if(x > y)
 return x; 
else return y;

Types of Functions  

There are two types of function in C, library function and user defined functions. These functions are discussed below: 4.3.1. Library Function These functions are already available in C. These are not written by the programmer. Their definitions are written in lib file and prototypes are defined in header file. The C language is accompanied by a number of library functions. Some of them are: sqrt(a) – returns square root value of a pow(a,b) – returns a raised to the power b abs(i) – returns absolute value of i strlen(s) – returns length of string s 4.3.2. User-defined Function These are the functions written by the programmer. In brief, user-defined function is self-contained block of code that performs a particular task. Once a user-defined function has been written, it can be treated as a block that can be called from other part of the program. We can write a user-defined function in four different ways depending on its arguments and return type.
1. Functions with no arguments and no return type
2. Functions with arguments and no return value
3. Functions with arguments and return type
4. Functions with no arguments and return type
4.3.2.1. Functions with no arguments and no return type
No data transfer takes place between calling function and called function. Keyword void is used to indicate that the function does not return value. For example, #include<stdio.h> #include<conio.h> void main() { void add(); clrscr();
add(); getch(); } void add() { int x, y, z; printf("Enter two numbers:\n"); scanf("%d%d",&x,&y); z = x + y; printf("Sum=%d", z); }

 Functions with arguments and no return type

Calling function passes values to the called function. Called function does not return value to the calling function. It is a one-way transfer of data from calling to called function. For example, #include<stdio.h> #include<conio.h> void main() { int a, b; void add(int, int); clrscr(); printf("Enter two numbers:\n"); scanf("%d%d",&a,&b); add(a, b); getch(); } void add(int x, int y) { int z; z = x + y; printf("Sum=%d", z); }

 Functions with arguments and return value

Passes values from actual arguments of calling function to the formal arguments of called function and the computed value by the called function is returned back to the calling function. For example, #include<stdio.h> #include<conio.h> void main() { int a, b, c; int add(int, int); clrscr(); printf("Enter two numbers:\n"); scanf("%d%d",&a,&b); c = add(a, b); printf("Sum=%d",c);
getch(); } int add(int x, int y) { int z; z = x + y; return z; }

Functions with no arguments but return value

These types of functions do not pass values from calling function to called function but the computed value of the called function is returned back to the calling function. For example, #include<stdio.h> #include<conio.h> void main() { int c; int add(); clrscr(); c = add(); printf("Sum=%d",c); getch(); } int add() { int x,y,z; printf("Enter two numbers:\n"); scanf("%d %d",&x,&y); z = x + y; return z; }

Recursive Function

Recursion is a process by which a function calls itself repeatedly, until some specified condition has been satisfied. The process is used for repetitive computations in which each action is stated in terms of a previous result. In order to solve a problem recursively, two conditions must be satisfied. First, the problem must be written in a recursive form, and second, the problem statement must include a stopping condition. For example, the program below gives factorial of an integer number using recursive function. #include<stdio.h> #include<conio.h> void main() { int n; long int facto; long int factorial(int n); printf("Enter value of n:");
scanf("%d",&n); facto=factorial(n); printf("%d! = %ld",n,facto); getch(); } long int factorial(int n) { if(n == 0) //stopping condition return 1; else return n * factorial(n-1); //recursive call }

  Storage Classes

Every variable and function in C has two attributes: type and storage class. The four storage classes are automatic, external, register, and static, with corresponding keywords auto, extern, register, and static. The storage class of a variable determines which parts of the program can access it (scope or visibility) and how long it stays existence (lifetime or duration). 4.5.1. The Storage class auto Variables defined within a function body are called automatic variables. These variables have implicitly automatic storage class. The keyword auto can be used to explicitly specify the storage class. Because the storage class is automatic by default, the keyword auto is seldom used. Automatic variables are local or private to a function in which they are defined. So, these are also called local variables.
 Lifetime: An automatic variable is not created until the function in which it is defined is called. When the function exits and control is returned to the calling program, the variables are destroyed and their values are lost. Hence, the lifetime of an automatic variable coincides with the time when the function in which it is defined is executing. The idea behind limiting the lifetime of variables is to save memory space.
 Visibility: Automatic variables are only visible, meaning they can only be accessed, within the function in which they are defined. Limiting the visibility of variables helps to organize and modularize the program. You can be confident that the variables in one function are safe from accidental alteration by other functions, because the other functions can’t see them.
 Initialization: When an automatic variable is created, the compiler does not try to initialize it. Thus it will start off with an arbitrary value, which may be 0 but probably will be something else. If you want it initialized, you must do it explicitly.
Example: int add (int n) {
auto int sum = 0; //int sum = 0; int i; for(i = 1; i < n; i++) sum = sum + i; return sum; }

The Storage class extern

When a variable is declared outside a function, it is called external variable. These variables have implicitly external storage class. The keyword extern can be used to explicitly specify the storage class. Because the storage class is external by default, the keyword extern is seldom used. External variables are also called global variables, since they are known by all functions declared after it in a program.
 Lifetime: These variables exist for the life of the program. That is, memory space is set aside for them when the program begins, and continues in existence until the program ends.
 Visibility: These variables are visible in the file in which they are defined, starting at the point where they are defined.
 Initialization: If an external variable is not initialized explicitly, it is initialized automatically to 0 when it is created.
Programs need not essentially be limited into a single file, multi-file programs is also possible, all the files are linked later to form executable object code. To share a single variable in multiple programs it should be declared as external variables that are shared by two or more files are obviously global variables. Example: extern int sum; //int sum; int add (int n) { int i; for(i = 1; i < n; i++) sum = sum + i; return sum; } 

The Storage class static

There are two types of static variables: static automatic and static external. Static variables are defined using static keyword. Static automatic variables are defined inside a function. Static automatic variables are used when it’s necessary for a function to remember a value when it is not being executed; that is, between calls to the function. It has the visibility of local variable but the lifetime of an external variable.
 Lifetime: These variables exist for the life of the program. That is, memory space is set aside for them when the program begins, and continues in existence until the program ends.
 Visibility: Static variables are only visible within the function in which they are defined.
 Initialization: If an external variable is not initialized explicitly, it is initialized automatically to 0 when it is created.
Static external variables are only meaningful in multi-file programs. These are scope restricted external variables. The scope is the remainder of the source file in which they are declared. Thus, they are unavailable to functions defined earlier in the file or to functions defined in other files. Example:
static int n; //static external variable 
int test()
{
static int count = 0; //static automatic variable
count++;
 return count;
}

The Storage class register

This storage class tells the compiler that the associated variables should be stored in high-speed memory registers. Because resource limitations and semantic constraints sometimes make this impossible, this storage class defaults to automatic whenever the compiler cannot allocate an appropriate physical register. It can be declared only inside a function. Basically, the use of register is an attempt to improve execution speed. When speed is concern, the programmer may choose a few variables that are most frequently accessed and declare them to be of storage class register. Common candidates for such treatment include loop variables and function parameters. Example:
 int add (int n) 
{
register int i;
 int sum = 0;
 for(i = 1; i < n; i++)
 sum = sum + i;
 return sum; 
}

The Preprocessor

Lines that begin with # are called preprocessor directives. These lines communicate with the preprocessor. Preprocessor is a part of the compiler that deals with preprocessor directives before real compilation process begin. Preprocessor directives are written at the beginning of the program. They must not end with a semicolon. Only one preprocessor directive can appear in one line. There are two types of preprocessor directives: #include and #define. 4.6.1. #include directive It is also called file inclusion directive. It tells the compiler to include another file into your source file. In effect, the #include directive is replaced by the contents of the file instead. We can write this directive as follows: #include<filename> OR #include filename For example, #include<stdio.h> In most cases, #include directive is used to include header files that contains various declarations describing any library function we use in our programs. For example, for sqrt(n) function, the header file is math.h and we use it as follows: #include<math.h>

 #define directive

It is called macro definition. Macro is used to generate inline code. Hence, macro name that appears in a program is replaced by the string that defines the macro. Their use can reduce the program execution time. This directive occurs in two forms: macros without arguments and macros with arguments. These two forms have following general forms respectively. #define identifier text #define identifier(identifier,…, identifier) text For example, #define PI 3.1415 //macro without argument #define area(l,b) l*b //macro with arguments l and b Macros with arguments are frequently used to replace function call. When macro name is found, it is replaced by the string that defines the macro. Since, macro name is replaced by its definition; it takes less time to execute your program. Example: Program to calculate area and circumference of circle #include<stdio.h>
 #include<conio.h>
 #include<math.h>
#define PI 3.1415
#define area(r) PI*pow(r,2)
#define circum(r) 2*PI*r
void main(void)
 {
 float r,a,c;
clrscr();
printf("Enter radius:");
 scanf("%f",&r);
 a=area(r);
 c=circum(r);
printf("Area=%f\n",a);
printf("Circumference=%f",c);
getch();
}

No comments:

Post a Comment