Unit 4

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

UNIT – IV

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;

Eg:- int *ad; /* pointer to int */


char *s; /* pointer to char */
float *fp; /* pointer to float */
char **s; /* pointer to variable that is a pointer to char */

A pointer is a variable that contains an address which is a location of another variable in


memory.

Consider the Statement


p=&i;

Here ‘&’ is called address of a variable.


‘p’ contains the address of a variable i.

The operator & returns the memory address of variable on which it is operated, this is
called Referencing.

The * operator is called an indirection operator or dereferencing operator which is used to


display the contents of the Pointer Variable.

Consider the following Statements :

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

POINTER FUNCTION ARGUMENTS

Function arguments in C are strictly pass-by-value. However, we can simulate pass-by-


reference by passing a pointer. This is very useful when you need to Support in/out(bi-
directional) parameters (e.g. swap, find replace) Return multiple outputs (one return value isn't
enough) Pass around large objects (arrays and structures).
/* Example of swapping a function can't change parameters */
void bad_swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
/* Example of swapping - a function can't change parameters, but if a parameter is a pointer it
can change the value it points to */

void good_swap(int *px, int *py)


{
int temp;
temp = *px;
*px = *py;
*py = temp;
}

#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);
}

POINTERS AND ARRAYS :

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.

Consider the array

2000 2002 2004 2006 2008

a[0] a[1] a[2] a[3] a[4]

The name of the array is called its base address.

i.e., a and k& a[20] are equal.

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

Reading and Printing an array using Pointers :

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));
}

In one dimensional array, a[i] element is referred by


(a+i) is the address of ith element.
* (a+i) is the value at the ith element.

In two-dimensional array, a[i][j] element is represented as


*(*(a+i)+j)

POINTERS AND FUNCTIONS :


Parameter passing mechanism in ‘C’ is of two types.

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.

Example of Call by Value:


#include <stdio.h>
void swap(int,int);
main()
{
int a,b;
printf(“Enter the Values of a and b:”);
scanf(“%d%d”,&a,&b);
printf(“Before Swapping \n”);
printf(“a = %d \t b = %d”, a,b);
swap(a,b);
printf(“After Swapping \n”);
printf(“a = %d \t b = %d”, a,b);
}

void swap(int a, int b)


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

Example of Call by Reference:

#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

Ex : int *pa; char *s;


s-1 →points to char before s (1 subtracted)
pa+1→ points to next int (4 added!)
s+9 →points to 9th char after s (9 added)
++pa→ increments pa to point to next int

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

397870 234560 287650

pointer to pointer to integer pointer to integer integer variable

//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 :

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).

BLOCK MEMORY ALLOCATION(MALLOC) :

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.

CONTIGIOUS MEMORY ALLOCATION(calloc) :


Calloc is primarily used to allocate memory for arrys.It differs from malloc only in that it
sets memory to null characters. The calloc function declaration:
Void *calloc(size_t element_count, size_t element_size);

The result is the same for both malloc and calloc.

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.

Void *realloc(void*ptr,size_t newsize);

Ptr
Before

18 55 33 121 64 1 90 31 5 77
10 Integers

Ptr=realloc(ptr,15*sizeof(int)); New elements


not initialized

ptr
18 55 33 121 64 1 90 31 5 77 ? ? ? ? ?

15 Integers
After

RELEASING MEMORY(FREE):When memory locations allocated by malloc,calloc or


realloc are no longer needed, they should be freed using the predefined function free. It is an
error to free memory with a null pointer, a pointer to other than the first element of an allocated
block, a pointer that is a different type then the pointer that allocated the memory, it is also a
potential error to refer to memory after it has been released.

Void free(void *ptr);

ptr ptr

Before After
Free(ptr);

In above example it releases a single element to allocated with a malloc,back to heap.

BEFORE AFTER

… …

Ptr 200 integers ptr 200 integers

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.

CHARACTER ARRAYS (STRINGS) :


A String is an array of characters. Any group of characters (except double quote sign
)defined between double quotes is a constant string.
Ex: “C is a great programming language”.

If we want to include double quotes.

Ex: “\”C is great \” is norm of programmers “.


Declaring and initializing strings :-
A string variable is any valid C variable name and is always declared as an array.
char string name [size];

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.

String can be initialized when declared as


1. char city[g]= “NEW YORK’;
2. char city[g]= {‘N’,’E’,’W’,’ ‘,’Y’,’O’,’R’,’K’,’/0’};
C also permits us to initializing a String without specifying size.
Ex:- char Strings[ ]= {‘G’,’O’,’O’,’D’,’\0’};

READING STRINGS FROM USER:

%s format with scanf can be used for reading String.

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.

Reading a line of 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).

Formatted string Input/Output:

Formatted String Input:scanf/fscanf:

Declarations:

int fscanf(FILE *stream, const char *format, ...);


int scanf(const char *format, ...);
The ..scanf functions provide a means to input formatted information from a stream
fscanf reads formatted input from a stream
scanf reads formatted input from stdin

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:

char *gets(char *str);

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:

char *fgets(char *str, int n, FILE *stream);

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:

int puts(const char *str);

Writes a string to stdout up to but not including the null character. A newline character is
appended to the output.

On success a nonnegative value is returned. On error EOF is returned.

fputs():
Declaration:

int fputs(const char *str, FILE *stream);


Writes a string to the specified stream up to but not including the null character.

On success a nonnegative value is returned. On error EOF is returned.

STRING HANDLING FUNCTIONS:

strcat( ) Concatenates two Strings


strcmp( ) Compares two Strings
strcpy( ) Copies one String Over another
strlen( ) Finds length of String

strcat() :

This function yours two strings together.


strcat(string1,string2);
string1 = VERY

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 :

It works almost as a string assignment operators. It takes the form


strcpy(string1,string2);
string2 can be array or a constant.
strlen() function :

Counts and returns the number of characters in a string.


n= strlen(string);
n integer variable which receives the value of length of string.

/* 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);
}

You might also like