Sei sulla pagina 1di 45

78 Procedure Oriented Programming Using C

TJNIT 4
-

4.1.1. Introduction
must be called main. Execution of the program will always begin by
carrying-out the instructions in main. Additional functions will be
subordinate to main, and perhaps to one another.

.*lling portion of the program, and return a single value.

(also called parameters), and retunred via the return statement.

type void), whereas other filnctions return multiple values, with help of
pointers and arguments (e.g.. librarv function scanf).

4.1.2. Purpose of Functions


factoring them into small, simple and manageable parts.
The use of functions provides a way to reuse code that is required in more
than one place in a program.
C language comes with a rich and valuable library. These C libraries provide
standard functions that make our work as a programmer much easier.
Programmer can also crsate our personal libraries that make developing new
systems much easier.
The use of functions cim protect data. This is done using the concept of local
data. Local data consist of clata described in a function. This data is available
only to the function and only while the function is executing. When the
function is not executing. the data is not accessible. Data in one function,
then, cannot be seen or changed by another function.

4.1.3. StandardFunctions
The functions that are inbuilt in the language compiler are library functions. For
example, printf0 and scanf0 belongs to the category of library functions.

The C language comprises a library of standard functions. Most versions of C


provide the libraries in both source code and re-locatable code. The re-locatable
code is already compiled into an intermediate code which is linked with the
compiled main program to form the final object code program.
These standard functions perform most of the commonly used operations or
calculations such as inpuUoutput operations (read and write characters), open and
close files, functions that perform operations on characters (conversion from
lower case to uppercase and vice versa), functions to carr5r-out mathematical
calculations (findirrg square roots, evaluate trigonometric expressions), functions
that perform operations on strings (comparing two strings, concatenating strings),
etc. Table 4.1 show the some library functions available in C language:

Table 4.1: Library Functions of C


Function Type Purpose Include
File
abs(i) int Returns the absolute value of i. stdlib.h
exit(u) void Closes all files and buffers and terminates the stdlib.h
Drosram.
fclose(0 int Closes file f. Retums 0 if the file is stdio.h
successfully closed.
fsete(fl int Enters a single character from file f. stdio.h
tgets(s, i, f1 char Enter string s, containing i characters, from stdio.h
file f.
fopen(s1, s2) FILE* Opens a file named sl of s2 type. Returns a stdio.h
pointer to a file.
fprind(f.. int Sends data items to file f. stdio.h
fputc(c, O int Sends a single character to file f. stdio.h
fputs(s, O int Sends strins s to file f. stdio.h
fread(s, il, i2, int Inputs i2 data items each of size i1 bytes, stdio.h
0 from file f to string s.
free(p) void Frees a block of allocated memory whose Malloc.h or
startins address is indicated by p. stdlib.h
fscanf(f....) int Inputs data items from fiIe f. stdio.h
fseek(fl 1, i) int Moves the pointer for file f at distance 1 stdio.h
bytes frorn location i (i may represent pointer
oosition or end-of-file).
pow(d1, d2) double Returns dl raised to the power d2. math.h
printf(...) int Sends data items to the standard output stdio.h
device.
putchar(c) int Sends a single character to the oufput device. stdio.h
puts(s) int Sends the string a to the standard output stdio.h
device.
scanf(. .. .) .int Allows input of data items from the standard stdio.h
ouout device.
strcmp(sl, s2) int Compares two stringS. Relums a -ve value if sring.h
sl < s2, 0 if sl = s2, +ve if sl > s2.
strcpy(s1, s2) char* Copies string s2 to string sl strine.h
strlen(s) int Returns the number of characters in string s. strine.h
toascii(c) int Converts value of argument to ASCII. ctvoe.h
tolower(c) int Converts value'of argument to lower-case. ctype.h or
stdlib.h
toupper(c) int Converts lefter to upper-case. ctype.h or
stdlib.h
To use the standard library functions, one has to include certain specific
information, within the main portion of the program. This type of information is
stored in special files. These special files are accessed with the preprocessor
statement #include and followed by the filename as shown below:
#include<filename>

These special files are generally supplied with the compiler. The commonly used
filenames are stdio.h, stdlib.h, etc. The suffix "h" denotes a "header" file. This
file has to be included at the beginning of the program.

4.1.4. User-DefinedFunctions
These are actually the user modules that are delibeqately cleated for a specific
purpose. This creation of modules results in function. Various programming
constructs like looping, jumping are used with it.

The main difference between built-in and user-define functions is that library
functions are not required to be written by us whereas a user-defined function has
to be developed by the user at the time of writing a program.

However, a user-defined function can later become a part of the C program


library.

Need for User-defined Functions


There are times when certain operation or calculations are to be repeated during a
program. For example, we may use a factorial of a number or printing some
string lines in the program. In these situations'we may repeat the code in our
program or just copy-paste it. That's why we make these user-defined functions
and use it whenever necessary. Here, user-defined functions can be really helpful
and can save the time and program space.

4.1.5. FunctionDefinition
The general form of a function definition in C programming language is as
follows:
Syntax:
return_type function_name(parameter list)
t
body of the function
)

A function definition in C programming language consists of a function header


and a function body. Here are all the parts of a function:
1) 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=
2) Function Name: This is the actual name of the function. The function name
and the parameter list together constitute the function signature.
3) 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; i.e., a
function may contain no parameters.
4) Function Body: The function body contains a collection of statements that
define what the function does.

For example, Following is the source code for a function called maxO. This
function takes two parameters numl and num2 and returns the maximum
between the two:
*/
/* function returning the max between two numbers
int max(int numl, int num2)
{
/* local variable declaration */
int result;

if(num1>num2)
result = numl;
else
result = num2;
return result;
)

Rules for Defining Functions


1) The first statement of the function must be the function defining statement
specifying the return type, name and formal arguments'
2) Ii tfre iype of the functi,on is omitted, then it is assumed of type integer (int).
But it is recommended that the return type must be explicitly specified.
3) Rules for naming a function are same as for variable names'
4) The formal arguments should neither be constants or expressions.
5i If a formal argument is an array name, it must be declared as an array in a
type declaration statement before the body of the function starts and its
miximum size must be equal to the actual size in the calling function.

4.1..6. Function Declaration


A function declaration statement is also known as prototype of the function or as
function prototype. Function declaration consists only of a function header; it
contains no code. Function header consists of three parts:
Syntax:
return-type Function-name(argument list);

1) Return-Type: If the function has no arguments, then write void in the


parentheses, etse the specific return type is mentioned. If the function has two
or more arguments, each is separated by comma'
2) Function-Name: It is given by the programmer as in case of variables'
3) Argument List: It is not mandlts, (essential) to include the names of the
arguments in the argument list. The purpose of the argument list is
to tell the
compiler the number, data type and order of *gr*.ntr. The names of
arguments do not need to be the same in the function declaration
and the
function definition. on the other hand, if the data types do not match, the
compiler will flag an error. The compiler checks the data types of the arguments .
in the function call to ensure that they are the same or atleasicompatibility.

A semicolon follows the function header. Function declarations also provide


an
excellent quick reference for functions used in the program, making them
excellent documentation.
For example,
int largest(int a, int b, int c);

Explanation: Above function definition tells the compiler that the return type of
the function is int, name of the function is largest, *a- it has three
arguments, all
of type int. The names of argument are not significant.

4.1.6.1. Rules for Declaring a Function


1) The parameter list must be separated by commas.
2) The parameter names de not need to be the same in the prototype declaration
and the function definition.
3) The types must match the types of parameters in the function definition,
in
number and order.
4) Use of parameter names in the declaration is optional.
5) If the function has no formal parameters, the liit is written as (void).
6) The return type is optional, when the function returns int type data.
7) The retype must be void if no value is returned.
8) when the declared types do not march with the types in the function
definition, compiler will produce an error.

