Beruflich Dokumente
Kultur Dokumente
4.1.1. Introduction
> Every C program consists of one or mors functions. On^ of these functions 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.
> Generally, a function will process information that is passed to it from the s. idling
portion of the program, and return a single value.
> Information is passed to the function via special identifiers called arguments (also
called parameters), and returned via the return statement.
> Some functions, however, accept information but do not return anything (of type
void), whereas other functions return multiple values, with help of pointers and
arguments (e.g., library function scanf).
fopen(sl, s2) FILE* Opens a file named si of s2 type. Returns a pointer stdio.h
to a file.
fprintf(f,...) int ’ Sends data items to file f. stdio.h
fputc(c, f) int Sends a single character to file f. stdio.h
fputs(s, f) int Sends string s to file f. stdio.h
fread(s, il, i2, f) int Inputs i2 data items each of size il bytes, from file stdio.h
f to string s.
free(p) void Frees a block of allocated memory whose starting Malloc.h or
address is indicated by p. stdlib.h
fscanf(f,...) int Inputs data items from file f. stdio.h
fseek(f, 1, i) int Moves the pointer for file f at distance 1 bytes stdio.h
from location i (i may represent pointer position or
end-of-file).
pow(dl, d2) double Returns dl raised to the power d2. math.h
printf(...) int Sends data items to the standard output device. stdio.h
scanf(....) int Allows input of data items from the standard ouput stdio.h
device.
strcmp(sl, s2) int Compares two strings. Returns a -ve value if si < string .h
s2,0 if si = s2, +ve if si > s2.
strcpy(sl, s2) char* Copies string s2 to string si. string.h
strlen(s) int Returns the number of characters in string s. string.h
toascii(c) int Converts value of argument to ASCII. ctype.h
tolower(c) int Converts value of argument to lower-case. ctype.h or
stdlib.h
toupper(c) int Converts letter 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.
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.
1) Return_Type: If the function has no arguments, then write void in the parentheses,
else 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 mandatory (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 arguments. 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 at least compatibility.
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, and it has three arguments, all of type
int. The names of argument are not significant.
1) Above All Functions (Global Prototype): It also includes main(). 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.
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. Function Arguments
Basically there are two types of function arguments in c:
For example,
main()
{
int x, y;
------------
-----------
}
4.I.7.2. Formal Arguments
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,
main()
{
int x, y;
-------
-------
output(x, y);
}
output(a,b) */ formal or dummy arguments */
int a, b;
{
/* body of the 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.
char s1, s2
---------
--------
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) If the type of the argument is float it is converted to double.
■ C:\Usefs\pravesh\Desktop... a
23
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.I.9.I. 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.
Explanation: In the above program we are passing values of the actual argument ‘x’
and ‘y’ to the function change(). The formal argument ‘a’ and ‘b’ of function change()
receives these values(). 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 main(), the changes
made in function change() vanishes. In the main() 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.
Explanation: Here addresses of formal arguments are passed to the function change().
The pointers in the change() receive these addresses() function, i.e., pointer points to
the actual argument. Here the change() function operates on the actual argument
through the pointer. Hence, the changes made in the values are permanent. 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 that Formal parameter is an alias for the actual
exists within the scope of the procedure/ parameter.
function/subprogram.
Value of actual parameter is used to initialize Formal parameter refers to the same memory
the formal parameter. cell for the actual parameter.
Changes made to formal parameter DO NOT Each formal parameter is a reference to the
get transmitted back to the caller. actual parameter and modifying the formal
will modify the actual.
C and Java restrict themselves to Call by Value. C++ and Pascal let you declare that a
parameter is a reference.
--------
---------
---------
---------
}
power(x, y)
int x, y;
{
/* 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 return statement */
#include<stdio.h>
#include<conio.h>
main()
{
int i, max;
printf("Enter a value for n ?\n");
scanf("%d", &max);
“ printff'number square \n")
- printf'(“ ____________________ \n");
for(i=0; i<=max-l; ++i)
square(i);
}
square(n)
int n;
{
int temp; temp n*n;
printf("%d\t\t%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 communicated between calling the portion and a
function block.
For example,
main()
{
int x, y, temp;
char ch;
---------
---------
One can design similar functions and use in the programs. For example,
int get_number(void);
main
}
int m = get_number();
printf("%d", m);
}
int get_number(void)
{
int number;
scanf("%d", &number);
retum(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);
**
main()
{
int x = 20, y = 10, s, d;
mathoperation(x, y, &s, &d);
printf("s=%d\n d=%d\n", s, d);
}
void mathoperation(int a, int b, int *sum, int *diff)
{
*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. (The 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 *sum and *diff are known as ‘pointers’ and sum and diff as ‘pointer
variables’. Since they are declared as int, they can point to locations of int type data.
4.2
SCOPE OF VARIABLES
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.
Global 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.
1) Auto Storage Class: The auto storage class is the default storage class for all local
variables.
{
/*auto variable declaration*/
int mount;
auto int month;
}
The example above defines two variables with the same storage class, 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 register 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*/
4) extern 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: /*lllustrating extern storage class.*/
#include<stdio.h>
#include<conio.h>
int a;
main()
{
extern int b;
printf("%d %d",a,b);
getch();
}
int b=10;
Output
C;\Users\pravesh„J EL! ® J
I
e 10
;4m H
►.1
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 becomes 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 = 10
n! = 3628800
When a recursive program 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)! = (n - 2) x (n - 3)!
……………………..
2! = 2x 1!
The actual values will then be returned in the following reverse order:
1! = 1 .
2!=2x1!=2x1=2
3!=3x2!=3x2=6
4!=4x3!=4x6=24
……………….
n! = n x (n - 1)! = •••
This reversal in the order of execution is a characteristic of all functions that are
executed recursively.
If a 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 same, as declared within the function. However, the variables will represent a
different set of values each time the function is executed. Each set of values 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.4. 'POINTERS
4.4.1. Introduction
> Pointers are widely used in programming; they are used to refer to memory
location of another variable without using variable identifier itself. They are
mainly used in linked lists and call by reference functions.
> With pointer we can perform lot many operations by using memory addresses. It is
possible to access and display the memory location of a variable using ‘&’
operator.
> A pointer variable holdfe the memory address of any type of variable. The pointer
variable and normal variable should be of the same type. The pointer is denoted by
symbol. „
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
0 1 2 3 4 5 6 7 8
9 A
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 value 2.
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 rvalue)
derived from the type of the operand. For example, if 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 type* 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 of its operand.
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
figure4.3
Value of v
Address of 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 assumed 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() '
{
inti, j;
int *p;/* a pointer to an integer */
p = &i;
*p = 5;
j = i;
printf(“%d %d %d\n”, i, j, *p);
}
Explanation: The line int *p declares a pointer. It asks the compiler to declare a variable p that is a
pointer to an integer. The * indicates that a pointer is being declared rather than a normal variable.
Programmer can create a pointer to anything: a float, a structure, a char, and so on.
The line p = &i;. expression &i means “the memory address of the variable i”. 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 random, unknown address, and its use will likely cause a
segmentation fault.
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 represented by a square to
indicate that it is a normal variable.
Once p points to i, the memory location i has two names. It is still known as 1, but now it is known as
*p as well. This is how C talks about the two parts of a pointer variable: p is the location holding the
address, while *p is the location pointed to by that address. 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.
Figure 4.4 gives a pictorial view of pointers and memory, where Address: x is the
address of an integer location x:
pi Address: x
For example, Consider the following program segment where a is an integer variable,
pi is a pointer to an integer variable and &a gives the address of the integer variable
a:
int a = 10;
int *p;
p=&a;
After compilation, we have the values in the variables as shown in figure 4.5:
pi addr
10
p X P X P y
q y q y q y
X 10 X 20 X 10
>
y 20 y 20 y 20
Basically the pointers have two types of assignment operations, namely *p = *q and
p = q, and are depicted in figure 4.7. After assignment of *p = *q, the value pointed
to by the pointer q is copied to the location pointed to by the pointer p, and both of
them have the 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. Both the pointers point
to the same memory location and hence the value of *p and *q is the same, i.e., 20.
Second statement in the preceding listing can be translated into the following two
equivalent statements:
int *piresult;
piresult = &iresult;
4.4.8.Indirection Operator
An indirection or pointer operator is represented by a combination of asterisk (*)
with a variable.
Syntax: *
int *ptr; // ptr is a pointer variable which holds the address of an integer data
type.
float *fpointer;
double *dpoint;
char *cpointl;
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.
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 executing program.
Any operation performed on the dereferenced pointer directly affects the value of the
variable it points to. For example, consider the following program
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 */
*ptr = 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
indirectly by means of pointers. The power of pointers becomes evident in situations
where indirect access is the only way to access variables in memory.
For example, the figure 4.8 illustrates the concept of pointer arithmetic:
char *cptr;
float *fptr;
int *iptr;
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
cpt cptr+1 cptr+2 cptr+3 cptr+4 cptr+5 cptr+6 cptr+7 cptr+8 cptr+9 cptr+10 cptr+11
An important point about the pointer variable is that it holds the address of the very first
byte of the memory location pointed to by it, known as the base 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. '
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.
int i, *ptr;
main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
int main()
{
int data[100];
int* pi;
int *p2;
int i; ,
clrscr();
for(i=0;i<100;i++)
{
data[i]= i;
}
p1 = &data[l];
p2 = &data[2];
if(pl>p2)
{
printf(”\n\n pi is greater than p2");
}
else
{
printf("\n\n p2 is greater than pi");
}
Output
4.5.2.I. Definition
Process of allocating memory at run time is known as dynamic memory allocation.
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
Global Variables
Low
Program
Figure 4.9: C Program’s use of Memory Table 4.5: Dynamic Memory Allocation Functions
malloc()---- Allocates request size of bytes and returns a pointer to the first byte of the
calloc()---- Allocates space for an array of elements, initializes then to zero and then returns a
realloc()---- Modifies the size of previously allocated space-- ptr = realloc(ptr, newsize);
ptr is a pointer to a memory block which has already been created by malloc() or
calloc().
If the memory allocation was successful, malloc() 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), malloc() will return a
NULL pointer.
Passing the pointer into free will release the allocated memory - it is good practice to
free memory when its usage is finished.
Program ll:/*illustrating malloc function*/
#include<stdio.h>
#include<conio.h>
main()
{
int *ptr_one;
ptr_one = (int *)malloc(sizeof(int));
if (ptr_one == 0)
printf("%d\n", *ptr_one);
free(ptr_one);
getch();
}
Output _________
i * C:\Users\praves.,
23
Explanation .
The malloc statement will ask for an amount of memory with the size of an integer
(32 bits or 4 bytes). If there is not enough memory available, the malloc function will
return a NULL. If the request is granted a block of memory is allocated (reserved).
The address of the reserved block will be placed into the pointer variable.
The if statement then checks for the return value of NULL. If the return value equals
NULL, then a message will be printed and the programs stops. (If the return value of
the program equals one, than that’s an indication that there was a
problem.)
The number 25 is placed in the allocated memory. Then the value in the allocated
memory will be printed. Before the program ends the reserved memory is
released.
calloc() returns a void pointer if the memory allocation was successful, else it’ll
return a NULL pointer. We can free memories by using the free() function.
}
1
printf("The numbers entered are: ");
Output
Free() Function: When your program comes out, operating system automatically
release all the memory allocated by your program but as a good practice when you
are not in need of memory anymore then you should release that memory by calling
the function free().
Program 13: To illustrate the use of realloc function.
#include <stdio.h>
#include <stdlib.h>
main()
{
char *str;
/* Initial memory allocation */
str = (char *) malloc(15);
strcpy(str, "TPPL"); ^
printf("String = %s, ’Address = %u\n", str, str); .
/* Reallocating memory */
str = (char *) realloc(str, 25);
strcat(str, ".com");
printf("String = %s, Address = %u\n", str, str);
free(str);
getch();
}.
Output
a C:\Users\pravesh\Desktop\t\cheek5sep.exe
4.5.2.5. Comparison among Memory Allocation Function Table 4.6:
Comparison of malloc(), caIloc() and realloc()
Basis--- malloc()----calloc()----reaIIoc()
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 calling function to called function and
it returns changed data is called function to the 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.
Program 13
#include<stdio.h>
void swap (int*, int*);
int main()
{
int a, b;
a = 10;
b = 20;
swap(&a, &b);
printf(“%d %d\n”, a, b);
}
void swap (int *x, int *y)
{
int temp;
temp = *x; temp 10
*x = *y; xy Program. Swap Two Variables Using pointers
= temp;
swap() function is called using the. address operator for the variables that is required
to exchange two values.
Note: The swap() function uses two formal parameters i.e., x and y along with temp local variable.
Using the dereferencing the parameters, we perform the swap using the variables in main and lowcal
variable temp in swap. The complete working program is shown in the program above.
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
calling the function it points to either a or b based on their values. The corresponding
C program and its equivalent diagram of the variable and pointer are shown in figure
4.10.