Tuesday 3 February 2015

Pointers in C

Pointers:
·        Pointers are variables that contain memory addresses and are used to access the data stored in the memory.
·        Pointers are used to return the multiple values from a function via arguments
·        Each location has a unique address .
Example :
int  x ;
x = 10;
int  *ptr;  /*    *ptr is a pointer variable pointing to an integer value */
·        “*” indicates that pointer variable ‘ptr’ contains address of variables .
·        The address should contain only integer type values .
ptr = &x;
            [&x is used to get the address of x]
Eg :
printf(“%d” , *ptr);
printf(“%d”, ptr);
printf(“%d”, &ptr);
Here , *ptr tells that the variable is a pointer .
·        ptr tells the name of memory location and points to a variable .
·        &ptr tells us the address of variable .
Determining the address of a variable can be done with the help of the operator ‘&’.
               Ex: P = & x;
               Would assign the address of x (the location of quantity) to the variable p. The ‘&’ operator can be remembered as ‘address of’.
                The ‘&’ operator can be used only with a simple variable or an array element.
              The following are illegal use of an address operator.
(1)    int x[10];
  &x (pointing at array names).
(2)   &(x+y) (pointing at expressions).

If x is an array, then expression such as & X [0] and & X [i+3]  are valid and represents the addresses of 0th and (i+3)th  elements of X.
POINTERS AND ARRAYS :
·        An Array name can be assigned to the pointer variable, because it contains the address of the first element.
·        When an array is declared the compiler allocates certain base address and storage in memory locations .
·        The base address is the location of the first element in an array .
·        For example : int x[5] = {1,2,3,4,5};
·        An array ‘x’ with size of 5 elements is declared and will be stored as follows .
·        Let us assume that the base address of ‘x’ is 100 then  , the remaining elements will be stored as follows :
 x =& x [1] = 1000+1 (no.of bytes required by    
                             the ‘int’ type )
                         = 1000+ 1(2) = 1002
If we declare ‘p’ as an integer pointer , as
int  *p;
p = x is equal to
p = & x [0]; ð p=& x [0] = 1000
                        P= & x [1] = 1002
                        P= & x [2]= 1004
                         P=& x [3] = 1006
                         P = & x [4] = 1008

POINTERS AND CHARACTERS :
·        Strings can be treated as character arrays .
·        The compiler automatically inserts the null character ‘\0’ at the end of the string .
·        Strings can be created using pointer variables .
Eg : char* str = “apple” ;
 Now , the string “apple” is stored as
·        The pointer ‘str’ points towards the first character  .  Assignment operator is used for giving values  .
 char *string1;
 String1 = “apple “;
·        The above statement is not a string copy because the variable ‘string1’ is a pointer not a stiring .
POINTERS AS FUNCTION ARGUMENTS :
·        We can pass the address of a variable as an argument to a function in the normal fashion.
·        When we pass addresses to a function ,  the parameters receiving the addresses should be pointers . the process of calling a function using pointers to pass the address 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 .
Consider the following code :
Main()
{
     int x ;
     x=20;
     change(&x);  /*call by reference or address*/
     printf(“%d\n”, x);
}
Change(int  *p)
{
*p = *p + 10 ;
}
·        When the function change() is called , the address of the variable x is passed into the function change() . Inside change() , the variable p is declared as a pointer and therefore p is the address of variable x .
·        Thus , call by reference provides a mechanism by which the function can change the stored values in the calling function .
·        Note that this mechanism is also known as “call by address” or “pass by pointers” .
·        Rules :
1)    The function parameters are declared as pointers .
2)    The dereferenced pointers are used in the function body.
3)    When the function is called the addresses are passed as actual arguments .


FUNCTION RETURNING POINTERS :
We can force a function to return a pointer to the calling function . consider the following code :
int *larger (int * , int *); /*prototype*/
main ( )
{     
  Int a = 10;
  Int b = 20;
  Int *p;
  p = larger (&a , &b);
  printf (“%d”, *p);     /*function call */
}
int *larger (int *x , int *y)
{
    if (*x>*y)
             return (x);   /*address of a */
    else
             return (y);   /*address of b */
}
·        The function larger receives the addresss of the variable a and b , decides which one is larger using the pointers x and y and then returns the address of its location . The returned value is then assigned to the pointer variable p in the calling function . In this case , the address of b is returned and assigned to p and therefore the output will be the value of b , namely 20 .
·        The address returned must be the address of a variable in the calling function.

POINTERS TO FUNCTIONS :
·        A function , like a variable , has a type and an address location in the memory . It is therefore , possible to declare a pointer to a function , which can 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 . the value parentheses around *fptr are necessary . remember that a statement like
                 type *gptr();
·        Would declare gptr as a function returning a pointer to type
·        We can make a function pointer to point to a specific function by simply assigning the name of the function to the pointer . for example , the statements
                double mul (int, int);
                double (*p1) ();
                 p1 = mul;
·        Declare p1 as a pointer to a function and mul as a function and then make p1 to point to the function mul. To call the function mul , we may now use the pointer p1 with the list of parameters. That is ,
               (*p1)(x,y)  /*function call*/
Is equivalent to
                    mul(x,y);
POINTERS AND STRUCTURES :
The name of a structure stands for the addresses of the 0th element . consider the following declaration :
                      struct inventory
                      {
                               Char   name[30];
                                Int   number ;
                                Float price ;
                        }  product [2] ,   *ptr ;
Its members can be accesed using the following notation
            Ptr->name
             Ptr->number
             Ptr->price
The symbol ‘->’ is called arrow operator ( also known as “member selection operator”). Ptr -> is simply another way of writing product[0].
POINTER TO STRUCTURE VARIABLES :
While using structure pointers , we should take care of the precedence of operators . the operators ‘->’ and ‘.’ And () [] have the highest priority among operators. They bind very tightly with their operands . for example
 Struct
{
                  Int count ;     /*pointer inside the struct*/
                  Float  *p ;      /*struct type pointer*/
 }  *ptr ;
Then the statement
                  ++ptr -> count ;
Increments the count not ptr. However
                  (++ptr)  -> count ;
Is legal and increments ptr after accessing count .
The following statements also behave similarly ,
*ptr ->p        fetches whatever p points to
*ptr->p++     increments p after accessing whatever it points to
(*ptr->p)++          increments whatever p points to
*ptr++->p            increments ptr after accessing whatever it
                               points to

Array of pointers to functions
#include <stdio.h>

int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);

int (*p[4]) (int x, int y);

int main(void)
{
  int result;
  int i, j, op;

  p[0] = sum; /* address of sum() */
  p[1] = subtract; /* address of subtract() */
  p[2] = mul; /* address of mul() */
  p[3] = div; /* address of div() */

  printf("Enter two numbers: ");
  scanf("%d %d", &i, &j);
  
  printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n");
  do {
    printf("Enter number of operation: ");
    scanf("%d", &op);
  while(op<|| op>3);

  result = (*p[op]) (i, j);
  printf("%d", result);

  return 0;
}

int sum(int a, int b)
{
  return a + b;
}

int subtract(int a, int b)
{
  return a - b;
}

int mul(int a, int b)
{
  return a * b;
}

int div(int a, int b)
{
  if(b) 
      return a / b;
  else 
      return 0;
}
 






No comments:

Post a Comment