4.1.6.2. Location of Declaration in program


The place of declaration of a function defines a region in a program
in which the
function may be used by other functions. This ."gio, is knoJn as the
scope of
the function.

A prototype declaration may be placed in two places in a program:

Places for Prototype Declaration

Above all functions Inside Function Definition


(Global Prototype) (Local Prototype)

1) Above All Functions (Gionat prototype): Ir also includes main0.


when we
place the declaration above all the functions (in the global
declaration
section), the prototype is referred to as a global prototype.-Such
declarations
are available for all the functions in the program.
2) Inside Function Definition (Local Prototype): When we place it in a
function definition (in the local declaration section), the prototype is called a
local prototype. Such declarations are primarily used by the functions
containing them.

It is a good programming style to declare prototypes in the global declaration


section before main. It adds flexibility, provides an excellent quick reference to
the functions used in the program, and enhances documentation.

Function prototypes are not mandatory in C. They are desirable, however,


because they further facilitate error checking between the calls to a function and
the corresponding function definition.

4.1.7. FunctionArguments
Basically there are two types of function arguments in c:
Function Arguments

4.L.7.1. ActualArguments
Sometimes a function may be called by a portion of a program with some
parameters and these parameters are known as the actual arguments.

For example,
main0
t
int x, y;

output(x, Y); /* x and y are the actual arguments */


)

4.L.7.2. FormalArguments
The formal arguments are those parameters present in a function definition and it
may also be called as dummy arguments or the parametric variables.

For example,
main0
t
int x, y;

output(x, y);
)

output(a,b) x/ formal or dummy arguments x/


int a, b;
t
/x body ofthe function */
)

The formal arguments may be declared by the same'name or different in calling a


portion of the program and a called function but the data types should be same in
both blocks.

For example, the following function declaration is invalid:


main0
{
int x, y;
char s1, s2

function(x, y, s1, s2);


)

function (x, y, sl, s?)l* datatype mismatch */


char x, y;
int sl, s2;
t
/* body of a function */
)

4.1..8. Function Call


list of arguments enclosed in parentheses and separated by commas.

statement), or it may be one of the operands within a more complex


expression.

of precedence. Therefore, when a function call is used as a part of an


expression, it will be evaluated first, unless parentheses are usedto change
the order of precedence.

which contains the actual parameters is the operator. The actual parameters
must match the function's formal parameters in type, order and number.
Multiple actual parameters must be separated by commas.

Note:
i) If the actual parameters are more than the formal parameters, the extra actual
arguments will be discarded.
ii) on the other hand, if the actuals are less than the formals, the unmatched
formal arguments will be initialized to some garbage.
iii) Any mismatch in data types may also result in some garbage values.
Argument Conversions
When a function is called, there are a number of possible conversions that will be
applied to the values supplied as arguments depending on the presence or absence
oi a prototype.

The rules mention the default argument promotions and compatible type' Where
they are used, the default argument promotions are:
1) Apply the integral promotions to the value of each argument,
2) lf tie type of the argument is float it is converted to double'
Rules for Conversion
1) At the point of calling a function, if no prototype is in scope, the arguments
all undergo the default argument promotions' Furthermore:
i) If th; number of arguments does not agree with the number of formal
parameters to the function, the behavior is undefined
ii) If the function definition was not a definition containing a prototype, then
the type of the actual arguments after promotion must b-e compatible with
the types of the formal parameters in the definition after they too have
had thi promotions applied. Otherwise the behavior is undefined.
iii) If the function definition was a definition containing a prototype, and the
types of the actual arguments after promotion are not compatible with the
formal parameters in the prototype, then the behavior is undefined. The
behavior is also undefined if the prototype included ellipsis(, ...).
2) At the point of calling a function, if a prototype is in scope, the arguments are
converied, as if by assignment, to the types specified in the prototype' Any
arguments which ialt under the variable argument list category (specified by
the prototype) still undergo the default argument conversions.

Program 1: /*Function and function calls*/


#include<stdio.h>
#include<conio.h>
/* function declaration */
int max(int num1, int num2);
main0
t
/* local variable definition */
int a = 100;
ir16 = 200;
int ret;
/* calling a function to get maximum value
*/
ret = max(a, b)l
printf("Max value is : 7od\n", ret);
getch0;
)
/* function refurning the max between two numbers
*/
int max(int num1, int num2)
{
/8 local variable declaration */
int result;
if(numl>num2)
result = numl;
else
result = num2;
return result;
)

4.1.9. Parameter Passing Mechanism


The mechanism used to pass data to a function is via argument list, where
individual arguments are called actual arguments. These *g,rm"nt5, are enclosed
in parentheses after the function name.

The actual arguments must correspond in number, type, and order with formal
arguments specified in the function definition. The actual arguments can be
constants, variables, array names, or expressions.

There are two approaches to passing arguments to a function:


1) Call by Value,
2) Call by Address (Reference).
4.1.9.1. Call by Value
In this type value of actual arguments are passed to the formal arguments and the
operation is done on the formal arguments. Any change made in the formal
argument does not affect the actual arguments because formal arguments are
photocopy of actual arguments.

Hence, when function is called by the call or by value method, it does not affect
the actual contents of the actual arguments. Changes made in the formal
arguments are local to the block of.the called function. Once control returns back
to the calling function the changes made vanish.

Important Points Regarding Call by Value Mechanism


1) The actual arguments can be constants, variables, or expressions.
2) when the control is transferred from the calling function to the called
function, the memory for formal arguments and local variables is allocated,
values of the actual arguments are substituted in the corresponding formal
arguments, and the statements in the function body are executed.
3) As soon as the called function finishes its execution, the memory allocated
for it is deallocated, i.e., the values of formal arguments and local variable are
destroyed, and finally the control is transferred back to the calling function.
4) Any change made to the formal arguments will have no effect on actual
arguments, since the function will only be using the local copy of the
arguments.

Program 2z *lTo send values by call by value*/


#include<stdio.h>
#include<conio.h>
void main0
t
int x, y, change(int, int);
clrscr0;
printf("\n Enter values of X and Y:");
sc anf (" 7a d%od ", &x, &Y) ;
change(x,y):
printf("\n In main0 X=VodY=%od",x,y);
getch0;
)
change(int a,int b)
t
int kl
I-_^.
l\-4,
a=b:
b=k;
printf("\n In change0 X=Vod Y =Vod",a,b);
)
Output

Explanation: In the above plogram we are passing values of the actual argument
,x' and 'y' to the function change$. The formal argument 'a' and 'b' of function
change0 receives these values0. The values are interchanged, i.e., value of 'a' is
assigned to 'b' and vice versa and printed. When the control returns back to the
main0, the changes made in function change0 vanishes. In the main0 the values
of ,x' and 'y' are printed as they are read from the keyboard. In call by value
method the formal argument acts as a photocopy of the actual argument. Hence,
changes made in them are temporary.

4.1.9.2. Call by Reference (Address)


Call by reference, the addresses of the actual arguments is used in the function
call. In this way the addresses of the actual arguments are passed to the function.
When control is transferred to the called function, the addresses of the actual
arguments are substituted to corresponding fory1l arguments and the body of the
function is executed. The formal arguments aG?echred as pointers to types that
match the data types of the actual arguments. This approach is of practical
importance while passing iurays and structures among function, and also for
passing back more than one value to the calling functions.

If the called function is supposed to return a value, it is returned via return


statement. Additional values can be returned to the calling function via formal
arguments which will be of pointer type.

Important Points Regarding Call by Reference Mechanism


