0% found this document useful (0 votes)
26 views33 pages

PPS Unit-4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views33 pages

PPS Unit-4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Introduction to functions

A function is a group of statements that together perform a task. Every C program has at least one function,
which is main(), and all the most trivial programs can define additional functions.

You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division is such that each function performs a specific task.

A function declaration tells the compiler about a function's name, return type, and parameters. A function
definition provides the actual body of the function.

The C standard library provides numerous built-in functions that your program can call. For example,
strcat() to concatenate two strings, memcpy() to copy one memory location to another location, and many
more functions.

A function can also be referred as a method or a sub-routine or a procedure, etc.


Defining a Function

The general form of a function definition in C programming language is as follows −

return_type function_name( parameter list ) {

body of the function

A function definition in C programming consists of a function header and a function body. Here are all the
parts of a function −

 Return Type − A function may return a value. The return_type is the data type of the value the
function returns. Some functions perform the desired operations without returning a value. In this
case, the return_type is the keyword void. 

 Function Name − This is the actual name of the function. The function name and the parameter
list together constitute the function signature.

 Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to
the parameter. This value is referred to as actual parameter or argument. The parameter list refers
to the type, order, and number of the parameters of a function. Parameters are optional; that is, a
function may contain no parameters.

 Function Body − The function body contains a collection of statements that define what the
function does.
Example
Given below is the source code for a function called max(). This function takes two parameters num1
and num2 and returns the maximum value between the two −

/* function returning the max between two numbers */

int max(int num1, int num2) {

/* local variable declaration */

int result;

if (num1 > num2)

result = num1;

else

result = num2;

return result;

Function Declarations
A function declaration tells the compiler about a function name and how to call the function. The actual
body of the function can be defined separately.

A function declaration has the following parts −

return_type function_name( parameter list );


For the above defined function max(), the function declaration is as follows −

int max(int num1, int num2);


Parameter names are not important in function declaration only their type is required, so the following is
also a valid declaration −

int max(int, int);


Function declaration is required when you define a function in one source file and you call that function
in another file. In such case, you should declare the function at the top of the file calling the function.
Function prototype

A function prototype is simply the declaration of a function that specifies function's name, parameters and
return type. It doesn't contain function body.

A function prototype gives information to the compiler that the function may later be used in the program.

Syntax of function prototype

returnType functionName(type1 argument1, type2 argument2,...);

In the above example, int addNumbers(int a, int b); is the function prototype which
provides following information to the compiler:

1. name of the function is addNumbers()


2. return type of the function is int
3. two arguments of type int are passed to the function

The function prototype is not needed if the user-defined function is defined before the main() function.

Category of functions:

A function depending an whether the arguments are present or not and whether a value is
returned or not, may belong to one of following categories

1. Function with no return values, no arguments


2. Functions with arguments, no return values

3. Functions with arguments and return values


4. Functions with no arguments and return values.

Function with no return values, no arguments

In this category, the function has no arguments. It does not receive any data from the calling
function. Similarly, it doesn‟t return any value. The calling function doesn‟t receive any data
from the called function. So, there is no communication between calling and called functions.

Functions with arguments, no return values

In this category, function has some arguments . it receives data from the calling function, but it
doesn‟t return a value to the calling function. The calling function doesn‟t receive any data
from the called function. So, it is one way data communication between called and calling
functions.
Eg: Printing n Natural numbers

#include<stdio.h>
#include<conio.h>
void nat( int);
void main()
{
int n;
printf("\n Enter n value:");
scanf("%d",&n);
nat(n);
}
void nat(int n)
{
int i;
for(i=1;i<=n;i++)
printf("%d\t",i);
}

Note:
In the main() function, n value is passed to the nat() function. The n value is now stored in the
formal argument n, declared in the function definition and subsequently, the natural numbers
upto n are obtained.

Functions with arguments and return values

In this category, functions has some arguments and it receives data from the calling function.
Simillarly, it returns a value to the calling function. The calling function receives data from the
called function. So, it is two-way data communication between calling and called functions.

Eg. Factorial of a Number

#include<stdio.h>
#include<conio.h>
int fact(int);
void main()
{
int n;
printf("\n Enter n:");
scanf("%d",&n);
printf("\n Factorial of the number : %d", fact(n));

}
int fact(int n)
{
int i,f;
for(i=1,f=1;i<=n;i++)
f=f*i;
return(f);
}

Functions with no arguments and return values.

In this category, the functions has no arguments and it doesn‟t receive any data from the calling
function, but it returns a value to the calling function. The calling function receives data from
the called function. So, it is one way data communication between calling and called functions.
Eg. Sum of Numbers

#include<stdio.h>
#include<conio.h>
int sum();
void main()
{
int s;
printf("\n Enter number of elements to be added :");
s=sum();
printf("\n Sum of the elements :%d",s);

int sum()

{
int a[20], i, s=0,n;
scanf("%d",&n);
printf("\n Enter the elements:");
for(i=0;i< n; i++)
scanf("%d",& a[i]);
for(i=0;i< n; i++)
s=s+a[i];
return s;
}

Inter Function communication


When a function gets executed in the program, the execution control is transferred from calling function
to called function and executes function definition, and finally comes back to the calling function. In this
process, both calling and called functions have to communicate each other to exchange information. The
process of exchanging information between calling and called functions is called as inter function
communication.
In C, the inter function communication is classified as follows...

 Downward Communication
 Upward Communication
 Bi-directional Communication

Downward Communication
In this type of communication, the data is transferred from calling function to called function but not
from called function to calling function. The function with parameters and without return value are
considered under Downward communication.
Example

#include <stdio.h>
#include<conio.h>
void main(){
int num1, num2 ;
void addition(int, int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;

printf("\nBefore swap: num1 = %d, num2 = %d", num1, num2) ;


addition(num1, num2) ; // calling function

getch() ;
}
void addition(int a, int b) // called function
{

printf("SUM = %d", a+b) ;

Output
SUM=30
Upward Communication
In this type of communication, the data is transferred from called function to calling function but not
from calling function to called function. The function without parameters and with return value are
considered under Upward communication.

Example
#include <stdio.h>
#include<conio.h>
void main(){
int result ;
int addition() ; // function declaration
clrscr() ;

result = addition() ; // calling function

printf("SUM = %d", result) ;


getch() ;
}

int addition() // called function


{
int num1, num2 ;
num1 = 10;
num2 = 20;
return (num1+num2) ;
}

Output
SUM=30

Bi-Directional Communication
In this type of communication, the data is transferred from called function to calling function and also
from calling function to called function. The function with parameters and with return value are
considered under Bi-Directional communication.

Example

#include <stdio.h>
#include<conio.h>
void main(){
int num1, num2, result ;
int addition(int, int) ; // function declaration
clrscr() ;

num1 = 10 ;
num2 = 20 ;

result = addition(num1, num2) ; // calling function

printf("SUM = %d", result) ;


getch() ;
}
int addition(int a, int b) // called function
{
return (a+b) ;
}
Output
SUM=30

Function Calls
This calls the actual function
Syntax:
function_name (arguments list);

There are two ways that a C function can be called from a program. They are,

1. Call by value
2. Call by reference

Call by Value

 In call by value method, the value of the variable is passed to the function as parameter.

 The value of the actual parameter can not be modified by formal parameter.

 Different Memory is allocated for both actual and formal parameters. Because, value of actual
parameter is copied to formal parameter.

Note:

 Actual parameter – This is the argument which is used in function call.

 Formal parameter – This is the argument which is used in function definition

Call by Reference:

 In call by reference method, the address of the variable is passed to the function as parameter.

 The value of the actual parameter can be modified by formal parameter.

 Same memory is used for both actual and formal parameters since only address is used byboth
parameters.

Parameter Passing Mechanisms:

In C Programming we have different ways of parameter passing schemes such as Call by Value and Call
by Reference.
Function is good programming style in which we can write reusable code that can be called whenever
require.
Whenever we call a function then sequence of executable statements gets executed. We can pass some of
the information to the function for processing called argument.
Two Ways of Passing Argument to Function in C Language :
A. Call by Reference
B. Call by Value
Let us discuss different ways one by one –

A. Call by Value :

#include<stdio.h>
void interchange(int number1,int number2)
{
int temp;
temp = number1;
number1 = number2;
number2 = temp;
}
int main() {

int num1=50,num2=70;
interchange(num1,num2);
printf("\nNumber 1 : %d",num1);
printf("\nNumber 2 : %d",num2);

return(0);
}

Output :
Number 1 : 50
Number 2 : 70

Explanation : Call by Value


While Passing Parameters using call by value , xerox copy of original parameter is created and passed
to the called function.
Any update made inside method will not affect the original value of variable in calling function.

In the above example num1 and num2 are the original values and xerox copy of these values is passed to
the function and these values are copied into number1,number2 variable of sum function respectively.
As their scope is limited to only function so they cannot alter the values inside main function.
B. Call by Reference/Pointer/Address :

#include<stdio.h>
void interchange(int *num1,int *num2)
{
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
int main() {
int num1=50,num2=70;
interchange(&num1,&num2);
printf("\nNumber 1 : %d",num1);
printf("\nNumber 2 : %d",num2);
return(0);
}

Output :
Number 1 : 70
Number 2 : 50

Call by Address
While passing parameter using call by address scheme , we are passing the actual address of the variable
to the called function.
Any updates made inside the called function will modify the original copy since we are directly
modifying the content of the exact memory location.
Passing Array to a Function:

Whenever we need to pass a list of elements as argument to any function in C language, it is


prefered to do so using an array.

Declaring Function with array as a parameter

There are two possible ways to do so, one by using call by value and other by using call by
reference.

We can either have an array as a Parameter

int sum (int arr[]);

Or, we can have a pointer in the parameter list, to hold the base address of our

array. int sum (int* ptr);

Returning an Array from a function

We don't return an array from functions, rather we return a pointer holding the base address of the
array to be returned.

int* sum (int x[])


{
// statements return x ;
}
Passing a single array element to a function(Call by value)

In this type of function call, the actual parameter is copied to the formal parameters.
Example 1:

#include<stdio.h>
void giveMeArray(int a);
int main()
{
int myArray[] = { 2, 3, 4 };
giveMeArray(myArray[2]);
return 0;
}
void giveMeArray(int a)
{
printf("%d", a);
}

Output: 4

Example 2:

#include <stdio.h> void disp( char ch)


{
printf("%c ", ch);
}
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
for (int x=0; x<10; x++)
{
disp (arr[x]);
}
return 0;
}
OUTPUT: abcdefghij

Passing array to function using call by reference


When we pass the address of an array while calling a function then this is called function call by
reference. When we pass an address as an argument, the function declaration should have a
pointer as a parameter to receive the passed address.

#include <stdio.h>
void disp( int *num)
{
printf("%d ", *num);
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8,9, 0};
for (int i=0; i<10;i++)
{
/* Passing addresses of array elements*/
disp (&arr[i]);
}
return 0;
}

OUTPUT:

1 2 3 4 5 6 7 8 9 0

Passing string to function

 A string is a collection of characters.


 A string is also called as an array of characters.
 A String must access by %s access specifier in c and c++.
 A string is always terminated with \0 (Null) character.

 Example of string: “Gaurav”


 A string always recognized in double quotes.
 A string also consider space as a character.
 Example: ” Gaurav Arora”
 The above string contains 12 characters.
 Example: Char ar[20]
 The above example will store 19 character with I null character.

Strings are just char arrays. So, they can be passed to a function in a similar manner as arrays.

#include <stdio.h>
void displayString(char str[]);
int main()
{
char str[50]; printf("Enter string: ");
gets(str);
displayString(str);
// Passing string c to function. return 0;
}
void displayString(char str[])
{
printf("String Output: ");
puts(str);
}

Here, string c is passed from main() function to user-defined function


displayString(). In function declaration, str[] is the formal argument

Example-2 :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void strreverse(char *string)
{
int i, len;
char c;
len=strlen(string);
char string2[len+1];

for(i=0; i<len; i++)


{
c=string[i];

string2[len-i]=c;

}
string2[len+1]='\0';
string=string2;
//printf("%s\n", string);
}

int main(int argc, char *argv[])


{
char str[256];
printf("Type a String to reverse it.[max. 255 chars]\n");
fgets(str, 255, stdin);
strreverse(&str[0]);
printf("%s", str);
return 0;
}
Arguments Passing with pointers

A pointer to a function is passed in this example. As an argument, a pointer is passed instead of a variable
and its address is passed instead of its value. As a result, any change made by the function using the pointer
is permanently stored at the address of the passed variable. In C, this is referred to as call by reference.
Below is the C program to pass arguments to function with pointers:

// C program to swap two values


// without passing pointer to
// swap function.
#include <stdio.h>

void swap(int* a, int* b)


{
int temp;
temp = *a;
*a = *b;
*b = temp;
}

// Driver code
int main()
{
int a = 10, b = 20;
printf("Values before swap function are: %d, %d\n", a, b);
swap(&a, &b);
printf("Values after swap function are: %d, %d", a, b);
return 0;
}

Output:

Values before swap function are: 10, 20


Values after swap function are: 20, 10
C Recursion
Recursion is the process of a function calling itself repeatedly till the given condition is satisfied. A
function that calls itself directly or indirectly is called a recursive function and such kind of function
calls are called recursive calls.

In C, recursion is used to solve complex problems by breaking them down into simpler sub-problems.
We can solve large numbers of problems using recursion in C. For example, factorial of a number,
generating Fibonacci series, generating subsets, etc.

Applications of Recursion in C

Recursion is widely used to solve different kinds of problems from simple ones like printing linked
lists to being extensively used in AI. Some of the common uses of recursion are:

 Tree-Graph Algorithms

 Mathematical Problems

 Divide and Conquer

 Dynamic Programming

 In Postfix to Infix Conversion

 Searching and Sorting Algorithms

Advantages of C Recursion

The advantages of using recursive methods over other methods are:

1. Recursion can effectively reduce the length of the code.

2. Some problems are easily solved by using recursion like the tower of Hanoi and tree
traversals.

3. Data structures like linked lists, trees, etc. are recursive by nature so recursive methods are
easier to implement for these data structures.

Disadvantages of C Recursion

As with almost anything in the world, recursion also comes with certain limitations some of which
are:

1. Recursive functions make our program a bit slower due to function call overhead.

2. Recursion functions always take extra space in the function call stack due to separate stack
frames.

3. Recursion methods are difficult to understand and implement.


Recursive Functions in C

In C, a function that calls itself is called Recursive Function. The recursive functions contain a call to
themselves somewhere in the function body. Moreover, such functions can contain multiple
recursive calls.

Basic Structure of Recursive Functions

The basic syntax structure of the recursive functions is:

type function_name (args) {


// function statements
// base condition
// recursion case (recursive call)
}

Types of C Recursion

Examples of Recursion in C

Example 1: C Program to Find the Factorial of a Natural Number using Tail Recursion.

// C program to find the factorail using tail recursion

#include <stdio.h>

int factorialTail(int n) {

// Base case

if (n == 1 || n == 0) {

return 1;

} else {

// Tail recursive call

return n * factorialTail(n - 1);


} }

int main() {

int n = 5;

int fact1 = factorialTail(n);

printf("Resursive Factorial of %d: %d \n", n, fact1);

return 0;

Output:

Resursive Factorial of 5: 120

Example 2: Fibonacci Series using recursion in C

#include<stdio.h>

void printFibonacci(int n){

static int n1=0,n2=1,n3;

if(n>0){

n3 = n1 + n2;

n1 = n2;

n2 = n3;

printf("%d ",n3);

printFibonacci(n-1);

} }

int main(){

int n;

printf("Enter the number of elements: ");

scanf("%d",&n);

printf("Fibonacci Series: ");

printf("%d %d ",0,1);

printFibonacci(n-2);//n-2 because 2 numbers are already printed

return 0; }

Output:

Enter the number of elements:15

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377


Dynamic Memory Allocation in C
using malloc(), calloc(), free() and realloc()
Since C is a structured language, it has some fixed rules for programming. One of them includes
changing the size of an array. An array is a collection of items stored at contiguous memory
locations.

As can be seen, the length (size) of the array above is 9. But what if there is a requirement to change
this length (size)? For example,

 If there is a situation where only 5 elements are needed to be entered in this array. In this
case, the remaining 4 indices are just wasting memory in this array. So there is a
requirement to lessen the length (size) of the array from 9 to 5.

 Take another situation. In this, there is an array of 9 elements with all 9 indices filled. But
there is a need to enter 3 more elements in this array. In this case, 3 indices more are
required. So the length (size) of the array needs to be changed from 9 to 12.

This procedure is referred to as Dynamic Memory Allocation in C.

Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the size of a data
structure (like Array) is changed during the runtime.

C provides some functions to achieve these tasks. There are 4 library functions provided by C defined
under <stdlib.h> header file to facilitate dynamic memory allocation in C programming. They are:

1. malloc()

2. calloc()

3. free()

4. realloc()

Let’s look at each of them in greater detail.

C malloc() method

The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large
block of memory with the specified size. It returns a pointer of type void which can be cast into a
pointer of any form. It doesn’t Initialize memory at execution time so that it has initialized each
block with the default garbage value initially.
Syntax of malloc() in C

ptr = (cast-type*) malloc(byte-size)


For Example:

ptr = (int*) malloc(100 * sizeof(int));


Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And, the pointer ptr
holds the address of the first byte in the allocated memory.

If space is insufficient, allocation fails and returns a NULL pointer.

Example of malloc() in C

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

int n, i;

// Get the number of elements for the array

printf("Enter number of elements:");

scanf("%d",&n);

printf("Entered number of elements: %d\n", n);

// Dynamically allocate memory using malloc()

ptr = (int*)malloc(n * sizeof(int));

// Check if the memory has been successfully

// allocated by malloc or not

if (ptr == NULL) {
printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

printf("Memory successfully allocated using malloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

return 0;

Output:

Enter number of elements: 5

Memory successfully allocated using malloc.

The elements of the array are: 1, 2, 3, 4, 5,

C calloc() method

1. “calloc” or “contiguous allocation” method in C is used to dynamically allocate the specified


number of blocks of memory of the specified type. it is very much similar to malloc() but has
two different points and these are:

2. It initializes each block with a default value ‘0’.

3. It has two parameters or arguments as compare to malloc().

Syntax of calloc() in C

ptr = (cast-type*)calloc(n, element-size);


here, n is the no. of elements and element-size is the size of each element.
For Example:

ptr = (float*) calloc(25, sizeof(float));


This statement allocates contiguous space in memory for 25 elements each with the size of the float.

If space is insufficient, allocation fails and returns a NULL pointer.

Example of calloc() in C

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()

ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by calloc or not

if (ptr == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {
// Memory has been successfully allocated

printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

} }

return 0; }

Output:

Enter number of elements: 5

Memory successfully allocated using calloc.

The elements of the array are: 1, 2, 3, 4, 5,

C free() method

“free” method in C is used to dynamically de-allocate the memory. The memory allocated using
functions malloc() and calloc() is not de-allocated on their own. Hence the free() method is used,
whenever the dynamic memory allocation takes place. It helps to reduce wastage of memory by
freeing it.

Syntax of free() in C

free(ptr);
Example of free() in C

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int *ptr, *ptr1;

int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using malloc()

ptr = (int*)malloc(n * sizeof(int));

// Dynamically allocate memory using calloc()

ptr1 = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by malloc or not

if (ptr == NULL || ptr1 == NULL) {

printf("Memory not allocated.\n");

exit(0);

else {

// Memory has been successfully allocated

printf("Memory successfully allocated using malloc.\n");

// Free the memory

free(ptr);

printf("Malloc Memory successfully freed.\n");

// Memory has been successfully allocated

printf("\nMemory successfully allocated using calloc.\n");

// Free the memory


free(ptr1);

printf("Calloc Memory successfully freed.\n");

return 0; }

Output:

Enter number of elements: 5

Memory successfully allocated using malloc.

Malloc Memory successfully freed.

Memory successfully allocated using calloc.

Calloc Memory successfully freed.

C realloc() method

“realloc” or “re-allocation” method in C is used to dynamically change the memory allocation of a


previously allocated memory. In other words, if the memory previously allocated with the help of
malloc or calloc is insufficient, realloc can be used to dynamically re-allocate memory. re-allocation
of memory maintains the already present value and new blocks will be initialized with the default
garbage value.

Syntax of realloc() in C

ptr = realloc(ptr, newSize);


where ptr is reallocated with new size 'newSize'.

If space is insufficient, allocation fails and returns a NULL pointer.


Example of realloc() in C

#include <stdio.h>

#include <stdlib.h>

int main()

// This pointer will hold the

// base address of the block created

int* ptr;

int n, i;

// Get the number of elements for the array

n = 5;

printf("Enter number of elements: %d\n", n);

// Dynamically allocate memory using calloc()

ptr = (int*)calloc(n, sizeof(int));

// Check if the memory has been successfully

// allocated by malloc or not

if (ptr == NULL) {

printf("Memory not allocated.\n");

exit(0);

} else {

// Memory has been successfully allocated

printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array

for (i = 0; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

}
// Get the new size for the array

n = 10;

printf("\n\nEnter the new size of the array: %d\n", n);

// Dynamically re-allocate memory using realloc()

ptr = (int*)realloc(ptr, n * sizeof(int));

// Memory has been successfully allocated

printf("Memory successfully re-allocated using realloc.\n");

// Get the new elements of the array

for (i = 5; i < n; ++i) {

ptr[i] = i + 1;

// Print the elements of the array

printf("The elements of the array are: ");

for (i = 0; i < n; ++i) {

printf("%d, ", ptr[i]);

free(ptr);

} return 0; }

Output:

Enter number of elements: 5

Memory successfully allocated using calloc.

The elements of the array are: 1, 2, 3, 4, 5,

Enter the new size of the array: 10

Memory successfully re-allocated using realloc.

The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,


Storage Classes in C
Storage classes in C are used to determine the lifetime, visibility, memory location, and initial value
of a variable. There are four types of storage classes in C

o Automatic

o External

o Static

o Register

Storage Storage Default Scope Lifetime


Classes Place Value

auto RAM Garbage Local Within function


Value

extern RAM Zero Global Till the end of the main program Maybe declared
anywhere in the program

static RAM Zero Local Till the end of the main program, Retains value
between multiple functions call

register Register Garbage Local Within the function


Value

Auto Storage Class

o Automatic variables are allocated memory automatically at runtime.

o The visibility of the automatic variables is limited to the block in which they are defined.

The scope of the automatic variables is limited to the block in which they are defined.

o The automatic variables are initialized to garbage by default.

o The memory assigned to automatic variables gets freed upon exiting from the block.

o The keyword used for defining automatic variables is auto.

o Every local variable is automatic in C by default.

Example 1

#include <stdio.h>

int main() {

int a; //auto

char b;
float c;

printf("%d %c %f",a,b,c); // printing initial default value of automatic variables a, b, and c.

return 0; }

Output:

garbage garbage garbage

Example 2

#include <stdio.h>

int main()

int a = 10,i;

printf("%d ",++a);

int a = 20;

for (i=0;i<3;i++) {

printf("%d ",a); // 20 will be printed 3 times since it is the local value of a

} }

printf("%d ",a); // 11 will be printed since the scope of a = 20 is ended.

Output:

11 20 20 20 11

Static Storage Class

o The variables defined as static specifier can hold their value between the multiple function
calls.

o Static local variables are visible only to the function or the block in which they are defined.

o A same static variable can be declared many times but can be assigned at only one time.

o Default initial value of the static integral variable is 0 otherwise null.

o The visibility of the static global variable is limited to the file in which it has declared.

o The keyword used to define static variable is static.


Example 1

#include<stdio.h>

static char c;

static int i;

static float f;

static char s[100];

void main () {

printf("%d %d %f %s",c,i,f); // the initial default value of c, i, and f will be printed.

Output:

Backward Skip 10sPlay VideoForward Skip 10s

0 0 0.000000 (null)

Example 2

#include<stdio.h>

void sum()

static int a = 10;

static int b = 24;

printf("%d %d \n",a,b);

a++;

b++;

void main() {

int i;

for(i = 0; i< 3; i++) {

sum(); // The static variables holds their value between multiple function calls.

} }

Output:

10 24

11 25

12 26
Register Storage Class

o The variables defined as the register is allocated the memory into the CPU registers
depending upon the size of the memory remaining in the CPU.

o We can not dereference the register variables, i.e., we can not use &operator for the
register variable.

o The access time of the register variables is faster than the automatic variables.

o The initial default value of the register local variables is 0.

o The register keyword is used for the variable which should be stored in the CPU register.
However, it is compiler?s choice whether or not; the variables can be stored in the register.

o We can store pointers into the register, i.e., a register can store the address of a variable.

o Static variables can not be stored into the register since we can not use more than one
storage specifier for the same variable.

Example 1

#include <stdio.h>

int main() {

register int a;

// variable a is allocated memory in the CPU register. The initial default value of a is 0.

printf("%d",a);

Output:

Example 2

#include <stdio.h>

int main() {

register int a = 0;

printf("%u",&a); // This will give a compile time error since we can not access the address of
a register variable.

Output:

main.c:5:5: error: address of register variable ?a? requested

printf("%u",&a);

^~~~~~
External Storage Class

o The external storage class is used to tell the compiler that the variable defined as extern is
declared with an external linkage elsewhere in the program.

o The variables declared as extern are not allocated any memory. It is only declaration and
intended to specify that the variable is declared elsewhere in the program.

o The default initial value of external integral type is 0 otherwise null.

o We can only initialize the extern variable globally, i.e., we can not initialize the external
variable within any block or method.

o An external variable can be declared many times but can be initialized at only once.
o If a variable is declared as external then the compiler searches for that variable to be
initialized somewhere in the program which may be extern or static. If it is not, then the
compiler will show an error.

Example 1

#include <stdio.h>

int main() {

extern int a;

printf("%d",a);

Output

main.c:(.text+0x6): undefined reference to `a'

collect2: error: ld returned 1 exit status

Example 2

#include <stdio.h>

int a;

int main() {

extern int a; // variable a is defined globally, the memory will not be allocated to a

printf("%d",a);

Output

0
Example 3

int a;

int main() {

extern int a = 0;

// this will show a compiler error since we can not use extern and initializer at same time

printf("%d",a);

Output

compile time error

main.c: In function ?main?:

main.c:5:16: error: ?a? has both ?extern? and initializer

extern int a = 0;

Example 4

#include <stdio.h>

int main() {

extern int a; // Compiler will search here for a variable a defined and initialized somewhere
//in the program or not.

printf("%d",a);

int a = 20;

Output

20

Example 5

extern int a;

int a = 10;

#include <stdio.h>

int main() {

printf("%d",a); }

int a = 20; // compiler will show an error at this line

Output

compile time error

You might also like