Unit 4
Unit 4
Unit 4
POINTERS :
One of the powerful features of C is ability to access the memory variables by their
memory address. This can be done by using Pointers. The real power of C lies in the proper use
of Pointers.
A pointer is a variable that can store an address of a variable (i.e., 112300).We say that a
pointer points to a variable that is stored at that address. A pointer itself usually occupies 4 bytes
of memory (then it can address cells from 0 to 232-1).
Advantages of Pointers :
1. A pointer enables us to access a variable that is defined out side the function.
2. Pointers are more efficient in handling the data tables.
3. Pointers reduce the length and complexity of a program.
4. They increase the execution speed.
Definition :
A variable that holds a physical memory address is called a pointer variable or Pointer.
Declaration :
Datatype * Variable-name;
The operator & returns the memory address of variable on which it is operated, this is
called Referencing.
int *p,x;
x =5;
p= &x;
Assume that x is stored at the memory address 2000. Then the output for the following
printf statements is :
Output
Printf(“The Value of x is %d”,x); 5
Printf(“The Address of x is %u”,&x); 2000
Printf(“The Address of x is %u”,p); 2000
Printf(“The Value of x is %d”,*p); 5
Printf(“The Value of x is %d”,*(&x)); 5
#include <stdio.h>
void bad_swap(int x, int y);
void good_swap(int *p1, int *p2);
main() {
int a = 1, b = 999;
printf("a = %d, b = %d\n", a, b);
bad_swap(a, b);
printf("a = %d, b = %d\n", a, b);
good_swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
}
When an array is declared, elements of array are stored in contiguous locations. The
address of the first element of an array is called its base address.
Now both a and a[0] points to location 2000. If we declare p as an integer pointer, then we can
make the pointer P to point to the array a by following assignment
P = a;
We can access every value of array a by moving P from one element to another.
i.e., P points to 0th element
P+1 points to 1st element
P+2 points to 2nd element
P+3 points to 3rd element
P +4 points to 4th element
main()
{
int *a,i;
printf(“Enter five elements:”);
for (i=0;i<5;i++)
scanf(“%d”,a+i);
printf(“The array elements are:”);
for (i=o;i<5;i++)
printf(“%d”, *(a+i));
}
1.Call by Value
2.Call by Reference.
The process of passing the actual value of variables is known as Call by Value.The
process of calling a function using pointers to pass the addresses of variables is known as Call by
Reference. The function which is called by reference can change the value of the variable used
in the call.
#include<stdio.h>
main()
{
int a,b;
a = 10;
b = 20;
swap (&a, &b);
printf(“After Swapping \n”);
printf(“a = %d \t b = %d”, a,b);
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
ADDRESS ARITHIMETIC :
Incrementing/Decrementing a pointer variable ,adding and subtracting an integer from
pointer variable are all legal and known as pointer arithmetic. Pointers are valid operands in
arithmetic expressions ,assignment expressions ,and comparison expressions. However not all
the operators normally used in these expressions are valid in conjunction with pointer variable.
A limited set of arithmetic operations may be performed on pointers. A pointer may be
incremented(+ +) or decremented(--) ,an integer may be added to a pointer
(+ or +=),an integer may be subtracted from a pointer(- or -=),or one pointer may be subtracted
from another.
We can add and subtract integers to/from pointers – the result is a pointer to another element
of this type
VOID POINTER :
In C ,an additional type void *(void pointer) is defined as a proper type for generic
pointer. Any pointer to an object may be converted to type void * without loss of information. If
the result is converted back to the original type ,the original pointer is recovered .
Ex:
main()
{
void *a;
int n=2,*m;
double d=2.3,*c;
a=&n;
m=a;
printf(“\n%d %d %d”,a,*m,m);
a=&d;
c=a;
printf(“\n%d %3.1f %d”,a,*c,c);
}
In the above program a is declared as a pointer to void which is used to carry the address of an
int(a=&n)and to carry the address of a double(a=&d) and the original pointers are recovered
with out any loss of information.
POINTERS TO POINTERS :
So far ,all pointers have been pointing directely to data.It is possible and with advanced
data structures often necessary to use pointers to that point to other pointers.
For example,we can have a pointer pointing to a pointer to an integer.This two level indirection
is seen as below:
//Local declarations
int a;
int* p;
int **q;
q p a
Ex: 234560 287650 58
//statements
a=58;
p=&a;
q=&p;
printf(“%3d”,a);
printf(“%3d”,*p);
printf(“%3d”,**q);
There is no limit as to how many level of indirection we can use but practically we
seldom use morethan two.Each level of pointer indirection requires a separate indirection
operator when it is dereferenced .
In the above figure to refer to ‘a’ using the pointer ‘p’, we have to dereference it as
shown below.
*p
To refer to the variable ‘a’ using the pointer ‘q’ ,we have to dereference it twice toget to
the integer ‘a’ because there are two levels of indirection(pointers) involved.If we dereference it
only once we are referring ‘p’ which is a pointer to an integer .Another way to say this is that ‘q’
is a pointer to a pointer to an integer.The doule dereference is shown below:
**q
In above example all the three references in the printf statement refer to the variable ‘a’.
The first printf statement prints the value of the variable ‘a’ directly,second uses the pointer
‘p’,third uses the pointer ‘q’.The result is the value 58 printed 3 times as below
58 58 58
Dynamic memory allocation uses predefined functions to allocate and release memory
for data while the program is running. It effectively postpones the data definition ,but not the
declaration to run time.
To use dynamic memory allocation ,we use either standard data types or derived types
.To access data in dynamic memory we need pointers.
MEMORY ALLOCATION FUNCTIONS:
Four memory management functions are used with dynamic memory. Three of
them,malloc,calloc,and realloc,are used for memory allocation. The fourth ,free is used to return
memory when it is no longer needed. All the memory management functions are found in
standard library file(stdlib.h).
The malloc function allocates a block of memory that contains the number of bytes
specified in its parameter. It returns a void pointer to the first byte of the allocated memory. The
allocated memory is not initialized.
Declaration:
void *malloc (size_t size);
The type size_t is defined in several header files including Stdio.h. The type is usually an
unsigned integer and by the standard it is guaranteed to be large enough to hold the maximum
address of the computer. To provide portability the size specification in malloc’s actual
parameter is generally computed using the sizeof operator. For example if we want to allocate
an integer in the heap we will write like this:
Pint=malloc(sizeof(int));
Malloc returns the address of the first byte in the memory space allocated. If it is not
successful malloc returns null pointer. An attempt to allocate memory from heap when memory
is insufficient is known as overflow.
The malloc function has one or more potential error if we call malloc with a zero size, the
results are unpredictable. It may return a null pointer or it may return someother implementation
dependant value.
Ex:
If(!(Pint=malloc(sizeof(int))))
// no memory available
exit(100);
//memory available
…
In this example we are allocating one integer object. If the memory is allocated successfully,ptr
contains a value. If does not there is no memory and we exit the program with error code 100.
calloc returns the address of the first byte in the memory space allocated. If it is not successful
calloc returns null pointer.
Example:
If(!(ptr=(int*)calloc(200,sizeof(int))))
//no memory available
exit(100);
//memory available
…
In this example we allocate memory for an array of 200 integers.
REALLOCATION OF MEMORY(realloc):
The realloc function can be highly inefficient and therefore should be used advisedly.
When given a pointer to a previously allocated block of memory realloc changes the size of the
block by deleting or extending the memory at the end of the block. If the memory can not be
extended because of other allocations realloc allocates completely new block,copies the existing
memory allocation to the new location,and deletes the old allocation.
Ptr
Before
18 55 33 121 64 1 90 31 5 77
10 Integers
ptr
18 55 33 121 64 1 90 31 5 77 ? ? ? ? ?
15 Integers
After
ptr ptr
Before After
Free(ptr);
BEFORE AFTER
… …
Free(ptr);
In the above example the 200 elements were allocated with calloc. When we free the
pointer in this case, all 200 elements are return to heap. First, it is not the pointers that are being
released but rather what they point to. Second , To release an array of memory that was allocated
by calloc , we need only release the pointer once. It is an error to attempt to release each element
individually.
Releasing memory does not change the value in a pointer. Still contains the address in the
heap. It is a logic error to use the pointer after memory has been released.
Note: Memory space should be freed whenever it is not required. The operating system will
release all memory when your program terminates.
size determines number of characters in the string name. When the compiler assigns a character
string to a character array, it automatically supplies a null character (‘\0’) at end of String.
Therefore, size should be equal to maximum number of character in String plus one.
char address[15];
scanf(“%s”,address);
The problem with scanf function is that it terminates its input on first white space it finds. So
scanf works fine as long as there are no spaces in between the text.
If we are required to read a line of text we use getchar(). which reads a single characters.
Repeatedly to read successive single characters from input and place in character array.
/* Program to read String using scanf & getchar */
#include<stdio.h>
main()
{
char line[80],ano_line[80],character;
int c;
c=0;
printf(“Enter String using scanf to read \n”);
scanf(“%s”, line);
printf(“Using getchar enter new line\n”);
do
{
character = getchar();
ano_line[c] = character;
c++;
} while(character !=’\n’);
c=c-1;
ano_line[c]=’\0’;
}
STRING INPUT/OUTPUT FUNCTIONS:
C provides two basic ways to read and write strings.First we can read and write strings with the
formatted input/output functions,scanf/fscanf and prinf/fprinf.Second we can use a special set of
strin only functions ,get string(gets/fgets)and put string(puts/fputs).
Declarations:
These functions take input in a manner that is specified by the format argument and store each
input field into the following arguments in a left to right fashion.
Each input field is specified in the format string with a conversion specifier which specifies how
the input is to be stored in the appropriate variable. Other characters in the format string specify
characters that must be matched from the input, but are not stored in any of the following
arguments. If the input does not match then the function stops scanning and returns. A
whitespace character may match with any whitespace character (space, tab, carriage return, new
line, vertical tab, or formfeed) or the next incompatible character.
String Input/Output
In addition to the Formatted string functions,C has two sets of string functions that read and
write strings without reformatting any data.These functions convert text file lines to strings and
strings to text file lines.
Line to String:
gets():
Declaration:
Reads a line from stdin and stores it into the string pointed to by str. It stops when either the
newline character is read or when the end-of-file is reached, whichever comes first. The newline
character is not copied to the string. A null character is appended to the end of the string.
On success a pointer to the string is returned. On error a null pointer is returned. If the end-of-file
occurs before any characters have been read, the string remains unchanged.
fgets():
Declaration:
Reads a line from the specified stream and stores it into the string pointed to by str. It stops when
either (n-1) characters are read, the newline character is read, or the end-of-file is reached,
whichever comes first. The newline character is copied to the string. A null character is
appended to the end of the string.
On success a pointer to the string is returned. On error a null pointer is returned. If the end-of-file
occurs before any characters have been read, the string remains unchanged.
String to Line:
puts:
Declaration:
Writes a string to stdout up to but not including the null character. A newline character is
appended to the output.
fputs():
Declaration:
strcat() :
string2 = FOOLISH
strcat(string1,string2);
string1=VERY FOOLISH
string2 = FOOLISH
strcmp() function :
This function compares two strings identified by arguments and has a value 0 if they are
equal. If they are not, it has the numeric difference between the first non-matching characters in
the Strings.
strcmp(string1,string2);
Ex:- strcmp(name1,name2);
strcmp(name1,”John”);
strcmp(“ROM”,”Ram”);
strcpy() function :
/* Illustration of string-handling */
#include<stdio.h>
#include<string.h>
main()
{
char s1[20],s2[20],s3[20];
int X,L1,L2,L3;
printf(“Enter two string constants\n”);
scanf(“%s %s”,s1,s2);
X=strcmp(s1,s2);
if (X!=0)
{
printf(“Strings are not equal\n”);
strcat(s1,s2);
}
else
printf(“Strings are equal \n”);
strcpy(s3,s1);
L1=strlen(s1);
L2=strlen(s2);
L3=strlen(s3);
printf(“s1=%s\t length=%d chars \n”,s1,L1);
printf(“s2=%s\t length=%d chars \n”,s2,L2);
printf(“s3=%s\t length=%d chars \n”,s3,L3);
}