The following rules must be noted about passing arguments using call by
reference mechanism:
1) The actual arguments can only be variables.
2) When the control is transferred from the calling function to the called
function, the memory for formal arguments and local variables is allocated,
addresses of the actual arguments are substituted in the corresponding formal
arguments, and the statements in the function body are executed.
3) As soon as the called function finishes its execution, the memory allocated for
it is deallocated, i.e., the values of formal arguments and local variables are
destroyed, and finally the control is transferred back to the calling function.
4) Any change made to the formal arguments will have immediate effect on
actual arguments, since the function will be working on actual arguments
through pointers.

Program 3: /* To send a value by reference to the user-defined function.s/


#include<stdio.h>
#include<conio.h>
void main0
t
int x, y, change(int*, int*);
clrscr0;
printf("\n Enter values of X and Y:");
scanf(" Vo dVod", &x, &y) ;
change(&x, &y);
printf("\n In main0 X=VodY=Vod", x, y);
getch0;
)
change(int*a, int*b)
{
int *k;
*k={<a.
*a=*b;
*b=*k;
printf("\n In change0 X=VodY=Vod", *a,*b);
return;
)
Explanation: Here addresses of formal arguments are passed to the function
chalngeo. The pointers in the changeo receive these addressesO function, i.e.,
poinf,r'points tL the actual argument. Here the change0 function operates on the
actual argument through the pointer. Hence, the changes made in the values are
p".*un"nt. In this type of call no return statement is required'

4.1.9.3. Differences between call by value and call by Reference


Table 4.2 shows the some basic difference between call by value and call by reference.
Table 4.2
Call by Value Call by Reference
Formal parameter is a new local variable Formal parameter is an alias for the
that exists within the scoPe of the actual parameter.
orocedure/ fu nction/subprogram.
Value of actual parameter is used to Formal parameter refers to the same
initialize the formal Parameter' memory cell for the actual parameter.
Changes made to formal parameter DO Each fonnal parameter is a reference to
NOT get transmitted back to the caller. the actual parameter and modifying the
formal will modify the actual.
C and Java restrict themselves to Call by C++ and Pascal let you declare that a
Value. parameter is a reference.

4.L.10. Types of Functions


A function, depending on whether arguments are present or not and whether
value is returned or not, may belong one of the following ways:
Types of Functions

Function with no Argument and


no Retum Value Functions with Arguments and
no Return Value
Function with Arguments and
Function with no Argument but
one Return Value
Return a Value

Function that Retum Multiple Values

4.1.10.1. No Arguments and No Return Values


It is tlie simplest way of writing a user-defined function in C. There is no data
communication between a calling portion of a program and a called function block.
The function is invoked by a calling environment by not feeding any formal
s1'clrrntents and the function also does not return back anything to the caller'
For example,
main0
{
int x, y;

message0; /* function is invoked */


)
message0
{
/* body of the function */
)

4.1.10.2. Arguments but No Return Values


The second type of writing a user-defined function is passing some formal
arguments to a function but the function does not return back any value to the
caller, it is a one way data communication between a calling portion of the
program and the function block.
For example,
main0
{
int x, y;
power(x, y); /* function declaration x/

)
power(x, y)
int x, y;
{
/x body of the function */
/* no values will be transferred back to the caller */
)

Program: A program to find the square of its number using a function


declaration without using the return statement.
/* passing formal arguments and no retum statement */
#include<stdio.h>
#include<conio.h>
main0
{
int i, max;
printf('Enter a value for n ?\n');
scanf("Vod", &max);
it. p.irtf("number square \n";
printf(, _ \r,,);
for(i=0' i<=max-l ; ++i)
square(i);
)
square(n)
int n; '-t
{
int temp;
temP = nt1'
printf("7o d\t\t %o d\n', n, temp) ;
)

4.1.10.3. Arguments with Return Values


The third type of writing a user-defined function is passing some formal
arguments to a function from calling the portion of the program and the computed
values, if any, is transferred back to the caller. Data are cofilmunicated between
calling the portion and a function block.
For example,
main0
t
int x. y, temp:
char ch;

temP = outPut(x, Y, ch);


)
output(a, b, s)
int a, b;
char s;
{
int value;
/* body ofthe function */
return(something);
)

Program: program to find the square of its number using


A a function
declaration using the return statement.
/* passing formal arguments and return statement */
#inciudecstdio.h>
#include<conio.h>
main0
{
int i, max, temp;
printf('Enter a value for n?\n");
scanf("%od", &max);
printf("number square \n") ;
printf("_ \o");
for(i=0; i<=max - 1; ++i){
temP = square(i);
printf("7od\t\t Vod\n', i, temP) ;

)
)
square(n)
int n;
{
int value;
value = n*n;
return(value);
)

4.1.10.4. No Arguments but Return a Value


Sometimes one may need to design functions that may not take any arguments
but returns a value to the calling function. A typical example is the getchar
function declared in the header file <stdio.h>. The getchar function has no
parameters but it returns an integer type data that represents a character.

One can design similar functions and use in the programs. For example,
int get-number(void);
main
)
int m = get_numbero;
pintf("Vod",m);
)
int get_number(void)
{
int number;
scanf(" Vo {', &number) ;
return(number);
)

4.1.10.5. Functions that Return Multiple Values


If one wants to get more information from a function then he/she can achieve this
in C using the arguments not only to receive information but also to send back
information to the calling function. The arguments that are used to "send-out"
information are called output parameters.

The mechanism of sending back information through arguments is achieved using


what are known as the address operator (&) and indirection operator (*). Let us
consider an example to illustrate this:

void mathoperation(int x, int y, int *s, int *d);


.t
main0
{
int x = 20,y = 10, s, d;
mathoperation(x, y, &s, &d);
pintf("s=7od\n d=%d\n", s, d)i
void mathoperation(int a, int b, int *sum, int *diffl
{
*sum=a+b;
*diff=a-b;
)
The actual arguments x and y are input arguments, s and d are output arguments.
In the function call, while we pass the actual values of x and y to the function, we
pass the addresses of locations where the values of s and d are stored in the
memory. (That is why, the operator & is called the address operator.) When the
function is called the following assignments occur:
value of x to a
value of y to b
address of s to sum
address of d to diff

Note: indirection operator * in the declaration of sum and diff in the header indicates
these variables are to store addresses, not actual values of variables. Now, the variables
sum and diff point to the memory locations of s and d respectively. Ghe operator * is
known as indirection operator because it gives an indirect reference to a variable
through its address.)

In the body of the function, we have two statements:


*sum=a+b;
*diff=a-b;
The first one adds the values a and b and the result is stored in the memory
location pointed to by sum. Remember, this memory location is the same as the
memory location of s. Therefore, the value stored in the location pointed to by
sum is the value of s.

Similarly, the value of a - b is stored in the location pointed to by diff, which is


the same as the location d. After the function call is implemented, the value of s is
a + b and the value of d is a - b. Output will be:
s=30
d=10
The variables xsum and *diff are known as 'pointers' and sutn and diff as
'pointer variables'. Since they are declared as int, they can point to locations of
int type data.

4.2.1. Introduction
In C, the scope of variables can be defined using some storage classes and can
define new type.

Local variables are declared inside a function. These are not known to other
functions outside their own function. In C, local variables are created when the
function is called and destroyed when the functions exit.
Local variables are further divided into auto and static variables.
Gtobal variables declared in main program and are known to all other functions. The
same variable name for global and local variable have the same name then all
reference to that variable name inside the function where the local variables is declared
will refer only to the local variable and will have no effect on the global variable.

4.2.2. Storage Classes


A storage class defines the scope (visibility) and life time of variables and/or
functions within a C Program. These specifiers precede the type that they modify.
There are following storage classes which can be used in a C Program:
Storage Classes

1) Auto Storage Class: The auto storage class is the default storage class for all
local variables.
{
I* aato variable declaration*/
int mount;
auto int month;
]
The example above defines two variables with the same storage tlass, auto
can only be used within functions, i.e.,local variables.

2) Register Storage Class: The register storage class is used to define local
variables that should be stored in a regist6r instead of RAM. This means that
the variable has a maximum size equal to the register size (usually one word)
and cannot have the unary '&' operator applied to it (as it does not have a
memory location).
{
/*register variable declaration*1

register int miles;


)
The register should only be used for variables that require quick access such
as counters. It should also be noted that defining 'register' goes not mean that
the variable will be stored in a register. It means that it might be stored in a
register depending on hardware and implementation restrictions.
i) Static Storage Class: The static storage class instructs the compiler to keep
a local variable in existence during the lifetime of the program instead of
creating and destroying it each time it comes into and goei out of scope.
Therefore, making local variables static allows them to maintain their values
between function calls.
The static modifier may also be applied to global variables. When this is done,
it causes that variable's scope to be restricted to the file in which it is declared.

In C programming, when static is used on a class data member, it causes only


one copy of that member to be shared by all objects of its class.

Program 4: /*Illustrating static storage class.*/


#include<stdio.h>
#inciude<conic.h>
/* function declaration */
void func(void);
static int count = 5; /* global variable */
main0
{
while(count--)
{
funcO;
)
return 0;
)
/* function definition */
void func(void)
{
static int i = 5; l* local static variable */
i++;
printf("i is Vod and count is Vod\n", i, count);
)

4) extirn Storage Class: The extern storage class is used to give a reference of
a global variable that is visible to all the program files. When you use
'extern' the variable cannot be initialised as all it does is point the variable
name at a storage location that has been previously defined.

When you have multiple files and you define a global variable or function
which will be used in other files also, then extern will be used in another file
to give reference of defined variable or function. Just for understanding
extern is used to declare a global variable or function in another file.
Program 5: /*Illustrating extern storage class.*/
#include<stdio.h>
#include<conio.h>
int a;
main0
t
extern int b;
pintf("Vod %od",a,b);
getch0;
)
int b=10;

t0utput,,:,{:, ,:{dli ,:&f i*rj}, *lt'E} ] ffij?


n C:\UserEfpravesh,."

4.2.3. Features of Storage Class Variables


Table 4.3: Summarv of Salient Features of Storase Class Variables
Keyword Declaration Accessibility Existence Place Default
Statement of Value of
Sfnraqe Variable
auto auto data_type Accessible within the Exists from the Primary Garbage
variable_name; function or block time of invocation memory
where it is declared. of function or
entry in the block
to its retum to the
calling function or
to the end of the
block.
register register Accessible within the Exists from the Register Garbage
data_type function or block time of invocation of CPU
variable_name; where it is declared. of function or
entry in the block
to its retum to the
callins function.
static static For Local: For Local: Primary Zero
data_type Accessible within the Preserves value memory
variable_name; function or block between function
'where it is declared. calls or block
For Global: entries.
Accessible within the For Global:
program file where it Preserves value in
is declared. the orosram file.
extern extern Accessible within the Exists as long as
Primary Zrro
data_type combination of the full
program memory
variable_name; program modules that is in execution.
form the full orosram.
4.3.1. Introduction
behind recursion is to decompose a problem into smaller sub-problems
which
are solved by recursivety catting the function that was called to solve the
original problem.

naturally recursive.

specified condition has been satisfied'

in terms of a previous ,e.rlt. Many iterative (i.e., repetitive) problems can be


written in this form.

i) The problem must be written in a recursive form,


ii) fne problem statement must include a stopping condition'

