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;
}
 






Passing arrays to functions in C

Passing arrays to functions:
One dimensional array :
To pass a one dimensional array to a called function, it is sufficient to list the name of the array(without any subscript)  and the size of the array as argument.
 For example

int  arry[10],n;  /*array declaration*/
                   ----
                   ----
                     largest(arry, n); /* function call st. - passing array as actual argument*/

                       

Text Box: int largest(int array[], int size) /* function definition. - array as formal argument*/

The call function call largest (arry, n) , Will pass the whole array arry to the called function. The called function expecting this call must be approximately defined.
The largest function header might look like

The pair of brackets informs the compiler that the arguments array is an array of numbers. It is not necessary to specify the size of the array here.

Main()
{
  int largest (float arry[], int n);
  int value[4]={12, 25, 2, 67};
  printf(“%d\n”,largest(value,4));
}
int largest(int arry[],int n)
{
  int i;
  int max;
  max=a[0];
  for(i=1;i<n;i++)
    if(max<a[i])
    max=a[i];
return(max);
}

Consider a problem of finding the largest value in an array of elements.
When the function call largest( value,4) is made, the values of all elements of array value become the corresponding elements of array a in the called function. The largest function finds the largest value in the array and returns the result to the main.
By passing the array name, we are infact, passing the address of the array to the called function. The array in the called function now refers to the  same array stored in the memory that is created from the main. Therefore, any changes made in the array in the called function will be reflected in the original array of the main.

Passing address of parameters to the functions is referred to as pass by address.    

Storage Classes in C

Storage Classes :
In C all variables have a data type, they also have a storage classes .the following variable storage classes are most relevant to functions :
1. automatic variables
2. external variables
3. static variables
4. register variables
The scope of variable determines over what region of the program a variable is actually available for use
Longevity refers to a period during which a variable retains a given value during execution of a program. The visibility refers to the accessibility of a variable from the memory.
The variables may also be broadly categorized , depending on the place of their declaration ,as internal or external. internal variables are those which are declared with in a particular function ,while external variables are declared outside of any function.
AUTOMATIC VARIABLES :
·         Automatic variables are declared inside a function in which they are to be utilized .
·         They are created when the function is called and destroyed automatically when the function is exited .
·         These are private to a function in which they are declared  because of this property , automatic variables are also referred to be as local or internal variable .
·         A variable declared inside a function without storage classes specifications is, by default, an automatic variable .
Example:
main()
{
int number ;   /* by default number is automatic variable*/
…..
…..
}
We may also use a keyword auto to declare automatic variables
main ()
{
  auto int number;
--
--
}
External variables:
·         These  are both  alive and active through out the entire program are known as external variables.
·         They are also known as global variables.
·         They can be accessed by any function in the program.
·         External variables are declared out side the function.
Example:
   int  number;
  float  length=7.5;
  main()
{
   ---
   ----
}
function1()
{
----
}
External Declaration :
  main()
{
 ----
extern  int  y;   /* external declaration */
  ---
 ----
}
function1()
{
extern   int  y; /* external declaration */
--
}
int  y;  /*  definition*/

·         The External Declaration  of y inside the functions informs the compiler that y is an integer type defined somewhere else in the program.
·         Extern declaration does not allocate storage space for variables. In case of arrays, the definition should include their size as well.
Static  Variables :
·         Static  variables persists until the end of the program. A variable can be declared static using the key word static.
static  int  x;
·         A Static  Variable may be either an internal type or external type depending on the place of declaration.
·         Internal static variables are those which are declared inside the function.
·         The scope of internal static variables extend up to the end of the function in which they are defined. Therefore, they are similar to auto variables.
·         They remain in existence (alive) through out the remainder of the program . It can be used to count the number of calls made to a function.
·         An external static variable is declared outside of all functions and is available to all the functions in that program.
·         Ex:  
void   ex_of_static ()
{
   static int  m=0;
   m++;
   printf(“m in function =%d”, m);
}
        
void main()
            {
               static int n=5;
               printf(“ n in main = %d”, n);
               ex_of_static();
                n++;
                printf(“ n in main = %d”, n);
ex_of_static();
           }
OUTPUT:
  n in main = 5
  m in function = 1
   n in main = 6
  m in function = 2
 
Register variables :
·         We can tell the compiler that a variable should be kept in one of the machine’s registers instead of keeping in the memory where normal variables are stored.
·         Register variables can be accessed  faster than memory variables.
·         Most of the compilers allow only int or char variables to be placed in the register.

·         Ex : register int x;