MAP

POINTERS IN C


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.


address of  v
 
value of v
 
                                                                 

            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 :

Text Box: #include <stdio.h>
main()
{
int n=1, v=3;
void fun2(int pu, int *pv) ;
printf(“ \n after calling func2 : u=%d v=%d “ , u,v) ;
}
void fun2(int *pu, int *pv)
{
*pu=0 ;
*pv=0 ;
printf(\n within fun2 pu=%d pv=%d”, pu,*pv);
return;
}

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

Text Box: #include <stdio.h>
main()
{
	static int x[5] = {10, 11, 12, 14};
	int I;
	for(I=0; I<5; I++)
	printf(“\n I=%d x[I]=%function *(x+I)=%d &x[I] = %d(x+I) %d”, x[I], *(x+I),&x[I],x+I);
}

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.

Text Box: Static char *name[5] = {
				“pacific”,
				“Atlantic”,
				“Indian”,
				“Caribbean”,
				“Bering”
			};

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

Twitter Delicious Facebook Digg Stumbleupon Favorites More