For example, suppose we wish to calculate the factorial of a positive integer


quantity. w" *outo normally express this problem as n! = lx2x 3 x...x n,
*h"r" n ir tt specified positive integer. However, we can also express this
"
problem in another way bywriting n! = n x (n - l)! This is a recursive statement
lf ttre prottem, in wtrictr ttre aesiriA acdon (the calculation of n!) is expressed in
t".-, of a previous result [the value of (n - 1)!, which is assumed to be known]'
Also, we know that 1! = 1 by definition. This last expression provides a stopping
condition for the recursion.

program 6: /* Calculate the factorial of an integer quantity using recursion


*l
#include<stdio.h>
#include<conio.h>

/* function prototype */
long int factorial(int n);
main0
t
int n;
long int factorial(int n);
/* read in the integer quantity */
clrscrO;
Printf("n = ";;
scanf("7od", &n);

printf("nl = 7o1d\n", factorial(n)); '*.r


| .t'
long int factorial(int n) /*calculate the factorial */
if(n<=l )
return(1);
else
return (n * factorial (n-1));
)

0utput

Ef* Tu,rba f o-+ trDE

Explanation: The main portion of the program simply reads the integer quantity
n and then calls the long-integer recursive function factorial. The function
factorial calls itself recursively, with an actual argument, (n 1) that decreases in
-
magnitude for each successive call. The recursive calls terminate when the value
of the actual argument becomes equal to 1.

The close correspondence between this function and the original problem
definition, in recursive terms, should be readily apparent. In particular, note that
the if-else statement includes a termination condition that beiomes active when
the value of n is less than or equal to 1.

Note: value of n will never be less than 1 unless an improper initial value is
entered into the computer.

When the program is executed, the function factorial will be accessed repeatedly,
once in main and (n - 1) times within itself, though the person using the program
will not be aware of this. only the final answer will be displayed, e.g.:
n= l0
.,s n! = 3628800

when a recursive progr:rm is executed, the recursive function calls are not
executed immediately. Rather, they are placed on a stack until the condition that
terminates the recursion is encountered. * The function calls are then executed in
reverse order, as they are "popped" off the stack. Thus, when evaluating a
factorial recursively, the function calls will proceed in the following order:
n!=nx(n-l)!
(n-1)!=(n-1)x(n-2)!
(n-2)l=(n*2)x(n-3)!
2! =2x l!
The actual values will then be returned in the following reverse order:
1!= 1

2t=2x 1! = 2xI=2
3!=3x21=3x2=6
4!=4 x 3!= 4x6=24

fl! =nx(n-1)! ="'


This reversal in the order of execution is a characteristic of all functions that
ale
executed recursivelY.

Ifa recursive function contains local variables, a different set of


local variables
will be created during each call. The names of the local variables will, of course,
always be the *u-", u. declared within the function. However, the variables
will
represent a different set of values each time the function is executed' Each set of
,ulu". will be stored on the stack, so that they will be available as the recursive
process unwinds, i.e., as the various function calls are "popped" off the stack and
executed.

4.3.2. Comparison of Iteration and Recursion


Table 4.4: between Iteration and Recursion
Iteration Recursion
1) Iteration is a Process of 1) Recursion is a process of executing
executing certain set of certain set of instructions repeatedly by
instructions rePeatedlY, without calling the self-function repeatedly.
calling the self-function.
2) The iterative functions are 2) Instead of making use of for, while, do-
implemented with the helP of while the repeatation in code execution
for, while, do-while is obtained by catling the same function
nrosramming constructs. aeain and again over some condition.
3) The iterative methods are more 3) The recursive methods are less efficient.
efficient because of better
execution sPeed.
4) Memory utilisation bY iteration 4) Memory utilisation is more in recursive
is less. functions.
5) It is simple to imPlement. 5) Recursive methods are complex to
implement.
6) The lines of code are more when 6) Recursive methods bring compactness
one uses iteration. in the program.

4.4.1. Introduction
location of anothei variable without using variable identifier itself. They are
mainly used in linked lists and call by reference functions'
addresses. It is possible to access and display the memory location of a
variable using '&' operator.

pointer variable and normal variable should be of the,.arrr" type. The pointer
is denoted by '*' symbol.

4.4.2. Uses of Pointers


