A pointer is a variable that holds address (memory
location) of another variable rather than actual value. Also, a pointer is a
variable that points to or references a memory location in which data is
stored. Each memory cell in the computer has an address that can be used to
access that location. So, a pointer
variable points to a memory location and we can access and change the contents
of this memory location via the pointer. Pointers are used frequently in C, as
they have a number of useful applications. In particular, pointers provide a
way to return multiple data items from a function via function arguments.
Pointer Declaration
Pointer variables, like all other
variables, must be declared before they may be used in a C program. We use
asterisk (*) to do so. Its general form is:
data-type
*ptrvar;
For example,
int* ptr;
This statement declares the
variable ptr as a pointer to int, that is, ptr can hold address of an integer
variable.
Once we declare a pointer variable we can point by it to something. We
can do this by assigning to the pointer the address of the variable you want to
point as in the following example:
int var=11,*ptr;
ptr=&var;
This places the address where var is stores into the variable ptr. For example, if var is stored in memory 21260 address
then the variable ptr has the value
21260.
We can access
the contents of the variable pointed by pointer using an asterisk (*) in front
of a variable name. For example,
int var=11,*ptr;
ptr=&var;
*ptr=45; //It changes the value of var to 45
Example:
#include<stdio.h>
#include<conio.h>
void main() {
int var=11,*ptr;
clrscr();
printf("%d\n",var); //prints 11
printf("%d\n",&var); //prints address of var
printf("%d\n",*&var); //prints
11
ptr=&var;
printf("%d\n",ptr); //prints address of var
printf("%d\n",*ptr); //prints 11
*ptr=45;
printf("%d\n",var); //prints 45
printf("%d\n",*ptr);
//prints 45
getch();
}
The operator ‘&’ is called “address
of” operator. The expression &var
returns the address of the variable var.
The operator ‘*’ called “value at address” operator. It gives
the value stored at a particular address. The “value at address” operator is also called “indirection operator”.
Passing (call) by Value and
Passing (call) by Reference
Arguments can generally be passed
to functions in one of the two ways:
- Sending the values of the arguments (pass by value)
- Sending the addresses of the arguments (pass by
reference)
Pass by value: In this
method, the value of each of the actual arguments in the calling function is
copied into corresponding formal arguments of the called function. With this
method the changes made to the formal arguments in the called function have no
effect on the values of actual arguments in the calling function. The following
program illustrates ‘call by value’.
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int, int );
clrscr();
a = 10;
b = 20;
swap(a,b);
printf("a = %d\tb
= %d",a,b);
getch();
}
void swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
printf("x = %d\ty
= %d\n",x,y);
}
The output of the above program
would be
x = 20 y = 10
a = 10 b = 20
Note that values of a and b
remain unchanged even after exchanging the values of x and y.
Pass by reference: In this
method, the addresses of actual arguments in the calling function are copied
into formal arguments of the called function. This means that using these
addresses we would have an access to the actual arguments and hence we would be
able to manipulate them. The following program illustrates this fact.
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int*, int*);
clrscr();
a = 10;
b = 20;
swap(&a,&b);
printf("a = %d\tb
= %d",a,b);
getch();
}
void swap(int *x, int *y)
{
int t;
t = *x;
*x = *y;
*y = t;
printf("x = %d\ty
= %d\n",*x,*y);
}
The output of the above program
would be
x = 20 y = 10
a = 20 b = 10
Note: We can use call by reference to return multiple values from
the function.
Pointers and Arrays
An array name by itself is an
address, or pointer. A pointer variable can take different addresses as values.
In contrast, an array name is an address, or pointer, that is fixed.
Pointers and
One-dimensional Arrays
In case of one dimensional array, an array name is really
a pointer to the first element in the array. Therefore, if x is a
one-dimensional array, then the address of the first array element can be
expressed as either &x[0] or simply x. Moreover, the address of the second
array element can be expressed as either &x[1] or as (x+1), and so on. In
general, the address of array element (x+i) can be expressed as either
&x[i] or as (x+i). Thus we have two different ways to write the address of
any array element: we can write the actual array element, preceded by an
ampersand; or we can write an expression in which the subscript is added to the
array name.
Since,
&x[i] and (x+i) both represent the address of the ith element of x, it
would seem reasonable that x[i] and *(x+i) both represent the contents of that
address, i.e., the value of the ith element of x. The two terms are
interchangeable. Hence, either term can be used in any particular situation.
The choice depends upon your individual preferences. For example,
/* Program to
read n numbers in an array and display their sum and average */
#include<stdio.h>
#include<conio.h>
#define SIZE 100
void main()
{
float
a[SIZE],sum=0,avg;
int n,i;
clrscr();
printf("How many numbers?");
scanf("%d",&n);
printf("Enter numbers:\n");
for(i=0;i<n;i++)
{
scanf("%f",(a+i)); //
scanf("%f",&a[i]);
sum=sum+*(a+i); //sum=sum+a[i];
}
avg=sum/n;
printf("Sum=%f\n",sum);
printf("Average=%f",avg);
getch();
}
Pointers and
Multidimensional Arrays
Since one-dimensional array can
be represented in terms of a pointer, a multidimensional array can also be
represented with an equivalent pointer notation. A two-dimensional array, for
example, is actually a collection of one-dimensional arrays. Therefore, we can
define a two-dimensional array as a pointer to a group of contiguous one-dimensional
arrays.
Suppose x is a
two-dimensional integer array having 10 rows and 20 columns. We can declare x
as
int (*x)[20];
rather than
int x[10][20];
In the first
declaration, x is defined to be a pointer to a group of contiguous,
one-dimensional, 20-element integer arrays. Thus, x points to the first
20-element array, which is actually the first row (i.e., row 0) of the original
two-dimensional array. Similarly, (x+1) points to the second 20 element array,
which is the second row (row 1) of the original two-dimensional array, and so
on. Now, we can access the element in row 2 (third row) and column 5 (sixth
column) by writing either x[2][5] or *(*(x+2)+5). In general, we can access the
element in row i and column j by writing x[i][j] or *(*(x+i)+j). For example,
#include<stdio.h>
#include<conio.h>
#define ROW 3
#define COL 2
void main()
{
int a[ROW][COL],b[ROW][COL],i,j,sum;
clrscr();
printf("Enter
elements of first matrix:\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
scanf("%d",(*(a+i)+j));
printf("\n");
}
printf("Enter
elements of second matrix:\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
scanf("%d",(*(b+i)+j));
printf("\n");
}
printf("Addition
matrix is:\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
{
sum=*(*(a+i)+j)+*(*(b+i)+j);
printf("%d\t",sum);
}
printf("\n");
}
getch();
}
Dynamic Memory Allocation
Dynamic memory allocation is the
process of allocating memory in a program dynamically at run time. C provides
two basic functions calloc() and malloc() for this purpose. The name
calloc stands for “contiguous allocation” and the name malloc stands for
“memory allocation”.
The programmer
uses calloc() and malloc() to dynamically create space arrays, structures, and
unions.
The function
calloc() takes two arguments both of unsigned integral type. When we call this
function, it allocates contiguous space in memory. For example,
/* Program to
read n floating point numbers and display their sum and average using pointer
and dynamic memory allocation*/
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
float *a,sum=0,avg;
int n,i;
clrscr();
printf("How many numbers?");
scanf("%d",&n);
a=(float*)calloc(n,sizeof(float));
printf("Enter numbers:\n");
for(i=0;i<n;i++)
{
scanf("%f",(a+i));
//scanf("%f",&a[i]);
sum=sum+*(a+i); //sum=sum+a[i];
}
avg=sum/n;
printf("Sum=%f\n",sum);
printf("Average=%f",avg);
free(a);
getch();
}
In the above program a points to the first memory block in
the allocated memory.
The programmer
uses malloc() in a similar fashion. This function takes a single argument of
unsigned integral type. For example,
a=(float*)mallocc(n*sizeof(float));
When we use
calloc(), the space is initialized with all bits set to zero. Unlike, calloc(),
the function malloc() does not initialize the space in memory that it makes
available. In a large program, malloc() may take less time.
Space that has
been dynamically allocated with either calloc() or malloc() does not destroyed
automatically. The programmer must use free() explicitely to destroy it. For
example,
free(a);
Operations on Pointers (Pointer Arithmetic)
Not all operations are applied
for pointers. Permissible operations that can be applied for pointers are given
below:
- A pointer variable can be
assigned the address of an ordinary variable. For example, pv = &v, where pv is a pointer variable and v is an ordinary variable.
- A pointer variable can be
assigned the value of another pointer variable provided both pointers
point to objects of the same data type. For example, pv = px, where both pv
and px are pointer variables of
the same data type.
- A pointer variable can be
assigned a null (zero) value. For example, pv = NULL, where NULL
is a symbolic constant that represent the value zero and pv is a pointer variable.
- An integer quantity can be
added to or subtracted from a pointer variable. For example, pv+3, ++pv etc. where pv is a pointer variable.
- One pointer variable can be
subtracted from another provided both pointers point to elements of the
same array.
- Tow pointer variables can be
compared provided both pointers point to objects of the same data type.
Other arithmetic operations on
pointers are not allowed. Thus, a pointer variable cannot be multiplied by
constant; two pointer variables cannot be added; and so on.
Pointer Constant and Pointer
to Constant
Pointer constant or constant
pointer means the pointer is constant. For example, int *const ptr2 indicates that ptr2
is a pointer which is constant. This means that ptr2 cannot be made to point to another integer after it points to
some integer. However the integer pointed by ptr2 can be changed. For example,
int a=2,b=3;
int *const ptr2 = &a;
ptr2=&b; //error
It is not a pointer to constant. A pointer to constant is written like
const int *ptr1. It indicates that ptr1 is a pointer that points to a constant integer. The integer is constant and cannot be changed. However, the pointer ptr1 can be made to point to some other integer constant. For example,
const int *ptr1. It indicates that ptr1 is a pointer that points to a constant integer. The integer is constant and cannot be changed. However, the pointer ptr1 can be made to point to some other integer constant. For example,
const int a=2;
const int *ptr2 = &a;
*ptr2=8; //error
3:45 PM
0 Responses to "Pointers"
Post a Comment