2 pointers

Upload: badshahsaad

Post on 08-Apr-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/6/2019 2 Pointers

    1/18

    POINTERS

    INTRODUCTION:

    Computers use their memory for storing the instructions of a

    program, as well as the values of the variables that are associated with it.The computers memory is a sequential collection of Storage Cells. Each cell,

    commonly known as a byte, has a number called address associated with it.

    Whenever we declare a variable, the system allocates, somewhere in

    the memory, an appropriate location to hold the value of the variable. Since,

    every byte has a unique address, this location will have its own address.

    Consider the following statement:

    int var=10;

    This statement instructs the system to find a location for the integer

    variable var and puts the value 10 in that location. Let us assume that thesystem has chosen the address the location 2000 for var.

    var

    2000

    During execution of the program, the system always associates the

    quantity with the address 2000(this is similar to having house no as well as

    the house name). We may have access the value 10 by using either the name

    var or the address 2000. Since memory addresses are simply numbers, they

    can be assigned to some variables which can be stored in memory, like anyother variable. Such variables that hold memory addresses are called

    pointers.

    Def: Pointer is variable that contains an address which is a location ofanother variable in memory.

    ptr var

    3000 2000Since a pointer is a variable, its value is also stored in the memory in

    another location. Suppose, we assign the address of var to a variable ptr.

    The link between the variable ptr and var visualized as shown in fig.

    Since the value of the variable ptr is the address of the variable var,

    we may access the value of var by using the value of ptr and therefore, we

    1

    102000

    10

  • 8/6/2019 2 Pointers

    2/18

    say that the variable ptr points to the variable var. Thus ptr gets name

    pointer.

    POINTER VARIABLE DECLARATION AND INITIALIZATION:The actual location of a variable in the memory is system dependent.

    To know the address of the variable C provides a operator called ampersand(&). This operator returns the address of the variable.

    To print the address of the variable we have to use %u or %x.Since the memory address are unsigned integers. If we used %u it prints

    positive integer and if we use %x it prints the address in hexadecimal

    format.

    ch i a

    65525 fff2 ffee#include

    #include

    void main()

    {

    char ch='A'; Output:65525

    int i=10; fff2

    float m=38.73; ffee

    clrscr();printf("%c is stored at addr %u\n",ch,&ch);

    printf("%d is stored at addr %x\n",i,&i);

    printf("%f is stored at addr %x\n",m,&m);

    getch();

    }

    POINTER DECLARATION:

    In C, every variable must be declared for its type. Since pointer

    variables contains addresses that belong to a separate data type, they must

    be declared as pointers before we use them. The general format of format

    declaration is

    datatype *pt_name;This tells the compiler three things about the variable pt_name

    1. The asterisk(*) tells that the variable pt_name is a pointer variable.

    2. pt_name needs a memory location.

    2

    A 10 38.73

  • 8/6/2019 2 Pointers

    3/18

    3. pt_name points to variable of type datatype.

    Example: int *ptr;

    This declaration tells that the variable points to an integer datatype.INITIALIZING POINTERS:

    Once a pointer variable has been declared, it can be made to point a

    variable using an assignment statement such as

    int i=10,*ptr;

    ptr=&i; or int *ptr=&i;which causes ptr to point to i. That is, p now contains the address of i.

    Note: A pointer declared of one datatype cannot point to

    variable of another datatype.

    We must ensure that the pointer variables always pointing to thecorresponding type of data. For example

    float a,b;

    int x,*p;

    p=&a; (Error because we are assigning int pointer to float var)

    p=&x;

    will result in erroneous output because we are trying to assign the address

    of a float variable to an integer pointer. When we declare a pointer to int

    type, the system assumes that any address that this pointer will hold will

    point to an integer variable.ACCESSING A VARIABLE THROUGH ITS POINTER:

    Once a pointer has been assigned the address of a variable, we can

    access the value of the variable using this pointer . This is done by using

    another unary operator *(asterisk), known as the indirection operator.

    1. int x,*ptr,y;

    2. x=10;

    3. ptr=&x;

    4. y=*ptr;5. *ptr=25;

    4106 4104 4102

    Ptr x y

    3

  • 8/6/2019 2 Pointers

    4/18

  • 8/6/2019 2 Pointers

    5/18

    The output of the program is:The value in the pointer variable 65532

    value at where the pointer is pointing 10

    The value assigned to y is 10

    Example 2: #include

    #include

    void main()

    {

    int x=10,y;

    int *ptr1,*ptr2;

    clrscr();

    ptr1=&x;ptr2=&y;

    *ptr2=*ptr1;/*Assigning value at ptr1 to point ptr2 points*/

    printf("The value at ptr2 points (i.e y value) %d",*ptr2);

    getch();

    }

    The output of the program is:The value at ptr2 points (i.e y value) is 10.

    Example: #include

    #include

    void main()

    {

    int a,b,c,d;

    int *ptr1,*ptr2,*ptr3,*ptr4;

    clrscr();

    ptr1=&a;

    ptr2=&b;ptr3=&c;

    ptr4=&d;

    *ptr1=5;

    *ptr2=*ptr1+5;

    *ptr3=*ptr2**ptr1;

    *ptr4=*ptr3/ *ptr2; (Give space btwn / and *)

    5

  • 8/6/2019 2 Pointers

    6/18

    printf("The values of a,b,c,d are %d %d %d %d",a,b,c,d);

    getch();

    }

    OUTPUT: The values of a,b,c,d are 5 10 50 5

    CALLING FUNCTIONS BY REFERENCE

    There are two ways to pass arguments to a function

    1) Call by Value

    2) Call by Reference

    Call by Value: refers to sending value of arguments onto the function. In

    this method, the value of actual arguments is copied onto the corresponding

    formal arguments whenever a function is called. The various operations

    performed on their(formal arguments) values of the function has no effect

    on the value of actual arguments in the main function. The following exampleclearly illustrates the call by value method.

    a b a b

    x y x y

    Before Swapping After Swapping

    #include

    #include

    void swap(int,int);

    void main()

    {

    int a=10,b=20;

    clrscr();

    printf("value of a before function call= %d\n",a);

    printf("value of b before function call= %d\n",b);swap(a,b); /*a&b are actual arguments*/

    printf("value of a after function call= %d\n",a);

    printf("value of b after function call= %d\n",b);

    getch();

    }

    void swap(int x,int y)/*x & y are formal arguments*/

    6

    10 20

    10 20

    10 20

    20 10

  • 8/6/2019 2 Pointers

    7/18

    {

    int temp;

    temp=x;

    x=y;

    y=temp;printf("value of a in the function = %d\n",x);

    printf("value of b in the function = %d\n",y);

    }

    The output of the above program is:

    value of a before function call= 10

    value of b before function call= 20

    value of a in the function = 20

    value of b in the function = 10value of a after function call= 10

    value of b after function call= 20

    Call by Reference is a method , in contrast to call by value method, the

    operations performed on the formal arguments directly effects the value of

    actual arguments . This is because the formal arguments contains the

    address of actual arguments, so any changes on that address effect the

    values. The following program illustrates the call by reference method.

    a(or)*x b(or)*y a b

    x y x y

    Before Swapping After Swapping

    #include#include

    void swap(int *,int *);

    void main()

    {

    int a=10,b=20;

    clrscr();

    7

    10 20

    4024 4026

    20 10

    4024 4026

  • 8/6/2019 2 Pointers

    8/18

    printf("value of a before function call= %d\n",a);

    printf("value of b before function call= %d\n",b);

    swap(&a,&b); /*passing addresses of variables*/

    printf("value of a after function call= %d\n",a);

    printf("value of b after function call= %d\n",b);getch();

    }

    void swap(int *x,int *y)

    {

    int temp;

    temp=*x;

    *x=*y;

    *y=temp;

    printf("value of a in the function = %d\n",*x);printf("value of b in the function = %d\n",*y);

    }

    The output of the above program is:

    value of a before function call= 10

    value of b before function call= 20

    value of a in the function = 20

    value of b in the function = 10

    value of a after function call= 20value of b after function call= 10

    POINTER EXPRESSIONS AND POINTER ARTHMETICPointers are valid operands in arithmetic expressions, assignment

    expressions, and comparision expressions.

    A limited set of arithmetic operations may be performed on pointers.

    A pointer may be incremented(++) or decremented(--), an interger may be

    added to a pointer(+ or +=), an integer may be subtracted from a pointer or-

    =) or one pointer may be subtracted from another.

    Pointers are used with unary operators such as

    incrementation ++

    decrementation --

    Pointers are variables which mainly store the address, they are not

    integers or definite value of a particular data type. Therefore the increase

    or decrease in pointer variable refers to the increment and decrement of

    8

  • 8/6/2019 2 Pointers

    9/18

    address not of data. For example, in case of integer type of pointer variable,

    if the pointer variable is incremented then, the address of pointer will be

    incremented by two address spaces. This is because one integer valued takes

    two bytes to store therefore the increment in address will be of two

    positions. This implies that the increment or decrement in pointer variabledepends on the type of pointer declared. The program given below will clear

    this point.

    Example: To display the address of pointer before and after incrementing.

    #include

    #include

    void main()

    {

    int a=10,*ptr;

    clrscr();ptr=&a;

    printf("Addr of pointer(ptr) before increment:%u\n",ptr);

    ptr++;

    printf("Addr of pointer(ptr) after increment:%u\n",ptr);

    getch();

    }

    OUTPUT: Addr of pointer(ptr) before increment:65522

    Addr of pointer(ptr) after increment: 65524

    The above programs output shows that the ptr of integer type

    contains address of int a. therefore the initial address of the pointer will be

    same as of integer a i.e 65522. After the incrementation operation, the

    address of pointer increases by two positions i.e 65524. This is because

    the pointer taken is of integer type and one integer takes two bytes to

    store.

    Similarly, the position/ address of pointer decreases when a

    decrementation operation is performed on it. The program given below show

    s the decrement of pointer variable.

    Example: To display the address of a pointer variable before and after

    decrementing.

    #include

    #include

    void main()

    {

    9

  • 8/6/2019 2 Pointers

    10/18

    int a=10,*ptr;

    clrscr();

    ptr=&a;

    printf(The addres of ptr before decrement:%u,ptr);

    ptr--;printf(The address of ptr after decrement:%u,ptr);

    getch();

    }

    OUTPUT: The address of ptr before decrementation: 65524

    The address of ptr after decrementation : 65520

    The above programs output clearly shows that since pointer taken is

    of float type therefore the decrementation operation on pointer leads to

    decrease in four address spaces.Pointers are also used with arithmetic operators for increment and

    decrement of address spaces. The arithmetic operators used are + and (not

    * and /). The following program shows the arithmetic operators with

    pointers to .

    To demonstrate arithmetic operations on pointers

    #include

    #include

    void main()

    {int a=10,*ptr1,*ptr2,*ptr3;

    clrscr();

    ptr1=&a;

    printf("Adress of pointer(ptr1) is %u\n",ptr1);

    ptr2=ptr1+2;

    printf("Address of pointer(ptr2) is %u\n",ptr2);

    ptr3=ptr1-2;

    printf("Address of pointer(ptr3) is %u\n",ptr3);

    getch();

    }

    OUTPUT: Address of Pointer(ptr1) is 65524

    Address of pointer(ptr2) is 65528

    Address of pointer(ptr3) is 65520

    10

  • 8/6/2019 2 Pointers

    11/18

    In above program, pointers ptr1,ptr2 and ptr3 are of integer type.

    Pointer ptr1 is assigned the address of integer a. Pointer ptr2 is assigned as

    pointer ptr1 plus 2. This means that, since ptr1 is an integer variable, there

    the addition of 2 to it leads to addition in address two times i.e by 4.

    Similarly, pointer ptr3 is assigned as pointer ptr1 minus 2. This meansthat ptr3 is equal to substraction of 2 from ptr1 which leads to decrease in

    address two times i.e by 4 .

    One pointer variable can be subtracted from another provided both

    variables point to element of the same. The resulting value indicates the

    number of bytes separating the corresponding array elements. This is

    illustrated in the following program.

    Example: #include

    #include

    void main(){

    int a[]={10,20,30,45,67,56,74,90};

    int *i,*j;

    clrscr();

    i=&a[1]; Output: 4 36

    j=&a[5];

    printf("\t%d\t%d",j-i,*j-*i);

    getch();

    }

    1000 1002 1004 1006 1008 1010 1012 1014

    i j

    Here i and j have been declared as integer pointers holding addressesof first and fifth element of the array respectively.

    Suppose the array begins at location 1000, then the elements a[1] and

    a[5] would be present at location 1002 and 1010 respectively since each

    integer in the array occupies two bytes in memory. The expression j-i would

    print a value 4 not 8. This is because j and I are pointing to locations which

    are 4 integers apart. What would be the result of the expression *j-*i? 36,

    11

    10 20 30 45 67 56 74 90

    1002 1010

  • 8/6/2019 2 Pointers

    12/18

    since *i and *j return the values present at addresses contained in the

    pointers i and j i.e 20 and 56. Therefore, *j-*I results 36.

    Do not attempt the following operations on pointers, they would never work.

    1) Addition of two pointers (i.e ptr1+ptr2)2) Multiplication of a pointer with a constant ( i.e ptr*3) and

    multiplication of pointer with a pointer (i.e ptr1*ptr2).

    3) Division of a pointer with a constat(i.e ptr/4) and division of pointer

    by a pointer(i.eptr1/ptr2).

    POINTER COMPARISIONPointer variables can be compared provided both variables point to

    objects of the same data type. Such comparisons can be useful when both

    pointer variables point to elements of the same array. The comparison cantest for either equality or inequality. Moreover a pointer variable can be

    compared with zero(usually expressed as NULL). The following program

    illustrates how the comparison is carried out.

    Example: #include

    #include

    void main()

    {

    int arr[]={10,20,36,72,12,38};int *p,*q;

    clrscr();

    p=&arr[4];

    q=&arr[4];

    if(p==q)

    printf("The two pointers point to the same location");

    else

    printf("The two pointers do not point to same location");

    getch();

    }

    OUTPUT: The two pointers point to the same location.

    12

  • 8/6/2019 2 Pointers

    13/18

    THE RELATIONSHIP BETWEEN POINTERS AND ARRAYS

    When an array is declared, the compiler allocates a base address and

    sufficient amount of storage to contain all elements of the array in

    contiguous memory locations. The base address is the location of the first

    element(index 0) of the array. The compiler also defines the array name as aconstant pointer to the first element. Suppose we declare an array x as

    follows:

    int x[5]={1,2,3,4,5};

    Suppose the base address of x is 1000 and assuming that each integer

    requires two bytes, the five elements stored as follows:

    x[0] x[1] x[2] x[3] x[4]

    1000 1002 1004 1006 1008

    Base addressThe name x is defined as a constant pointer pointing to the first

    element, x[0] and therefore the value of x is 1000, the location where x[0]

    is stored. That is,

    X=&x[0]=1000

    If we declare ptr as an integer pointer, then we can make the pointer

    ptr to point to the array x by the following assignment

    int *ptr; or int *ptr;

    Ptr=x; ptr=&x[0];

    ptr x[0] x[1] x[2] x[3] x[4]

    2000 1000 1002 1004 1006 1008

    Now the pointer ptr is pointing to starting address of the array. The

    pointer expression to represent the address of a[3](i.e &a[3]) is

    Ptr+3and the pointer expression to represent the value at a[3] is

    *(ptr+3) ( Value at that address)

    Here the parenthesis is necessary because the precedence of * is higher

    than the precedence of +. With out parenthesis, the above expression would

    add 3 to the value of the expression *ptr(i.e 3 is added to x[0] assumed ptr

    is pointing to the beginning of the array).

    13

    1 2 3 4 51000

    1 2 3 4 5

  • 8/6/2019 2 Pointers

    14/18

    Now, we can access every value of x using ptr++ to move from one

    element to another. The relationship between ptr and x is shown below.

    ptr = &x[0] = 1000 *ptr = x[0] = 1ptr+1 = &x[1] = 1002 *(ptr+1) = x[1] = 2

    ptr+2 = &x[2] = 1004 *(ptr+2) = x[2] = 3

    ptr+3 = &x[3] = 1006 *(ptr+3) = x[3] = 4

    ptr+4 = &x[4] = 1008 *(ptr+4) =x[4] = 5

    The array name itself can be treated as pointer and used in pointer

    arithmetic. For example, the expression

    *(x+3)

    also refers to the array element x[3]. In general, all subscripted arrayexpressions can be written with a pointer and offset. In this case,

    poiter/offset notation was used with the name of the array as a pointer.

    Note that the preceding statement does not modify the array name in any

    way: x still points to the first element in the array.

    Pointers can be subscripted exactly as arrays can. For example, the

    expression

    ptr[3]

    refers to the array element x[3].

    An array name is essentially a constant pointer; it always point to thebeginning of the array. Thus, the expression

    x+=3

    is invalid because it attempts to modify the value of the array name with

    pointer arhtematic.

    Example: #include

    #include

    void main()

    {

    int x[]={10,20,30,40},*ptr,i;

    ptr=x;/* set ptr to point to array x*/

    clrscsr();

    printf(" The array x printed with\n\n");

    printf("\n\nArray subscript notation\n");

    for(i=0;i

  • 8/6/2019 2 Pointers

    15/18

    printf("\n\npointer/ offset notation where\n");

    printf("the pointer is the array name\n");

    for(i=0;i

  • 8/6/2019 2 Pointers

    16/18

    char *s="Hyderabad";

    clrscr();

    printf("%s\n",arr);

    printf("%s",s);

    getch();}

    a[0]..a[8] s 1000

    Stored in array Pointer Some Mem loc

    OUTPUT: Hyderabad

    Hyderabad

    Here, though the declarations of arr and s are different the output

    of both the printf() is same. What exactly is the difference in thedeclarations?. In the first declaration Hyderabad gets stored in array arr[

    ], whereas in the second Hyderabad gets stored at some place in memory

    and the base address of it is stored in s. In other words s points to the

    zeroth character in the string.

    On mentioning the name of the array arr we get its base address.

    Hence the following printf() would print the base address of arr and the

    address stored in s.

    printf(%d %d,arr,s);

    In that sence arr acts as a pointer to a char. But the similarity between arrand s ends there. The following program outlines this difference.

    void main()

    {

    char str[ ],arr[10]="Hyderabad";

    char *s="Hyderabad",*p;

    s++;

    arr++; /*Error because we are changing base address*/

    str=arr;/*Error because we cannot assign*/

    p=s;/* This statement works*/printf("%s\n",arr);

    }

    Here s++ increments s such that it starts pointing to y of

    Hyderabad and hence printf() would output yderabad. As against this

    arr++ would give an error message. This is because all that is known to the C

    16

    H y d e r a b a d

    d1000 Hyderabad

  • 8/6/2019 2 Pointers

    17/18

    compiler about an array is its base address, and if we do arr++ we are

    attempting to change this base address. This the C compiler would never

    allow.

    The other difference is we cannot assign a string to another, whereas,

    we can assign a char pointer to another char pointer.

    Another difference between arrays and pointers is the way the sizeof

    operator treats them.

    printf(%d %d,sizeof(s),sizeof(arr));

    In this statement the first expression would print 2 since size of any

    Pointer is 2 bytes. However, the second expression would print 10 because

    the array contains 10 characters including 0 .

    ARRAY OF POINTERSThe way there can be an array of ints or an array of floats, similarlythere can be an array of pointers. Since a pointer variable always contains an

    address, an array of pointers would be nothing but a collection of addresses.

    The addresses present in the array of pointers can be addresses of isolated

    variables or addresses of array elements or any other addresses.

    The general format of declaring array of pointers is as follows

    datatype *arr_name[sz];

    Example: int *arr[5];This indicates arr is the array which consists of pointers point to

    integer data type.

    Example: #include

    #include

    void main()

    {

    int *arr[4];

    int a=31,b=5,c=19,d=71,i;

    clrscr();

    arr[0]=&a;

    arr[1]=&b;

    arr[2]=&c;

    arr[3]=&d;

    for(i=0;i

  • 8/6/2019 2 Pointers

    18/18