1) Pointers are more efficient in handling arrays and data tables.
2) Pointers can be used to return multiple values from a function via function
arguments.
3) Pointers permit references to functions and thereby facilitating passing of
functions as arguments to other functions.
4) The use ofpointer turays to character strings results in saving ofdata storage
space in memory.
s) Pointers allow C to support dynamic memory management.
6) Pointers provide an efficient tool for manipulating dynamic data structures
such as structures, linked lists, queues, stacks anO trles.
7) Pointers reduce length and complexity of programs.
8) They increase the execution speed & thus reduce the program execution
time.

4.4.3. Understanding Memory Addresses


identified by a memory address. A memo.ry address is similar to a street
address -just as 345 and 34Tidentify differlnt houses on a street, different
memory locations are labeled with address numbers. Memory address
numbers are usually large numbers with many digits because the memory
of a
computer likely has billions of locations where data can be stored.

computer chooses an available memory location in which to store tir" int"g"r,


and then associates the name myAge with the memory address of lhat
location.
4 bytes word
High Addresses
languages allow you to use easy-
to-remember variable identifiers -
like myAge - so that you do not :

have to remember actual memory 20


addresses. An address is a 16
reference to a variable (or object),
t2
i.e., just as 345 refer to a specific
8
house, a memory address refers to
4
a specific object in memory.
0
fixed location, it is a constant. In Addresses go
other words, a variable,s address from low to higE Low Addresses
is not changeable; when you Figure 4.1: Memory
declare a variable, it is stored at a specific memory address that canttot be
altered. Although you cannot choose a variable's actual memory address, for
assigning the memory to a variable we use the address operator (&), also
called the refererice operator. Address operator is a unary operator that
returns the address of the variable that follows it.
Here is a simple figure 4.1 which shows showing the arrangement of
computer memory perplexed one. Memory is essentially an array of byte
addrissable elements in which binary values can be stored. Memory
addresses start at zeto and goes upto however much memory you have in
your computer.
Hardware architecture of the computer system dictates how physical memory
is arranged and accessed, but here we will assume that the word size is 32
bits. Looking at figure 4.1, memory starting at address 0 contains the four
bytes with addresses O, l, 2, and 3 for a total of 32 bits. The 32-bit memory
words are aligned on addresses divisible by 4, which is why the addresses 0,
4,8, 12, etc., are going-up the left side of memory in the diagram'

Figure 4.2 shows another way of representing memory that reinforces the
idea that it is a contiguous array of elements:

00000000 00000000 00000000 00000001 00000000 00000000 000000000 00000010 00000000 00000000

1
I
mal A
Addresses go from low to high

. Figure 4.2: Another Way to Represent Memory

Figure 4.2 also shows the memory initialized with two integer values. The
integer object beginning at address 0 has a value of 1. The second integer
object begins at address 4 and contains the value2.

4.4.4. Address of Operator/Address Operator (&)


The unary address-ofoperator (&) takes the address ofits operand. The operand
of the address-of operator can be either a function designator or an l-value that
designates an object that is not a bit field and is not declared with the register
storage-class sPecifier.

The address-of operator can only be applied to variables with fundamental,


structure, class, or union types that are declared at the file-scope level, or to
subscripted array references. In these expressions, a constant expression that does
not include the address-of operator can be added to or subtracted from the
address-of expression.
when applied to functions, the result of the expression.is a pointer type (an r-
value) derived from the type of the operand. For example, ii the operand is of
type char, the result of the expression is of type pointer to char. The address-of
operator, applied to const or volatile objects, evaluates to const typex or
volatile type*, where type is the type of the original object.

For example, suppose v is a variable that represents some particular data item.
The compiler will automatically assign memory cells for this data item. The data
item can then be accessed if we know the location (i.e., the address) of the first
memory cell.

Address of v's memory location can be determined by the expression &v, where
& is a unary operator, called the address operator, that evaluates the address ofits
operand.

Now let us assign the address of v to another variable, pv. Thus,


pv=&v
This new variable is called a pointer to v, since it "points" to the location where v
is stored in memory. pv represents v's address, not its value. Thus, pv is referred
to as a pointer variable. The relationship between pv and v is illustrated in figure
4.3.

Figure 4.3: Relationship between pv and v (where pv &v and v *pv)


= =

The data item represented by v (i.e., the data item stored in v's memory cells) can
be accessed by the expression *pv, where * is a unary operator, called the
indirection operator, that operates only on a pointer variable. Therefore, *pv and
v both represent the same data item (i.e., the contents of the same memory cells).
Furthermore, if we write pv = &v and u = *pv, then u and v will both represent
the same value, i.e., the value of v will indirectly be assigned to u. (It is aisumed
that u and v are of the same data type).

4.4.5. Definition
A pointer is a variable that points to another variable. This means that it holds the
memory address of another variable. So we can say that, the pointer does not hold
a value in the traditional sense; instead, it holds the address of another variable. It
points to that other variable by holding its address.

Because a pointer holds an address rather than a value, it has two parts. The
pointer itself holds the address. That addresses points to a value. There is the
pointer and the value pointed to.
For example, consider the following program'
#include<stdio.h>
void main()
t
int i, j;
int *p;/* a pointer to an integer
*/
P=&i:
*P=5;
j = i;
pintf(" %od Vod %od\n", i, j, *P) ;

Explanation: The line int *p declares a pointer. It asks the compiler to


declare a
* that a pointer is being
variable p that is a pointer io an integer. The indicates
declared rather than a normal variable. Programmer can create
a pointer to
anything: a float, a structure, a char, and so on'
..the memory address of the variable i,,.
The line P = &i;. expression &i means
Thus, the expression P = &i; means 'Assign to p the address of i"'
Once
programmer executes this statement, p points to i. Before he does so, p contains a
fault.
.urio*, unknown address, and its use will likely cause a segmentation

H
After the line p = &i; the memory situation looks something like this:

Note: p is represented by a circle to indicate that it is a pointer, while


i is
."p."r"nt"d by a square to indicate that it is a normal variable'
ation i has two names' It is still known as i' but
no* ii ls known as *p as well. This is how C talks about the two parts of a pointer
*p is the location pointed to
variable: p is the location holding the address, while
by that uddr"rr. Therefore
*p = 5 means that the location pointed to by p should
be set to 5. Because this location is also i, i also take on the value 5'
Consequently, j = i; sets j to 5, and the printf statement produces
5 5 5'

4.4.6. Declaration of Pointer -'int, float,


c programming language supports pointers to different data types
value or to multiple
double-, char, erc. fver/pointer can point to either a single
(in the
values. Whether a poiniei is to point to a single value or to multiple
values
the associated
case of a pointer to an array) is decided by its specific use -with
program. In c a pointer variable is declared by using the pointer
constructs of the
(*) operator.
*/
iyntax: int *pi; /* pi is an integer pointer/pointer to an integer
float *pf; /* pf is a float Pointer */
char *pc; /* pc is a character pointer */
Here, the pointer variables pi, pf and pc contain a pointer to the corresponding
data item. consider the declaration of int *pi; Here, pi is a pointer variablL which
is capable of holding the address of the memory location containing an integer.
When the compiler comes across this statement, it allocates a location that ian
store the address of an integer location. Hence, a pointer is an address variable
that holds the physical address of the data item.

Figure 4.4 gives a pictorial view of pointers and memory, where Address: x is
the address of an integer location x:

Address: x

o, I ooa."* I (-.

Figure 4.4: Pointers and Memory

For example, consider the following program segment where a is an integer


variable, pi is a pofurter to an integer variable and &a gives the address of itre
integer variable a:
int a = 10;
int *p;
P=&a;

After compilation, we have the values in the variabres as shown in figure 4.5:

ol "* I Pr addr

^l , I l0

Figure 4.5: Memory Status after Compilation

After execution of the first statement, i.e., p - &a; the values of the variables will
be as shown in figure 4.6.

,l " I
.l-,o-l

Figure 4.6: Memory Status after Execution of Statement


pointers allow indirect access to data. One can read a value into a variable in two
different ways.
1) Direct Access,
2) Indirect Access.
The following statements illustrate direct access and indirect access to the data:
scanf("Vod", &a); l* Direct access
*/
scartf("Vod", p); /x Assume that the statement P = &a has been executed' indirect
access */

