C Unit 5
C Unit 5
POINTER Introduction
A pointer is a derived data type in C. It is buit fromone of the fundamental data types available in C.
Pointers contain memory addresses as their values.Since these memory address are the locations
in the computer memory where program instructions and data are stored, pointers can be used to
access and manipulate data stored in the memory.
Pointers are undoudtedly one of the most distinct and exiciting features of c language. It has
added power and flexibility to the language. Although they appear little confusing and difficult to
understand for a beginner, they are powerful tool and handy to use once they are mastered.
Pointers are used frequently in C, as they offer a number of benefits to the programmer. They
include:
1.Pointers are more efficient inhandling arrays and data tables.
2.Pointers can be used to return multiple values from a functions via function argument.
3.pointer permit references to functions and there by facilitating passing of function as arguments
to other functions.
4.The use of pointer arrays to character strings results in saving of data storage space in memory.
5.Pointers allows C to support dynamic memory management.
6.Pointer provides an efficient tools for manipulating the dynamic data structures such as
structure,linked list, queues, stack and trees.
7. Pointers reduced the length and complexity of programs.
8.They increase the execution speed and thus reduce the program execution time.
Understanding Pointers
The computer memory is a sequential collection of storage cells, each cell commonly
known as byte, has a number called address associated with it.Typically the addresses are
numbered consecutively, starting from 0. The last address depends on the memory size.The
computer system having 64K memory will have its last address as 65535.
This statement instructs the system to find a location for the integer variable quantity and
puts the value 179 in that location. Assume that the system has chosen the address location 5000
for quantity. We may represent this as shown below.
During execution of the program, the system always associates the name quantity with
the address 5000. To access the value 179 we use either the name quantity or the address 5000.
Since memory addresses are simply numbers, they can be assigned to some variables which can
be stored in memory, like any other variable. Such variables that hold memory addresses are
called pointers. A pointer is, therefore, nothing but a variable that contains an address
which is a location of another variable in memory.
Since a pointer is a variable, its value is also stored in the memory in another
location.Suppose, we assign the address of quantity to a variable p. The link between the
variables p and quantity can be visualized as shown below. The address of p is 5048.
Fig 2.3 pointer variable
Since the value of the variable p is the address of the variable quantity, we may access
the value of quantity by using the value of p and therefore, we say that the variable p ‘points’ to
the variable quantity. Thus, p gets the name ‘pointer’.
If x is an array ,then expressions such as &x[0] and &x[i + 3] are valid and represent the
addresses of 0th and (i + 3)th elements of x.
The program shown below declares and initializes four variables and then prints out these values
with their respective storage locations.
Program
/*******************************************************************/
/* ACCESSING ADDRESSES OF VARIABLES */
/*******************************************************************/
main() { char a; int x; float p, q; a = ’A’; x = 125; p = 10.25 , q = 18.76; printf(“%c
is stored as addr %u . \n”, a, &a); printf(“%d is stored as addr %u . \n”,x , &x);
printf(“%f is stored as addr %u . \n”, p, &p); printf(“%f is stored as addr %u . \n”, q,
&q); }
OUTPUT:
Example:
1. int *p;
2. float *x;
Once a pointer variable has been declared, it can be made to point to a variable using an
assignment operator such as
p= &quantity;
Before a pointer is initialized it should not be used. Ensure that the pointer variables always point
to the corresponding type of data.
Example:
float a, b;
int x, *p;
p = &a;
b = *p;
will result in erroneous output because we are trying to assign the address of a float
variable to an integer pointer. When we declare a pointer to be of int type, the system assumes
that any address that a pointer will hold will point to an integer variable.
int *ptr;
….
?
Ptr ?
Example:
int q;
int *p; /*declaration */ P=&q;
/*initialization */
int *p=&q;
is allowed. The only requirement here is that the variable q must be declared before the
initialization takes place. Remember, this is an initialization of p and not *p.
we must ensure that pointer variable always points to the corresponding type of data. For
Example,
will result in erroneous output because we are trying to assign the address of a float variable to an
integer pointer. When we declare a pointer to be of int type, the system assumes that any address
that the pointer will hold will point to an integer variable. Since the complier will not detect such
errors, care should be taken to avoid wrong pointer assignments.
It is also possible to combine the declaration of data variable, the declaration of pointer variable
and the initialization of the pointer variable in one step. For example,
int x, *p=&x; /*three in one */ is perfectly valid.It declare x as an integer variable and p as a
pointer variable and then intializes p to the address of x. and also remember that the target
variable x is declared first. The statement
int *p = &x, x;is not valid .We could also define null or o to the pointer variable and other
constants value can not be assigned to a pointer variable. For example, int *p=null; /*valid*/ int
*p=0; /*valid*/ int *p=5360; /*invalid*/
To access the value of the variable using the pointer, another unary operator *(asterisk),
usually known as the indirection operator is used. Consider the following statements:
The statement n=*p contains the indirection operator *. When the operator * is placed
before a pointer variable in an expression (on the right-hand side of the equal sign), the pointer
returns the value of the variable of which the pointer value is the address. In this case, *p returns
the value of the variable quantity, because p is the address of the quantity. The * can be
remembered as ‘value at address’. Thus the value of n would be 179. The two statements
p= &quantity;
n= *p; are
equivalent to n=
*&quantity;
which in turn is equivalent to n=
quantity;
The following program illustrates the distinction between pointer value and the value it
points to and the use of indirection operator(*) to access the value pointed to by a pointer.
main( )
{ int x,
y;
int * ptr; x =10; ptr = &x; y = *ptr; printf
(“Value of x is %d \n\n”,x); printf (“%d is
stored at addr %u \n” , x, &x); printf (“%d is
stored at addr %u \n” , *&x, &x); printf (“%d is
stored at addr %u \n” , *ptr, ptr); printf (“%d is
stored at addr %u \n” , y, &*ptr); printf (“%d is
stored at addr %u \n” , ptr, &ptr); printf (“%d is
stored at addr %u \n” , y, &y);
*ptr= 25;
printf(“\n Now x = %d \n”,x);
} pointed to by the pointer ptr to
y.
*ptr=25;
This statement puts the value of 25 at a memory location whose address is the value of
ptr. We know that the value of ptr is the address of x and therefore the old value of x is replaced
by 25. This, in effect, is equivalent to assigning 25 to x. This shows how we can change the value
of a variable indirectly using a pointer and the indirection operator.
Chain of Pointers
p2 p1 variable
address 2 address 1
value
Here the pointer variablep2 contains the address of the pointer variable p1,which points to the
locations that contains the desired value. This is known as multiple indirections.
A variable that is a pointer to a pointer must be declared using additional indirection operator
symbols in front of the name. Example : int **p2;
This declaration tells the complier that p2 is a pointer to a pointer of int type. Remember, the
pointer p2 is not a pointer to an integer, but rather a pointer to an integer pointer.we can access
the targetvalue indirectly pointed to a pointer by applying the indirection operator twice.Consider
the following code:
Main() {
int x,*p1,**p2;
x=100; p1=&x;
p2=&p1;
printf(“%d”, **p2); }
This code will display the value 100.Here p1 is declared as a pointer to an integer and p2 as
apointer toa pointer to an integer.
Pointer Expressions
Like other variables, pointer variables can be used in expressions. For example, if p1 and
p2 are properly declared and initialized pointers , then the following statements are valid. 1) y =
*p1* *p2; same as (* p1) * (* p2)
2) sum = sum + *p1;
1 2 3 4 5
Value
The name x is defined as a constant pointer pointing to the first element[0] ans therefore
value of x is 1000, the location where x[0] is stored. That is,
X=&x[0]=100
Accessing array elements using the pointer
Pointers can be used to manipulate two-dimensional array as well. An element in a two-
dimensional array can be represented by the pointer expression as follows:
*(*(a+i)+j) or *(*(p+i)+j)
The base address of the array a is &a[0][0] and starting at this address, the compiler
allocates contiguous space for all the elements, row-wise. That is, the first element of the second
row is placed immediately after the last element of the first row, and so on.
A program using Pointers to compute the sum of all elements stored in an array is
presented below:
Pointers in one-dimensonal array
main ( ) {
int *p, sum , i
static int x[5] = {5,9,6,3,7}; i = 0; p = x; sum = 0;
printf(“Element Value Address \n\n”); while(i < 5)
{ printf(“ x[%d} %d %u\n”, i, *p, p); sum = sum +
*p; i++, p++; }
printf(“\n Sum = %d \n”, sum); printf(“\n &x[0] = %u \n”, &x[0]); printf(“\n p = %u \n”, p); }
Output
Element Value Address
X[0] 5 166
X[1] 9 168
X[2] 6 170
X[3] 3 172
X[4] 7 174
Sum = 55
&x[0] = 166 p=
176
Pointers and character strings
We know that a string is an array of characters, terminated with a null character. Like in
one-dimensional arrays, we can use a pointer to access the individual characters in a string. This
is illustrated in the program given below. /* Pointers and character Strings */
main() { char *
name; int length;
char * cptr = name;
name = “DELHI”;
while ( *cptr != ‘\0’)
{ printf( “%c is stored at address %u \n”,
*cptr,cptr); cptr++; }
length = cptr-name;
printf(“\n length = %d \n”, length);
} Output:
DELHI
D is stored at address 54
E is stored at address 55
L is stored at address 56
H is stored at address 57
I is stored at address 58
Length=5
Array of Pointers
One important use of pointers in handling of a table of strings. Consider the following
array of strings: char name[3][25];
This says that name is a table containing three names, each with a maximum length of 25
characters ( including null character ).Total storage requirements for the name table are 75
bytes.Instead of making each row a fixed number of characters , we can make it a pointer to a
string of varying length. For example
static char *name[3] = { “New zealand”,
“Australia”,
“India” };
declares name to be an array of three pointers to characters, each pointer pointing to a particular
name as shown below: name[0] à New Zealand name[1] à Australia
name[2] à India
Pointers to functions
A function, like a variable has an address location in the memory. It is therefore, possible
to declare a pointer to a function, which can then be used as an argument in another function. A
pointer to a function is declared as follows: type (*fptr)( );
This tells the compiler that fptr is a pointer to a function which returns type value. A
program to illustrate a function pointer as a function argument.
Program
#include <math.h>
#define PI 3.141592 main ( )
{ double y( ), cos( ), table( ); printf(“Tableof y(x) = 2*x*x- x+1\n\n”); table(y, 0.0 , 2.0,
0.5); printf(“\n Table of cos(x) \n\n”); table(cos, 0.0, PI , 0.5);
}
double table(f, min, max, step) double (*f) ( ), min, max , step;
{
double a, value;
for( a = min; a < = max; a + = step)
{
value = (*f)(a); printf(“%5.2f
%10.4f\n”, a, value);
}}
double y(x) double x;
{
return (2*x*x-x+1);
}
File management in C
Introduction
Many real- life problems involve large volumes of data and in such situations, the console
oriented I/O operations pose two major problems.
1. It becomes cumbersome and time consuming to handle large volumes of data through
terminals.
2. The entire data is lost when either the program is terminated or the computer is turned-
off.
It is therefore necessary to have a more flexible approach where data can be stored on the
disk and read whenever necessary, without destroying the data. This method employs the
concept of files to store data. A file is aplace on the disk where a group of related data is
strored.Like most other language, C supports a number of functions that have the ability to
perform basic file operations,which include:
• Naming a file,
• Opening a file,
• Reading data from a file, Writing data from a file and
• Closing a file.
There are two distinct ways to perform file operations in C. The first one is known as the
low-level I/O and uses UNIX system calls. The second method is referred to as the high-level
I/O operation and uses functions in C’s standard I/O library.
we shall discuss in this chapter, the important file handling functions that are available in the
c library. They are listed Below
If we want to store data in a file in the secondary memory, we must specify certain things
about the operating system.They include:
1.File name
2.Data Structure,
3.Purpose.
File name is a string of characters that make up a valid file name for the operating system.
It may contain two parts, a primary name and optional name with the extension.Example
input.data,pro.c
Data structure of a file is defined as FILE in the library of standard I/O function
definitions. Therefore all files should be declared as type FILE before they are used. FILE
is a defined data type.
The following is the general format for declaring and opening a file:
FILE *fp;
fp = fopen(“filename”, “mode”);
The first statement declares the variable fp as a pointer to the data type FILE. FILE is a
structure that is defined in the I/O library. The second statement opens the file named filename
and assigns an identifier to the FILE type pointer fp.This pointer, which contains all the
information about the file is subsequently used as a communication link between the system and
the program.
The second statement also specifies the purpose of opening this file. Mode can be one of the
following:
r+ the existing file is opened to the beginning for both reading and writing.
w+ same as w except both for reading and writing.
Closing a file
A file must be closed as soon as all operations on it have been completed. This ensures
that all outstanding information associated with the file is flushed out from the buffers and all
links to the file are broken. It also prevents any accidental misuse of the file. The syntax for
closing a file is
Fclose(file_pointer);
This would close the file associated with the FILE pointer file_pointer .
Example:
…..
…..
fclose(p1);
fclose(p2);
…..
This program opens two files and closes them after all operations on them are completed.
Once a file is closed, its file pointer can be reused for another file. All files are closed
automatically whenever a program terminates.
The file i/o functions getc and putc are similar to getchar and putchar functions and
handle one character at a time. The statement
putc(c, fp1);
writes the character contained in the character variable c to the file associated with FILE pointer
fp1. Similarly, getc is used to read a character from a file that has been opened in the read mode.
For example, the statement c = getc(fp2);
would read a character from the file whose file pointer is fp2.
A program to illustrate to read data from the keyboard, write it to a file called INPUT,
again read the same data from the INPUT file, and then display it on the screen is given below:
Program
/*********************************************************************/ /*
WRITING TO AND READING FROM A FILE */
/*********************************************************************/
#include <stdio.h>
main ( )
{
FILE *fp1;
char c;
printf(“Data input\n\n”);
f1 = fopen(“INPUT” , “w” ) /* Open the file INPUT */
while((c = getchar( ))!=EOF) /* Get a character from keyboard */
putc(c,f1) /* Write a character to INPUT */
fclose(f1); /* Close the file INPUT */
printf(“\n Data OUTPUT\n\n”);
f1 = fopen(“INPUT” , “r”) /* Reopen the file INPUT */
while ((c =getc( f1))!=EOF) /* Read a character from INPUT */
printf(“%c”, c); /* Display a character on the screen */
fclose(f1); /* close the file INPUT */
}
putw functions
Output
Data input
A program to read a series of integer numbers from the file DATA and then write all odd
numbers into the file ODD and even numbers into file EVEN is given below:
Program
#include <stdio.h>
main ( )
{
FILE *f1, *f2, *f3;
int number, i;
scanf(“%d”, &number);
if(number == -1)break;
putw(number,f1);
}
fclose(f`1);
f1 = fopen(“DATA” , “r”);
f2 = fopen(“ODD” , “w”);
f3 = fopen(“EVEN”, “w”);
{
if(number %2 = = 0)
else
putw(number,f2); /*Write to ODD file*/
}
fclose(f1);
fclose(f2); fclose(f3); f2 =
fopen(“ODD” , “r”);
The functions fprintf and fscanf perform I/O operations that are identical to the printf and
scanf functions except of course that they work on files. The general form of fprintf is
Write a program to open a file named INVENTORY and store in it the following data:
Item nameNumber Price Quantity
Extend the program to read this data from the file INVENTORY and display the inventory
table with the value of each item.
/*Program */
ERROR HANDLING
The feof function can be used to test for an end of file condition. It takes a FILE pointer as
its only argument and returns non zero integer value if all of the data from the specified file has
been read, and returns zero otherwise. If fp is a pointer to file that has just been opened for
reading , then the statement
if(feof(fp))
printf(“End of data.\n”);
would display the message “End of data.” on reaching the end of file condition. The ferror
function reports the status of the file indicated. It also takes a FILE pointer as its argument and
returns a nonzero integer if an error has been detected up to that point, during processing. It
returns zero otherwise. The statement
if(ferror(fp) !=0)
would print the error message, if the reading is not successful. If the file cannot be opened for
some reason then the function returns a null pointer. This facility can be used to test whether a file
has been opened or not.
Example:
There are occasions, where we need accessing only a particular part of a file and not in
reading the other parts. This can be achieved by using the functions fseek, ftell, and rewind
available in the I/O library.
ftell takes a file pointer and returns a number of type long, that corresponds to thecurrent
position and useful in saving the current position of a file, which can be used later in the program.
It takes the following form:
n = ftell(fp);
rewind takes a file pointer takes a file pointer and resets the position to the start of the file.
Example :
rewind(fp); n = ftell(fp);
would assign 0 to n because the file position has been set to the start of the file by rewind. fseek
function is used to move the file position to a desired location within the file.
The syntax is
Value Meaning
0 Beginning of file.
1 Current position.
2 End of file.
The offset may be positive, meaning move forwards, or negative , move backwards.
StatementMeaning
When the operation is successful, fseek returns 0 or if the operation fails it returns –1.
It is a parameter supplied to a program when a program is invoked. The main can take two
arguments called argc and argv. The variable argc is an argument counter that counts the number
of arguments on the command line. The argv is an argument vector and represents an array of
character pointers that point to the command line arguments. The size of this array will be equal to
the value of the argc. In order to access the command line arguments, we must declare the main
function and its parameters as follows.
char *argv[];
{
……
……
}
A program that will receive a file name and a line of text as command line arguments and
write the text to the file is presented below:
Program
#include<stdio.h>
main(argc,argv) /* main with argument*/
{
FILE *fp;
int i;
char word[15];
fp = fopen(argv[1], “w”); /* Open file with name argv[1]*/
for(i=2;i<argc;i++) fprintf(fp,”%s”,argv[i]); /*
Write to file arv[1]*/
fclose(fp);
printf(“Contents of %s file\n\n”,argv[1]); fp
= fopen(argv[1], “r”); for(i=2:i<argc;i++)
{
fscanf(fp,”%s”,word);
printf(“%s”,word);}
fclose(fp);
printf(“\n\n”); }
SAMPLE PROGRAMS:
Output
Enter elements: 1
2
3
5
4
You entered: 1
2
3
5
4
UNIT-V - QUESTIONS SECTION A
SECTION –B
1. What is pointer? Explain with example.
2. Explain the features of pointers.
3. Explain pointer of any data type that requires four bytes.
4. What is an array of pointer ? How it is declared.
5. Explain the use of (*) indirection operator.
6. What is the difference between end of file and end of string?
7. Distinguish between text mode and binary mode operation of a file.
8. What is the use of fseek() ? Explain its syntax.
9. How does an append mode differs from a write mode.
10. Explain low level disk operation.
SECTION C
1. Explain the relation between an array and a pointer with example.
2. What are the possible arithmetic operations with pointers?
3. Explain the comparison of two pointers.
4. What is a base address? How is it assessed differentially for one dimension and two
dimension.
5. Explain in detail about the chain of pointers with example.
6. Write a brief note on pointers as function arguments with suitable example.
7. Explain in detail about the command line arguments and environment variable.
8. How re-direction of input and output is done? Explain in brief.
9. Write a program to open a file in append mode and add a new records in it.
10. Distinguish between the following function Scanf() and fscanf().
Getc() and getchar().
Putc() and fputc().
Putw() and getw().
Ferror() and perror().