A pointer
is a variable that represents the location of a data item, such as a variable
or an array element. Pointers have a number of useful applications. For
example, pointer can be used to pass information back and forth between a
function and a reference point. In particular, other provides a way to return
multiple data items from a function via arguments. Pointer also permits
references to other functions to be specified as arguments to a given function.
This has the effect of passing function as arguments to the given functions.
Pointers are also closely associated with arrays and therefore provide an
alternative way to access individual array elements.
AND & OPERATORS
Suppose v
is a variable that represents some particular data item. The address location can
be determined by the expression &v. where & is a unary operator called
the address operator. That evaluates the address of its operand.
Now let
us assign the address of v to another variable pv. Thus pv = &v;
This new
variable is called pointer to v. since it “points to” the location where v is
stored in address, not its value. Thus pv is referred to as a pointer variable.
The relationship between pv and v is illustrated in the following figure.
|
|
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 indication operator, that
operates only on a pointer variable. Therefore, *pv and v both represent the
same data item. (i.e. contents of same memory cell). 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
declared to have the same data type).
The unary
operators & and * are members of the same precedence group as the other
unary operators. This group of operators has a higher precedence than the
groups containing the arithmetic operators. The associativity of the unary
operators is right to left.
The
address operator(&) must act upon operand associated with unique addresses.
Such as ordinary variables or single array elements. Thus the address operator
cannot act upon arithmetic expressions such as 2*(u+v).
The
indirection operator(*) can only act upon operands that are pointers. However,
if pv points to v (i.e. pv=&v) then an expression such as *pv can be used
interchangeably with its corresponding variable v. thus an indirect reference
can also appear on the left side and assignment statement. This provides another
method for assigning a value to an array element of an ordinary variable (e.g.
v) within a more complicated expression.
Pointer
variables can point to numeric or character variables, arrays, functions or
other pointer variables. Thus a pointer variable can be assigned the address of
an ordinary variable (i.e. pv=&v). also a pointer can be assigned the value
of another pointer variable (i.e. pv=px) provided both pointer variables point
to data items of the same type. More over, a pointer variable can be assigned a
null (zero ) value.
POINTER DECLARATIONS :
Pointer
variables, like all other variables, must be declared before, they may be used
in C program. When a pointer variable is declared, the variable name must be
preceded by an asterisk(*). This identifies the fact that the variable is a
pointer. The data type that appears in the declaration refers to the object of
the pointer. i.e. the data item that is stored in the address represented by
the pointer, rather than the pointer itself.
Thus a
pointer declaration may be written in general terms as :
Data_type
*ptvar;
Where
ptvar is the name of the pointer variable and data type refers to the data type
of the pointer object. Remember that an asterisk must precede ptvar.
For
example,
Float
u,v;
Float
*pv;
---
pv
= &v;
The first
line declares u and v to be floating point variables. The second line declares
pv to be a pointer whose object is a floating-point quantity. i.e. pv points to
a floating point quantity. note that pv represents an address not a
floating-point quantity. An asterisk should not be included in the assignment
statement.
Within a
variable declaration, a pointer variable can be initialized by assigning in the
address of another variable, remember that the variable whose address is assigned
to the pointer variable must have been declared earlier in the program, for
example,
Float
u,v;
Float
*pv=&v;
PASSING POINTER TO A FUNCTION :
Pointers
are often passed to a function as arguments. This allows data items within the
calling portion of the program to be accessed by the function altered within
the function and then returned to the calling portion of the program in altered
form. We refer to this use of pointer as passing of arguments by reference (or
by address or by location).
When an
argument is passed by value, the data item is copied to the function. Thus any
alteration made to the data item within the function is not carried over into
the calling routine. When an argument is passed by reference, however (i.e.
when a pointer is passed to a function) the address of a data item is passed to
the function. The contents of that address can be accessed freely, either
within the function or within the calling routine. More over change that is
made to the data item(i.e. to the contents of the address) will be recognized
in both the function and the calling routine, thus the use of pointer as a
function argument permits the corresponding data item to be altered globally
from within the function. When pointers are used as argument to a function the
formal arguments that are pointers must each be preceded by an asterisk. Also,
if a function declaration is included in the coding portion of the program. The
data type of each argument that corresponds to a pointer must be followed by an
asterisk. Both these points are illustrated in the following example :
here,
fun2 receives two pointer to integer variables as its arguments. The arguments
are identified as pointers by the indirection operators (i.e. the asterisk)
that appear in the argument declaration, in addition declaration indicates that
the pointers represents the integer quantities.
Within
fun2, the contents of the pointer address are reassigned the values 0.0; since,
the address are recognized in both fun2 and main, the reassigned values will be
recognized within main after the call to fun2, therefore, the integer variables
u and v will have accessed indirectly, by referencing the pu and pv. This is
necessary because the variable u and v are not recognized such as within fun2.
The items
in parentheses identify the arguments as pointers to integer quantities. The
pointer variable, pu and pv have not been declared elsewhere in main.In the
declaration of the formal argument within the first line of fun2, that is void
func2(int *pv, int *pv) .The formal arguments pu and pv are consistent with the
dummy arguments in the function prototype. In this example the corresponding
variable names are the same though this is generally not required.
An array
name is actually a pointer to the array. i.e. the array name represents the
address of the first element in the array. therefore, an array name is treated
as pointer when it is passed to a function. However, it is not necessary to
precede the array names with an ampersand within the function call. An array
name that appears as a formal argument within a function definition can be
declared either as a pointer or as an array of unspecified size.
It is
possible to pass a portion of an array, rather than an entire array, to a
function. To do so, the address of the first array element to be passed must be
specified with the argument. The remainder of the array, starting with
specified array element, will then be passed to the function.
A
function can also return a pointer to the calling portion of the program. The
do so, the function definition and any corresponding function declaration must
indicate that the function will return a pointer. this is accomplished by
preceding the function name with an asterisk. The asterisk must appear in both
the function definition and the function declaration.
POINTER AND ONE DIMENTSIONAL ARRAY
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 written as either &x[1] or as (x+1). And so on. In general the address of I+1 th array element is expressed as (x+I). Since x[1] and (x+1) both represent the address of 1 element of x. it would seem reasonable that x[1] and *(x+1) both represent the contents of that address. i.e. the value of the 1st element of x for example.
executing
this program results the following
output :
I=0 x[I]=10 *(x+I)=10 &x[I]=72 x+I=72
I=1 x[I]=11 *(x+I)=11 &x[I]=74 x+I=74
I=2 x[I]=12 *(x+I)=12 &x[I]=76 x+I=76
I=3 x[I]=13 *(x+I)=13 &x[I]=78 x+I=78
I=4 x[I]=14 *(x+I)=14 &x[I]=7A x+I=7A
We can
see that the value of the ith array element can be represented either x[I] or
x[I+1] and the address of the ith element can be represented by either
&x[I] or x+i. When assigning a value an array element such as x[I], the
left side of the assignment statement may be written as either x[I] or as
*(x+I). Thus a value may be assigned directly to an array element or it may be
assigned to the memory area whose address is arbitrary address to an array name
or to an array element. Thus expression such as (x+1) and &x[I] cannot
appear on the left side of an assignment a\statement. For example. these four
statement are all equivalent.
Line[2] = line[1];
Line[2] = *(line+1);
*(Line+2) = line[1];
*(Line+2) = *(line+1);
The
address pf an array element cannot be assigned to some other array element. We
cannot write a statement such as.
&line[2] = &line[1];
we can
assign the value of one array element to another through a pointer. if we wish,
for example,
pl
= &line[I]
line[2]=*pi
pl
= line+l;
*(line+2)
= *pl;
numeric
array element cannot be assigned initial values if the array is defined as a
pointer variable. Therefore a conventional array definition is required if initial
values will be assigned to the element of a numerical array. however, a
character type pointer variable can be assigned an entire string as a part of
the variable declaration. Thus a string can conveniently be represented by
either a non-dimensional array or a character pointer.
OPERATIONS ON POINTERS
In
particular an integer value can be added to or subtracted from a pointer
variable though the resulting expression must be interpreted very carefully.
Suppose for example that, px is the pointer variable representing the address
of the same variable x, we can write expressions such as ++px, --px, (px+3),
(px-1), where I is an integer variable. Such expression will represent an
address located some distance of the integer quantity and the number of bytes
or words associated with the data item to which px points. Suppose for example,
that px points to an integer quantity, and each integer quantity requires 2
bytes of memory. Then the expression (px+3) will result in an address 6 bytes
beyond the integer to which px points as illustrated following ;
Px->
2 bytes v (px+3)
One
pointer variable can be subtracted from another provided both pointer point to
element of the same array. the resulting value indicates the number of words or
bytes separating the corresponding array elements.
Pointer variable can be compared provided both variable
point to object of the same data type. Such comparisons can test for either
quality or inequality.
Moreover,
a pointer variable can be computed with 0.
The
permissible operations on pointers are summarized below :
1.
a pointer variable can be assigned the address of an
ordinary variable (e.g. pv=&v)
2.
a pointer variable can be assigned the value of another
pointer variable (e.g. pv=px) provided both pointers points to the object of
the same data type.
3.
a pointer variable can be assigned a null(zero) value
(e.g. pv=null)
4.
an integer quantity can be added to or subtracted from
a pointer variable (e.g. pv+3, ++pv, pv-1)
5.
one pointer variable can be subtracted from another
provided both pointer points to the element of the same array.
6.
the pointer variables can be compared provided both
pointers point to the object of the same type.
Other
arithmetic operations on pointers are not allowed. Thus a pointer variable
cannot be multiplied by a constant. Two pointer variables cannot be added and
so on.
POINTERS AND MULTIDIMENSIONAL ARRAYS :
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. A two-dimensional array declaration can be written
Data-type
(*ptvar) expression 2;
This
concept can be generalized to higher
dimensional arrays that is
Data-type
(*ptvar) [expression 2][expression 3] … [expression n];
In these
declarations data type refers to the data type of the array. ptvar is the name
of the pointer variable. Array is the corresponding array name an expression 1,
expression 2, … expression n are positive –valued integer expression that
indicate the maximum number of array element associated with each subscript.
The
parentheses that surround the array name should normally be evaluated right to
left. Suppose that x is a two-dimensional integer array having 10 rows and 20
columns. We can declare x as a
Int(*x)[20];
In this
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 (row 0) of the original two-dimensional
array. Similarly, (x+1) points to the second 20 elements array. which is the
second row(row 1) of the original two-dimensional array and so on.
An
individual array element within a multidimensional array can also be accessed
by repeatedly using the indirection operator. Usually, however this procedure
is more awkward then the conventional method for accessing an array element.
The following example illustrates the use of the indirection operator.
Suppose
that x is a two dimensional integer array having 10 rows and 20 columns, as
declared as
Int(*x)
[20];
The item
in row2, column 5 can be accessed by working either.
X[2][5]
or *(*(x+2)+5)
Here,
(x+2) is a pointer to row 2, therefore, the object of this pointer *(x+2),
refers to the entire row since row2 is a one-dimensional array. *(x+2) is
actually a pointer to the first element in row 2. we now add 5 to the pointer.
hence, (*(x+2)+5) is a pointer to element 5 in row 2. the object of this
pointer, refers to the item in column 5 or row 2 which is x[2][5].
ARRAY OF POINTERS:
A
multidimensional array can be expressed in terms of an array of pointers rather
than as a pointer to a group of contiguous arrays. In such situations the newly
defined array will have one less dimension that the original multidimensional
array. such pointer will indicated the beginning of separate (n-1) dimensional
array.
In
general terms a two-dimensional array can be defined as one-dimensional array
of pointes by writing
Data-type *array(expression 1);
Similarly
an n-dimensional array can be defined as (n-1) dimensional array of pointer by
writing,
Data-type
*array[expression 1][expression 2]…[expression n];
In these
declaration data type refers to the data type of the original n-dimensional
array. array is the array name and expression 1, expression 2, expression n are
positive valued integer expressions that indicate the maximum number of element
associated with each subscript.
A
right-to-left rule first associates the pairs of square brackets with array, defining
the named object as an array. the preceding asterisk then establishes that the
array will contain pointers.
The last
(the right most) expression is when defining an array of pointers. Where as the
first (the left most) expression is omitted when defining a pointer to a group
of arrays. When an n-dimensional array expressed in this manner an individual
array element within the n-dimensional array can be accessed by a single use of
the indirection operator for example,
We can
define x as a one dimensional array of pointers by writing
Int *x[10];
Hence,
x[0] points to the beginning of the first row, x[1] points to the beginning of
the second row and so on. Note that the number of element within each row is
not explicitly specified.
An
individual array element, such as x[2][5] can be accessed by writing,
*(x[2]+5)
In this
expression, x[2] is a pointer to the first element in row 2 so that x[2] +5
points to element 5 within row 2. the object of this pointer, *(x[2] +5)
therefore refers to x[2][5]. Now consider a three-dimensional floating-point
array t. suppose the dimension of t is 10 x 20 x 30. this array can be
expressed as a two-dimensional array of pointers by writing
Float
*t[10][20];
Therefore
we have 200 pointers, each pointing to a one-dimensional array. an individual
array element, such as t[2][3][5] can be accessed by writing
*(t[2][3]+5)
In this
expression, t[2][3] is a pointer to the first element in the one-dimensional
array represented by t[2][3]. Hence (t[2][3]+5) points to element 5 within this
array. the object of this pointer *(t[2][3]+5) therefore represents t[2][3][5].
Pointer
arrays offer a particularly convenient method for storing strings. In this
situation, each array element is a character type pointer that indicated the
beginning of separate string. Thus an n-element array can be point to n
different strings. Each individual string can be accessed by referring to its
corresponding pointer.
For
example, char name[10][12]; here name contains
10 rows to accommodate the 10 strings. Each row must be large enough to
store at least 12 characters. A better way to do this is to define a 10 element
of pointer, that is,
Char
*name[10];
Thus,
name[0] will indicate the first name. Name[1] will indicate the second name and
so on.
Just as
individual strings can be accessed by referring to the corresponding pointers.
(i.e. corresponding array element). So can individual string element be
accessed through the use of the indirection operator. For example,
*(*(name+2)+3) refers to the forth character in the third string of the array
name.
If the element of the array is sting pointers, a set of initial values can be specified as a part of the array declaration. In such cases the initial values will be strings, where each string corresponds to a separate array element. Remember however that an array must be declared static if it is initialize within a function. For example
in this
example, name is a 5-element array of pointers. The first array element (i.e.
the first pointer ) will point to Pacific, the second element will points to
Atlantic, and so on.
PASSING POINTER TO FUNCTIONS :
Pointer
parameters are commonly employed in string functions. Consider the function
copy which copies one sting to another.
Copy(s1,s2);
Char *s1, *s2;
0 comments:
Post a Comment