x x v

v v v

l0 20 .l0
20 20 20

(a) (b) (c)

Figure 4.7: (a) Memory status before Assignrnent; (b) Memory Status after
Assign'ment of *p = *q from (ax (c) Memory Status after Assignment of p = q from

*p = *q
Basically the pointers have two types of assignment operations, namely
*p *q,
and p - q, uri *" depicted in figure 4.7. After assignment of = the value
poinied to by the pointer q is copied to the location pointed to by the pointer p,
and both of them have tlie value 20 as shown in figure 4.7. Similarly, after
assignment of p - q, the address stored in the pointer q is copied into the pointer
*p
p. n-ottr the pointers point to the same memory location and hence the value of
and *q is the same, i.e.,20.

4.4.7. Initialization of Pointer


Pointer variables can be initialized in their definitions, just like many other
variables in C.
For example, the following two statements allocate storage for the two cells
iresult and piresult:
I ) int iresult:
2) int *piresult = &iresult;
The variable iresult is an ordinary integer variable, and piresult is a pointer to an
integer.

Additi6nally. the code initializes the pointer variable piresult to the address of
iresult. We are not initializing *piresult (which would have to be an integer value)
but piresult (which must be an address to an integer)'

Second statement in the preceding listing can be translated into the following two
equivalent statements:
int *piresult;
piresult = &iresulq
4.4.8. IndirectionOperator
An indirection or pointer operator is represented by a combination of asterisk
(*) with a variable.

Syntax: c

int *ptr; ll ptr is a pointer variable which holds the address of an integer data
type.
float *fpointer;
double *dpoint;
char xcpointl:

Indirection/Dereferencing is an operation performed to access and manipulates


data contained in the memory location pointed to by a pointer.
Or
The process of following a pointer to the location to which it points is called
indirection or dereferencing the pointer. The opeiator * is used to dereference
pointers.

A pointer variable is dereferenced when the unary operator *, in this case called
the indirection operator, is used as a prefix to the pointer variable or pointer
expression.

Ifthe operand points to a function, the result is a function designator. If it points


to a storage location, the result is an l-value designating the storage location. If
the pointer value is invalid, the result is undefined.

The following list includes some of the most common conditions that invalidate a
pointer value.
1) The pointer is a null pointer.
2) The pointer specifies the address of a local item that is not visible at the time
of the reference.
3) The pointer specifies an address that is inappropriately aligned for the type of
the object pointed to.
4) The pointer specifies an address not used by the execuring program.
Any operation performed on the dereferenced pointer directly affects the value of
the variable it points to. For example, consider the following program

Program 7: illustrates dereferencing of pointer (derefer.c).


#include<stdio.h>
#include<conio.h>
void main0
{
int xiptr, varl, var2;
iptr = &varl lx initialize pointer iptr */
*iptr 25; /* dereference iptr, varl = 25, *l
=
xiptr += 10; /* varl = varl + 10; */
/* next statement prints varl, it should be 35 *l
clrscr0;
printf( "Variable var 1 contains : 7o7\n", var 1 ) ;
varL = *iptr, /* same as var2 = varl', *l
/* next statement prints var2, it also contains 35 */
printf ( " V ari able v arL c ontain s : Vo i\m", v at2) ;
iptr = &var2; l* iptr now points to vat2 *l
*iptr += 20; /* increase contents of var2by 20, *l
/* next statement prints var2, it now cor.taitts 55 *l
printf( "Vari able v arL now contains : 7oi\t1 ", v at2) ;

Explanation
1) The asterisk (*) used as an indirection operator has a different meaning from
the asterisk used to declare pointer variables:
int *ptr; /* This is a pointer declaration */
xptr = 100; /* The LHS does pointer indirection */
2) Indirection allows the contents of a variable to be accessed and manipulated
without using the name of the variable.
3) All variables that can be accessed directly (by their names) can also be accessed
"trecomes
indirectly by means df pointers. The power of pointers evident in
situations where indirect access is the only';/ay to access variables in memory.

4.4.9. Pointer Arithmetic


The C language allows programmer to adcl and subtract integers to and from
pointers. For example, if p is a pointer, the expression p+3 is perfectly legal,
meaning three objects after the object that p points to. Because p holds an
address, performing arithmetic on p generates a new address value. However,
rather than simply adding 3 to p, the compiler multiplies the 3 by the size of the
object that p points to. This is called scaling.
In pointer arithmetic, all pointers increase or decrease by the length of the data
typi pointed to by them. This length is known as the scale factor. The scale
factors for various data tY pes on an IBM PC and its
Data Type Lensth
char I byte
lnt 2 bvtes
float 4 bytes
long int 4 bvtes
double 8 bytes
For example, the figure 4.E illustrates the concept of pointer arithmetic:
Char *cPIi;-
float xfptr;
o
- int *iptr;

2001 2m2 2003 20/.t4 2005 200,6 2007 2008 2009 2010 2011 2012
cpt cptr+1 cptr+2 cptr+3 cptr+4 :ptr+5 :ptr+6 :pr+7 cptr+8 :ptr+9 ;ptr+10 )ptr+l I
tt r l r

iptr iptr+l iptr+2 iptr+3 iptr+4 iptr+5

fptr fptr+l fptr+2


Figurc 4.t: (Showing Pointer Arithmetic Relative to its Base Type)

An important point about the pointer variable is that it holds the address of the
very firsl byte of the memory location pointed to by it, known as the base
1 address.

For example, suppose that the address value held by p is 1000. If p is declared as
' a pointer to a 4:byte long int, the 3 in p+3 is multiplied by 4. The value of p+3,
therefore, is 1012. 2

on the other hand, if p is declared as a pointer to a char, p+3 would equal 1003.
In this way, the expression p+3 always means 3 objects after p, regardless of the
type of object that
?points to.
The following arithmetlc opcrations on pointers are not permitted:
i) Addition of nvo pointer variables.
i, Multiplication of a pointer variable by a number.
iii) Division of a pointer variable by a number.
4.4.9.1. Incrementing a Pointer
Generally progralnmers use a pointer in the program instead of an array because
the variable pointer can be incremented, unlike the array name which cannot be
incremented because it is a constant pointer. Following program increments the
variable pointer to access each succeeding element of the a:ray:

Program E: To illustrate the ilcrement of a pointer.


#include <stdio.h>
finclude<conio.h>
const int MAX = 3;
main 0
t
int var[] - {10, 100,200};
int i, *ptr;
/* let us have array address in pointer */
ptr = var;
for(i=0;i<MAX;i++)
{
printf("Address ofvar[7od] = 96x\n", i,pt );
printf("Value of varf%od] = 7rd\n", i, *ptr );

/* move to the next location */


ptr++;
)
getch0;

