Wednesday, September 12, 2012

Pointers, Call by Value & Reference

Pointers : 

C# also supports pointers in a limited extent. A pointer is nothing but a variable that holds the memory address of another type. But in C# pointer can only be declared to hold the memory address of value types and arrays. Unlike reference types, pointer types are not tracked by the default garbage collection mechanism. For the same reason pointers are not allowed to point to a reference type or even to a structure type which contains a reference type. We can say that pointers can point to only unmanaged types which includes all basic data types, enum types, other pointer types and structs which contain only unmanaged types.  


The general form of declaring a pointer type is as shown below 
       
type *variable_name;  

Where * is known as the de-reference operator. For example the following statement 

int *x ; 
Declares a pointer variable x, which can hold the address of an int type. The reference operator (&) can be used to get the memory address of a variable.  

int x = 100; 

The &x gives the memory address of the variable x, which we can assign to a pointer variable
 
int *ptr = & x;.

Console.WriteLine((int)ptr) // Displays the memory addressConsole.WriteLine(*ptr) // Displays the value at the memory address. Unsafe Codes :

The C# statements can be executed either as in a safe or in an unsafe context. The statements marked as unsafe by using the keyword unsafe runs out side the control of Garbage Collector. Remember that in C# any code involving pointers requires an unsafe context. 
We can use the unsafe keyword in two different ways. It can be used as a modifier to a method, property, and constructor etc. For example          using System;
class MyClass
{
static void Main(string[] args)
        {
            unsafe
            {
                int a = 10;
                int* ptr = &a;  //pointer valriable
                Console.WriteLine("value of a :" + (*ptr));
                Console.WriteLine("address of a :"+(int)ptr);
                Console.Read();
            }
        }




Pointers & ConversionsIn C# pointer types do not inherit from object and no conversion exists between pointer types and objects. That means boxing and un-boxing are not supported by pointers. But C# supports conversions between the different pointer types and pointer types and integral types. 
C# supports both implicit and explicit pointer conversions within un-safe context. The implicit conversions are

  1. From any type pointer type to void * type.
  2. From null type to any pointer type.
The cast operator (()) is necessary for any explicit type conversions. The explicit type conversions are
  1. From any pointer type to any other pointer type.
  2. From sbyte, byte, short, ushort, int, uint, long, ulong to any pointer type.
  3. From any pointer type to sbyte, byte, short, ushort, int, uint, long, ulong types.
For example

char c = 'R';
char *pc = &c;
void *pv = pc; // Implicit conversionint *pi = (int *) pv; // Explicit conversion using casting operator 


Call by Value : 

In call by value method, the called function creates a new set of variables and copies the values of arguments into them.

To be more precise any changes that take place inside the calling method have no affect on the original value of the variable.Look the example below.Here in our example original value of a is 10 .When it is passed to "callByValue" method a is incremented.But it is not reflected in the main method and hence the final value of a remains same ie 10.

Pass by Reference: 


Any changes that take place inside the calling method will affect the original value of the variable."ref" keyword must be used in the calling method & called method.


Here in our example original value of a is 10 .When it is passed to "callByRef" method, a is incremented and also reflected in the main method and hence the final value of a is 20.
 Example :

public static void callByValue(int x)
        {
            x = x + x;
            Console.WriteLine("Sum : " + x);
        }
        public static void callByRef(ref int x)
        {
             x=x+x;
            Console.WriteLine("Sum : " + x);
        }
        static void Main(string[] args)
        {
                int a = 10;
                callByValue(a);
                Console.WriteLine("a value after call by val :" + a);
                callByRef(ref a);
                Console.WriteLine("a value after callby Ref :" + a);
                Console.Read();
            }
          
        }


No comments:

Post a Comment