Putput ;
ffi c:\usersgrarinsh\DusL*tb\To{#1@ Eiffi
:,ei
"
-ryryJ

4.4.9.2. Decrementing a Pointer


The same concerns as apply in increment of a pointer is apply to decrementing a
pointer, which decreases its value by the number of bytes of its data type.as
shown below in the program:

Program 9: To illustrate the concept of decrementing a pointer.


#include <stdio.h>
#include<conio.h>
const int MAX = 3;

main 0
{
int var[] = {10, 100,200};
int i, *ptr;

/* let us have array address in pointer */


ptr = &var[MRX-l];
for(i=MAX;i>0;i--)
t
printf("Address of varl%od] = Vox\t", i, ptr );
printf("Value of varl%od] = 7od\n", i, *ptr );
ff move to the previous location */
ptr--;
)
getch0;
),
4.4.9.3. ' Pointer Comparisons
Pointers may be compared by using relational operators, such as = =, (, and >. If
p1 and p2 point to variables that are related to each other, such as elements of the
same array, then pl and p2 can be meaningfully compared. Consider the
following program which illustrates the pointer comparison.

Program 10: To illustrate the comparing the pointer.


#include<stdio.h>
#include<conio.h>

int mainQ
{
int data[100];
intx p1;
int*p2;
int i;
clrscr0;
for(i=0;i<100;i++)
{
ddta[i]= i;
)
p1 = &data[1J;
p2= &dataf?l;

if(p1>p2)
t
' printf("\n\n pl is greater than p2");
)

else
{
l. printf("\n\n p2 is greater than p1");
)
Any program or data must be loaded into memory before it can be executed or
processed. Therefore, for every program to be executed or data to be processed,
some memory must be allocated for them.

One of the important aspects of pointer is memory allocation. There are two types
memory allocation possible in C.

Memory Allocation

Static Allocation or Compile -


Time Memory Allocation Dynamic Allocation or Run -
Time Memory Allocation"

4.5.1. Static Memory Allocation


In the static allocation, the required amount of memory is allocated to the
program element (identifiers names which include variable name, function name,
program name etc.) at the start of program.

The main drawback of static allocation if there is less number of elements than
then the rest amount of memory is wasted. The concept Dynamic or run time
memory allocation help to overcome this problem.

4.5.2. Dynamic Memory Allocation


It makes efficient use of memory, by allocating the require amount of memory
whenever needed, unlike static allocation where the amount to be declared statically.

Dynamically allocated variables are simply variables that do not exist when the
program is loaded, but are created dynamically as they are needed. It is possible,
using these techniques, to create as many variables as needed, use them, and de-
allocate their space for use by other variables.

4.5.2.1. Definition
Process of allocating memory at run time is known as dynamic memory
alloihtion.
Dynamic allocation is a technique in which program can acquire storage space in
the main memory. In this method, the space for the program is allocated from the
free space during execution of the program. The free region of the memory is
called the heap.
The heap changes depend upon what memory model is being used. The amount
of memory requirement is decided by how the program is designed.
Stack

I
High
1
Free memory for
allocation

Global Variables

Low

Program

Figure 4.9: C Program's use of Memory

able 4.5: Dynamic Allocation I'unctions


malloc0 Allocates request size of bytes and ptr = (cast-type *)
returns a pointer to the first byte of the malloc(byte-size);
allocated space
calloc0 Allocates space for an iuray of ptr = (cast-type x)
elements, initializes then to zero and calloc(n, elem-size);
then returns a pointer to the memory
free0 Frees previously allocated space free (ptr);
realloc0 Modifies the size of previously ptr = realloc(ptr,
allocated space newsize);

ptr is a pointer to a memory block which has already been created by mallocQ or
callocO.

4.5.2.2. malloc0Function
ma11oc0 requires one argument - the number of bytes you want to allocate
dynamically. It returns the address of memory chunks that is allotted.

If the memory allocation was successful, malloc0 will return a void pointer - you
can assign this to a pointer variable, which will store the address of the allocated
memory.

If memory allocation failes (e.g if the system is out of memory), mallocQ will
return a NULL pointer.

Passing the pointer into f#b willrelease the allocated memory :n it is good
practice to free memory when its usage is finished.
Program 11:/*illustrating malloc function*/
#include<stdio.h>
#include<conio.h>
main0
i
int tPtr-one;
ptr-one = (int *)malloc(sizeof(int));
if (Ptr-one == 0)
t
Printf("ERROR: Out of memory\n");
return 1;
)

*ptr-one = 25;
printf(" 7od\n', *Ptr-one);

free(ptr-one);

getchO;

Explanation
the size of an
The malloc statement will ask for an amount of memory with
memory available, the malloc
i*g". (32 bits or 4 bytes). If there is not enough
block of memory is
function will return u NUI-1. If the request is granted a
block will be placed into the
allocated (reserved). The address of the reserved
pointer variable'

The statement then checks for the return value of NULL'


if If the return value
proglams stops. (If the
equats NULL, then a message will be printed and the
."io* value of the program one, than that's an indication that there was a
"quutt
problem.)

the value in the allocated


The number 25 is placed in the allocated memory. Then
;;r";ry will be printea. Before the program ends the reserved memory is
released.

4.5.2.3. calloc0Function
values stored in
calloc0 is similar to mallocO, but the main difference is that the
the allocated memory space is zeroby default'
callocO Arguments: It requires two arguments. The first is the number of
variables that the programmer would like io allocate memory for. The second is
the size of each variable.

calloc0 returns a void pointer if the memory allocation was successful,


else it,ll
return a NULL pointer. we can free memories by using
the free0 function.

Program 12: illustrating calloc$ function.


#include <stdio.h>
#include <stdlib.h>

main0
1
int i, n;
int *a;

printf("Number of elements to be entered:");


scanf("7od",&n);

a - (int*)calloc(n, sizeof(int));
prinfff 'Enter 7od numbers :\n",n) ;

for(i=0;i<n;i++)
{
scanf("Vod" ,&a[i]);
)
printf("The numbers entered are: ");

for(i=0;icn;i++)
{
pintf("Vod, ",a[i]);
)
getch0;

i=jF 4 j

".q
4.5.2.4. realloc0Funcfon
jThe reallocO function ctraniet the size of previously dynamically allocated
memory without changing the pUntents of the memory'

If the done allocation ef memory is not sufficient for the programmer's pse then
there are two ways to again dynamically extend memory'
1) First is to copy "u"iytfring into a larger array, whioh is inefficient, and
Zi Second allocate moie bytes using realloc, without losing data.
reallocO Arguments: realloc {akes two arguments. The first
is the pointer
of bytes that are to be
referencing the memory. The second is the total number
of calling free'
reallocated. Passing ,"- u, the second argument is the equivalent

once again, realloc returns a void pointer if successful, else a NULL pointer is
returned.

automatically
Free() Function: When your program comes out, operating system
good practice when
release all the memory utto"ut"O6y your proglam but as a
memory by
you are not in need of memory anymore then you should release that
calling the function free0.

Program 13: To illustrate the use of realloc function'


#include <stdio.h>
#include <stdlib.h>
main0
{
char *str;

/* Initial memory allocation */


s6 = (char x) malloc( l5);
strcpy(str, "TPPL");
-
prirrtil;'stritt E = vos,*Addr"ss = 7ouvl"' str' sE);

/* Reallocating memory'*/
str - (char x) realloc(str, 25);
strcat(str, ".com");
printf("StrinE= %os, Address - 7ou\n"' str' str);
free(str);
getcho:
)

I=:."ry'.:': .'"-"- - ' "" ' i'=-*' E*-*" jx


r
|

C;:\Users\F,ravesh\Desktop\t\<*reck5rcp'exe -
4.5.2.s. Comparison among Memory Allocation Function
Table 4.6: Comparisonof malloc0, ciltocQ and realloc$
Basis malloc0 calloc0 realloc0
No. of I 2 2
Arguments
No. of Bytes Total no. of bytes No. of elements and No. of bytes required
required size of elements for expansion
Type of Type of data unknown Type of data known Dynamic allocation
Data while working in the
code.
Deallocation Free is used explicitly Free is used explicitly realloc itselfcan be
to free the memory to free the memory used for freeing the
memory

one of the most useful applications of pointers is in functions. we know that


function can pass parameters in two ways one is pass by value and other
c
one is
pass by reference.

In the pass by value is that only direct way to send values from calling function
to called function and it returns processed value through only return statement.
And in pass by reference by passing an address from catting function to called
function and it returns changed data is called function to iie calling function
program.
This concept is also called as pass by reference (address). when we pass
by
address, we are actually passing a pointer to a variable

4.6.1. Pointer as Formal parameters


Consider the program below to specify the concept of
pass by value. Here, we call the swap function, paising
two variables whose contents are to be exchanged. In
their process, the contents are exchanged in thJcailed
function but it is not reflected in the main program i.e.,
nothing is changed in the calling function program.

Program: illustrating as formal parameters.


#include<stdio.h>
void main0
(
int a = l0;
int b - 20;
swap(a, b);
pintf (" Vo d Vo d\n", a, b) ;
)
void swap (int x, int Y)
t
int temp;
temP = 1;
x=y;
return Y = temp;
)

Instead of using pass by value to swap


two elements, we can use a pass pointers
to the value i.e., pass bi reference. once
we are making use of pointer to variable,
variable within main ( ) function
it does not make *V Oifi".""ce in terms of local
*liii gr"bal variables but we can exchange these two values'
"
Intheprogrambelowshqwstheexchangetwovaluesusingpointers.Todefinea
the calling function is shown below'
pointer we use,h" J;;;=; operator (ana) in
Now, we *" purrrng udd'""'of t*o variable
i'e'' a and b refer than their values'
swap (&a, &b);
Theusagesofpassbyaddress,i".}?.calledfunctionformalparametersare
the link and allows us to indirectly
defined as pointer to u'u*iaUt". it establishes
pointers'
i"f"."o." the variable in the calling program using

void swaP(int*, int*);


Toassignavalueofa,weneedtousedereferencethepointerinswapfunction.
Thisoperationaltowstoaccessdatainthecallingprogramusingthepassby In
address. It is very i;;;;;, to know that. c still uses only pass by a value.
(address) of the variable we require to
thissituation, the value is the reference
change.

Program 13
#include<stdio.h>
void swaP (intx, int*);

6 r;l
int main0
{
int a, b;
a= 10;
T""**T
6 =20;
swaP(&a, &b);
Pintf("Vod 7od\n", a, b);
1t
I _l_
)

*Y)
E L+r
+ After t
void swaP (int *x, int
t
int temp;
E L"l
temP = *1; ,.,"nF'l
*x = *y;
pointers
xy = temp; Program. Swap Two Variableg Using

)
swapo function is called using the*.address
operator for the variables that is
required to exchange two values. *
Note: The swap0 function uses two formar parameters
i.e., x and y along with temp local
variable. using the dereferencing the parame^ters,
we perform the swap using the variables
in main and locar variable temp-in swap. rhe complete
working program is shown in the
program above.

4.6.2. FunctionsReturningpointers
A pointer is also a data type in c, we ul.o force a function to return a pointer
t-o the calling function consider the"iprogram
below contains a function to
determine the larger of two numbers. H-ere,
we need a pointer to the rarge of two
variables a and b. Since, *"
1t" using two pointers to a function, which uses a
condition expressiori to determine wniln value is larger.
Once after knowing the larger value,
we can return address of its location
as pointer. The return address is then
assigned in the calling function
pointer p, so that after ;aling the
function it points to either a or b
based on their values. The
corresponding C program and its xy
equivalent diagram of the variable and
Figure 4.10: Function Returning pointers
pointer are shown in figure 4.10.

Program: illustrating functions refurning pointer.


#include<stdio.h>
int *larger (int *x, int *y);
void mainQ
{
int a,b;
int *p;
printf("enter the value of a nad b/n,,);
scanf(" Vod Vo d,,, &a, &b) ;
p = larger(&a, &b);
, printf("largest - Vod\n,,p);
)
int *larger(int *x, int *y)
{
return (xx>*y? *r r *y),
-
)
Note: The address must be the address or the variable
in the calling function. It is an error
to return a pointer to a local variable in the called
function, u""ir* *t"n the function
terminates, its memorv may be used by other
parts of the program. Arthough such
a
simple program*uy ,Lt noiice such typ" *t
,pu*'*ui i"ur"o, but a rarge
programs may get wrong answer or fail "ooiu""rur"
when the memorybeing referenced by the pointer
was changed.
Program 14: To caluclate square of a value using function'
#include<stdio.h>
#include<conio.h>

// function prototype, also called function declaration


float sqpare ( float x );
main( )
{
float m, n ;
printf ( "\nEnter some number for finding square \n");
scanf ( "Vof', &m) ;
// function call
n=square(m);
printf ( "\nSquare of tire given number Vof is Vof",m,n);
getch0;
)

// function definition
float square ( float x )
t
float p ;
P=x*x;
return(P);
)-
g"tp,rt t'*
tSJ
: es
*f,1 C:Ukers\pravesh\Seskto'p\I*\WU'exe

Example 15: Program to add | + 2 +.'.+ 100 using a pointer to a function


method.
#include<stdio.h>
#includecconio.h>
main0
t
int n, a, sum(int n);
int(*ptr)(int n);
printf("Enter the value of n\n");
scanf("Vod", &n);
ptr = &sum;
a = (*ptr)(n);
printf("Sum = VodV',, a):
getchQ;
)

int sum(int n)
t
int i, j;
j=0;
for(i=1; i<=n; i++)
{
j+=i;
)
returnO;
)

Program 16: Prime Nurirbers Between two Intervars


by Making User-defined
Function.
#include<stdio.h>
#include<conio.h>

int check_prime(int num);


mainQ{
intnl,n2,i,fla5:
printf("Enter two numbers(intervals):',);
sc anf(" Vo d Vo d", &rtl, &n2)
;
printf("Prime numbers between Vod and Vod are: ,, nI,
, n2);
for(i=n1+1;icn2;++i)
{
flag-check prime(i);
if(flag==O)
printf("7od ",i);
)
getch0;
]
int check_prime(int num)
{
int j,flag=O;
for(=114-num/2;++j){
if(numToj==Q){
flag-l;
break;
)
)
return flag;
)
Output:
,S -1 C:\User:\Fra:*esh\Desktop\ToWTUerc

Program 17: To reverse a sentence using recursion.


#include <stdio.h>
#include<conio.h>
void Reverse0;
main0
{
printf("Enter a sentence: ");
ReverseO;
getch0;
)
void ReverseQ
{
char c;
scanf("%oc" ,&c);
if( c !='\n')
{
ReverseO;
pintf("Voc",c);
)
1) What do you understand by pointers? Give the syntax of declaration of a poinrer.
2) Find the output of the following program:
main0
{
int x=5, *p;
P=&x;
pintf("Vod", ++xP);
)
3) What will be the output of following block?
main1.1
t
int arr[5]=[3, 4,6,2, l];
int *p-arr; $

int *q=41.'2'
int *r=&arr[l];
pintf ('\n%o dVo d%o d", arrl2), * (arr+2); * r) ;
pintf('\nVod%o d%o d", * p, * (q+ I ), * (r+ I )) ;
return 0;
)
4) How do you use a pointer to a function?
5) Discuss the various arithmetic operations performed on a pointer.
6) Explain the use of (*) indirection operator?
7) Explain the effect of ++ and
- operator with pointer of all data types?
8) Why addition of two pointers is impossible?
9) Explain the relation between an iuray and a pointer?
10) Distinguish between the address stored in the pointer and the value at that address?
ll) What is the base address? How is it accessed differentially for one-dimensional and two-
dimensional arrays?
12) Explain the comparison of two pointers?
13) Explain the feature ofpointers?
14) How strings are stored using pointer variables? Is it essential to deciare length?
15) Write a program to sort l0 strings with the help of pointers.

Potrebbero piacerti anche