Monday, December 23, 2013

Chapter 9: Pointer



9.1 Introduction
Pointer data type is one of the strengths of C and C++ language. The pointer is a powerful technique to access the data by indirect reference as it holds the address of that variable where it has been stored in memory. A pointer is a variable, which holds the memory address of another variable. Sometimes, only with the pointer a complex data type can be declared and accessed easily. The pointer has the following advantages.
·It allows passing variables arrays, strings and structures as function arguments.
·A pointer allows returning structures variables from functions.
·It provides functions, which can modify their calling arguments.
·It supports dynamic allocations and de-allocations of memory segments
·Pointer can return more than one value.
·A pointer improves the efficiency of certain routines.
A pointer contains the memory address. Most commonly this address is the locations of another variable, where it has been stored in memory. If one variable contains the address of another variable then the first variable is said to point to the second. In C and C++ pointer are distinct such as integer pointer, character pointer, floating point number pointer etc. A pointer consists of two parts, namely

a) The pointer operator
b) The address operator

a) Pointer operator
A pointer operator can be represented by combinations of * (asterisk) with a variable. For e.g. if a variable of integer data type and also declared * (asterisk) with another variable, it means the variable is of type “pointer to integer”. In other words, it will be used in the program indirectly to access the value of one or more integer variables.

For e.g.
int  *myptr;
where myptr is a pointer, which holds the address of an integer data type All pointer variables must be declared before it is used in C and C++ programs like other variables. When a pointer variables is declared, and asterisk must precede the variable name  this identifies the variable as a pointer

The general form of pointer declaration
data_type *pointer_variable_name;

b) Address operator
An address operator can be represented by a combination of & (ampersand) with a pointer variable. For e.g. if a pointer variable is an integer type and also declared & with the pointer variable then it means that the variable is of type “address of”. In other words, it will be used in the programs to indirectly access the value of one or more integer variables. The  “&” is unary operator that returns the memory address of its operand. A unary operator requires only on operand.

m=&ptr;
Note, that the pointer operator & is an operator that returns the address of the variable following it. Therefore, the preceding assignment statement could be verbalized as “in receives the address of ptr”.
The other operator * is the complement of &. It is unary operator that returns the value of the variable located at the address that follows
The operation of * implies to the phrase “at address”. Unfortunately, the symbol * represents both the multiplication sign and the “at address”, and the symbol & represents both bitwise AND and the “address of” sign. When these are used as pointer operators, they have no relationship to the arithmetic operators. That happened to look like the same. Both, the pointer operators, & and *, have higher precedence over all other arithmetic operators except the unary minus, with which they have equal precedence.

Pointer assignment:
A pointer is a variable data type and hence the general rule to assign its value to the pointer is same as that of any other variable data type.
For e.g.

int x=5,y;
int  *ptr1,*ptr2;

1) ptr1=&x;
Here, the memory address of variables x is assigned to the pointer variable ptr1.

2) y=*ptr1;
The contents of the pointer variables is assigned to the variable y, not the memory address

3) ptr2=ptr1; /*address if ptr1 is assigned to the ptr2*/
The address of the ptr2 is assigned to the pointer variable ptr2. The contents of both ptr1 and ptr2 will be same as these tow pointer variables hold the same address

Graphical figure of the above demo
1)
X
5
100H
Ptr1
100H
5000H
2)
Y
5
300H
ptr1
100H
5002H

Here, the value or content of ptr1 i.e 100H (address) si assigned to another pointer. So, this both pointers show to the same variables.
3)
ptr2
100H
5002H
ptr1
100H
5000H

Legend of above diagram

ptr2
100H
5002H
Variable name

A program to display the contents of the pointer
#include<stdio.h>
#include <conio.h>
main()
{
    int x;
    int *ptr;
    x=10;
    ptr=&x;
    printf("x=%d  and ptr=%d",x,ptr);
    printf("\nx=%d and contents of ptr=%d”,*ptr);
    getch();
}



Pointer Arithmetic
As a pointer holds the memory address of variable, some arithmetic operations can be performed with pointers. C and C++ supports four arithmetic operators that can be used with pointers, such as

Addition                       +
Subtraction                   -
Incrementation  ++
Decrementation            --

Pointers are variables. They are not integers, but they can be displays as unsigned integers. The conversion specifier for a pointer is added and subtracted. For e.g.

pr++    causes the pointer to be incremented, but not by 1
ptr--     causes the pointer to be decremented, but not by 1

According to datatype declared to that pointer variable if arithmetic operation is done then values(contents) will be incremented or decremented as per the data type is chosen

The following program segment illustrates the pointer arithemetic.
The integer would occupy adderss 2000 to 2001 (two bytes of memory allocation)

A program to increment the pointer’s address
main()
{
    int value,*ptr;
    value=120;
    clrscr();
    ptr=&value;
    printf("ptr=%d",ptr);
    ptr++;
    printf("\nptr=%d”,ptr);
    getch();
}
Here, lets say address of ptr which it is pointing is 4050 then after ptr++ is now increment not by one but by 2 as it is defined as integer and compiler knows that it should occupy 2 bytes show as first ti will show 4050 and after ptr++ it wil 4052.




A program to show the arithmentic operation on pointers
main()
{
    float value,*ptr;
    int x,*ptr1,*ptr2;
    value=120.0;
    ptr=&value;
    printf("\nMemory address=%d",ptr);
    ptr++;
    printf("\nMemory address after increment=%d",ptr);
    ptr--;
    printf("\nMemory address after decrement=\n\n\n%d",ptr);
    x=101;
    ptr1=&x;
    printf("ptr1=%d",ptr1);
    ptr2=ptr1+6;
    printf("\nValue of x=%d",x);
    printf("\nCotents of ptr1=%d”<<*ptr1;
    printf("\nAddress of ptr1=%d",&ptr1);
    printf("\nAddress of (ptr2=ptr1+6)=%d",&ptr2);
    printf("\nAddress of ptr2=%d”,*ptr2); /*gives the garbage value*/
}


Valid pointer operations:
·Assignment to a pointer of the same type
·Assigning a pointer to pointer of type (void *) and back
·Adding or subtracting a pointer and an integer (including increment and decrement)
·Subtracting or comparing two pointers which point to members of the same array
·Assigning or comparing to zero

#define NULL 0
main( )
{  
int x,y;  
int *px=&x;
int *py;  
void *pv;  
py=px;                         /* Assignment to a pointer of the same type*/ 
px=(int *) pv;             /* recast a (void *) pointer */  
pv=(void *)px;           /* recast to type (void *) */ 
py=px+2;                  /* Adding or subtracting a pointer and an integer is legal */  
px++;                      /* Increment and decrement is legal*/  
if(px==NULL)        /* Compare to null pointer*/    
py=NULL;             /* Assign to null pointer*/
}

Invalid pointer operations:
·Adding two pointers
·Multiply, divide, shift, mask pointers
·Add float or double numbers to a pointer
·Assign a pointer of different types without cast
main()
{   
int x,y;  
int *px,*py,*p;   
float *pf;  
px=&x;  
py=&y;  
p=px+py;     /*Addition of two pointer is illegal */ 
p=px*py;    /* Multiplication of two pointer is illegal */  
p=px/py;    /* Division of two pointer is illegal */  
p=px+10.5;  /* Addition of float to pointer is illegal */  
pf=px;      /* Assignment of different types of pointer is illegal */
}

9.2 Pointers and Functions
Pointers are very much used in function declaration. Sometimes only with a pointer a complex function can be easily represented and accessed. The use of the pointers in a function definition may be classified into two groups they are call by value and call by reference
Call by value
Whenever a portion of the program invokes a function with formal arguments, control will be transferred from the main to the calling function and the value of the actual argument is copied to the function. Within the  function, the actual value is copied from the calling portion of the program may be altered or changed. When  the control is transferred back from the function to the calling portion of the program, the altered values are not transferred back from the function to the calling portion of the program, the altered values are not transferred back. This type of passing formal arguments to a function is technically known as call by value.
main()
{
    int x=100,y=20;
    clrscr();
    printf("Values after swap\n");
    printf(”x=%d”and y=%d”,x,y);
    swap(x,y);
    printf("\nValues after swap\n");
    printf(”x=%d and y=%d”,x,y);
    getch();
}
swap(int a,int b)
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}
Since, the above function is declared call by value, the value is not swapped. As a single variable is transferred to the function, it protects the value of this variable from alteration within the function. On the other hand, it prevents the altered value being transferred back from the function to the calling portion of the program.

Call by Reference
When a portion of a program calls the function, the addresses of the actual arguments are copied on to the formal arguments, though they may be referred by different variable names. The content of the variables that are altered within the function block are returned to the calling portion of the program in the altered form itself, as the formal and actual arguments are referencing the same memory location or address. The technique is known as call by reference or call by adder or call 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 arguments passed by reference(i.e. when a pointer is passed to the function), the address of the data item is passed to the function. The contents of that address can be accessed freely, either within a function or within a calling routine. Moreover, any changes that is made to the data item(i.e. the contents of the address(will be recognized in both the function and the calling portion of the program. Thus, the use of the pointer as function arguments permits the corresponding data item to be altered globally from within the function.

A program to exchange the content of two variables using call by reference
main()
{
    int x=100,y=20;
    clrscr();
    printf("Values before swap\n");
    printf(”x=%d”and y=%d”,x,y);
    swap(&x,&y);
    printf("\nValues after swap\n");
    printf(”x=%d and y=%d”,x,y);
    getch();
}

swap(int *a,int *b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;}

9.3 Pointers and One-dimensional Array
In C and C++, there is a close correspondence between array datatype and pointers. Any array name is C and C++ is very muck like a pointer but there is difference between them. The pointer is variable that can appear on the left side of an assignment operation. The array name is constant and  can’t appear on the left side of an assignment operator. In all the other aspects, both the pointer and the array are the same.

Recall that an array name is really a pointer to the first element in the array. Therefore, if x is a one-dimensional array, then the address of the first array element can be expressed as either &x[0] or simply as 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 array element (i+1) can be expressed as either &x[i] or as (x+i). Thus we have two different ways to write the address of an array element: we can write the actual array element, preceded by an ampersand; or we can write an expression in which the subscript is added to the array name.
Since &x[i] and (x+i) both represent the address of the ith element of x, it would seem reasonable that x[i] and *(x+i) both represent the contents of that address, i.e., the value of the ith element of x. Hence, either term can be used in any particular application.

A program to access the array element using pointer
main()
{
    int myArray[5]={1,2,3,4,5};
    int i;
    for(i=0;i<5;i++)
        printf("%d\t",*(myArray+i));
    getch();
}
OR
main()
{
    int myArray[5]={1,2,3,4,5};
    int i;
    for(i=0;i<5;i++)
        printf("%d\t",myArray[i]);
    getch();
}
In above program, instead of adding i to myArray to step through the array address, we wanted to use the increment operator. Could we write *(myArray++) ? The answer is no, and the reason is that we want increment a constant(or indeed change it in anyway). The expression myArray is the address where the system has chosen to place our array, and it will stay at this address until the program terminates. myArray is constant. We can’t say myArray++ any more though we can the array element of pointer to which it is pointer can be incremented. While we can’t increment an address, we can increment a pointer that holds an address.
main()
{
    int myArray[]={1,2,3,4,5};
    int *ptr2myArray,i;
    clrscr();
    ptr2myArray=myArray;
    for(i=0;i<5;i++)
        printf("%d",*(ptr2myArray++));
    getch();
}
When assigning a value to an array element such as x[i], the left side of the assignment statement 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 that of the array element.
On the other hand, it is sometimes necessary to assign an address to an identifier. In such situations, a pointer variable must appear on the left side of the assignment statement. It is not possible to assign an arbitrary address to an array name or to an array element. Thus, expressions such as x, (x+i) and &x[i] cannot appear on the left side of an assignment statement. Moreover, the address of an array cannot arbitrarily be altered, so that expressions such as ++x are not permitted.
Note that the address of one array element cannot be assigned to some other array element. Thus, we cannot write a statement such as
            &line[2]=&line[1];
On the other hand, we can assign the value of one array element to another through a pointer if we wish,e.g.,
            p1=&line[1];
            line[2]=*p1;
                 OR
            P1=(line+1);
            *(line+2)=*p1;
If a numerical array is defined as a pointer variable, the array elements cannot be assigned initial values. Therefore, a conventional array definition is required if initial values will be assigned to the elements 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 one-dimensional character array or a character pointer.

#include<conio.h>
#include<stdio.h>
char x[]="this is first\n\n";
main()
{
   char y[]="this is second\n";
    printf("%s",x);
    printf("%s",y);
    getch();
}

#include<conio.h>
#include<stdio.h>
char *x="this is first\n\n";
main()
{
   char *y="this is second\n";
    printf("%s",x);
    printf("%s",y);
    getch();
}

Try  Yourself- Example: Finding smallest element of Array using pointer



Dynamic Memory Allocation
Since an array name is actually a pointer to the first element within the array, it should be possible to define the array as a pointer variable rather than as a conventional array. Syntactically, the two definitions are equivalent. However, a conventional array definition results in a fixed block of memory being reserved at the beginning of program execution, whereas this does not occur if the array is represented in terms of a pointer variable.

Using malloc( ) and calloc( ) functions we can allocate memory only at the time of execution. Since these functions allocate memory on the fly(during execution) they are often known as "Dynamic Memory Allocation" functions.

 Therefore, the use of a pointer variable to represent an array requires some type of initial memory assignment before the array elements are processed. This is known as dynamic memory allocation. Generally the malloc library function is used for this purpose, as illustrated in the next example.
Example:
Suppose x is a one-dimensional, 10 element array of intergers. It is possible to define x as a pointer variable rather than an array. Thus, we can write
            int *x;
rather than
            int x[10];
However, x is not automatically assigned a memory block when it is defined as a pointer variable, though a block of memory large enough to store integer quantities will be reserved in advance when x is defined as an array.
To assign sufficient memory for x, we can make use of the library function malloc, as follows.
            x=(int *)malloc(10*sizeof(int));
Since malloc() returns a void pointer, we have to typecast it into apprpriate pointer (as int in above example)
This function reserves a block of memory whose size(in bytes) is equivalent to 10 integer quantities. As written, the function returns a pointer to an integer. This pointer indicates the beginning of the memory block. In general, the type cast preceding malloc must be consistent with the data type of the pointer variable. Thus, if y were defined as a pointer to a double-precesion quantity and we wanted enough memory to store 10 double-precesion quantities, we would write
            y=(double*)malloc(10*sizeof(double));

The calloc( ) function work exactly similar to malloc( ) except for the fact that it needs two arguments.
For example:
            int *x;
            x=(int *)calloc(n,sizeof(int));
Here, sizeof(int) indicates that we wish to allocate memory for storing integers and n indicates that we want to reserve space for storing n integers. Another minor difference between malloc( ) and calloc( ) is that, by default, the memory allocated by malloc( ) contains garbage values, whereas that allocated by calloc( ) contains all zeros.
While using these functions it is necessary to include the file "alloc.h" at the beginning of the program.



Sorting elements of array in ascending order using pointer

#include<stdio.h>
#include<conio.h>
#include<alloc.h>

main()
{
int i,n,*x;
printf("How many nos?");
scanf("%d",&n);
x=(int *)calloc(n,sizeof(int));
for(i=0;i<n;i++)
            scanf("%d",x+i);
for(i=0;i<n;i++)
            printf("%d\t",*(x+i));

for(i=0;i<n-1;i++)
{
  int temp;
  for(j=i+1;j<n;j++)         
    {
            if(*(x+i)>*(x+j))   // This is for ASCENDING ORDER, for DESCENDING use < sign
            {
            temp=*(x+i);
           *(x+i)=*(x+j);
           *(x+j)=temp;
          }
      }
}

for(i=0;i<n;i++)
            printf("%d\t",*(x+i));
getch();
}



9.4 Pointers and Multidimensional Arrays
A two-dimensional array 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. Thus a two-dimensional array declaration can be written as
          data_type (*ptrvar)[expression 2];
rather than
            data_type array[expression 1][expression 2];
This concept can be generalized to higher dimensional arrays; that is,
            data_type (*ptrvar)[expression 2][expression 3] .  . .[expression n];
replaces
            data_type array[expression 1][expression 2]. . . . [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, and expression 1, expression 2, . . . .,expression n are positive-valued integer expressions that indicate the maximum number of array elements associated with each subscript.

Example:
Suppose x is a two-dimensional integer array having 10 rows and 20 columns. We can declare x as
            int (*x)[20];
rather than
            int x[10][20];
In the first 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 (i.e., row 0,x[0]) of the original two-dimensional array. Similarly, (x+1) points to the second 20-element array, which is the second row(row 1) of the original two-dimensional array, and so on, as illustrated in figure:







         x                                     Ist one-dimensional array







     (x+1)                                   2nd one-dimensional array

                        . . . . …………………………………………….







     (x+9)                                   10th  one-dimensional array

The item in row 2, column 5 can be accessed by writing either
            x[2][5]  or *(*(x+2)+5) or *(x[2]+5)
(x+2) is a pointer to row 2. Therefore the object of this pointer, *(x+2), refers to the entire row. Since row 2 is a one dimensional array, *(x+2) is actually a pointer to the first element in row 2. We now add 5 to this pointer. Hence, (*(x+2)+5) is a pointer to element 5 (i.e., the sixth element) in row 2. The object of this pointer, *(*(x+2)+5), therefore refers to the item in coulmn 5 of row 2, which is x[2][5]. These relatinships are illustrated in figure:
           






         x                                     Ist one-dimensional array







       (x+1)                                 2nd one-dimensional array







        (x+2)                                3rd one-dimensional array

                  *(x+2)                                                        *(*(x+2)+5)     *(x+2)+5

Similarly, x[2] refers to the row 2 and x[2]+5 refers to the address of fifth element of row 2. So *(x[2]+5) will give the fifth element of row 2.

Example:
#include<stdio.h>
 #include<conio.h>
 void main()
 {
  int i,j;
  int stud[5][2];
 for(i=0;i<=4;i++)
  {
   for(j=0;j<=1;j++)
     scanf("%d",*(stud+i)+j);
   }

  for(i=0;i<=4;i++)
  {
   printf("\n");
    for(j=0;j<=1;j++)
            printf("%d        ",*(*(stud+i)+j));
    }
    getch();
    }
Array of Pointers
Like array of ints, floatts;we can have 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. All rules that apply to an ordinary array apply in to the array of pointers as well.
Example:
#include<stdio.h>
#include<conio.h>
main()
{
  int *arr[4];
 int i=21,j=5,k=19,l=71,m;
arr[0]=&i;
arr[1]=&j;
arr[2]=&k;
arr[3]=&l;
for(m=0;m<3;m++)
printf("\n%d",*(arr[m]));
getch();
}
Demonstartion of Array of Pointers

Matrix addition using pointer and functions

#include<stdio.h>
#include<conio.h>
#include<alloc.h>

void read(int *b[3]);
void display(int *c[3]);
void add(int *d[3],int *e[3]);
int i,j;

main()
{
int *x[3],*y[3];

//Memory Allocation for first matrix
for(i=0;i<3;i++)
{
x[i]=(int *)malloc(3*sizeof(int));
y[i]=(int *)malloc(3*sizeof(int));
}
printf("Enter the elements of Matrix A:\n");
read(x);
printf("\nContent of A:\n");
display(x);
printf("\nEnter the contents of Matrix B:\n");
read(y);
printf("\nContent of Matrix B:\n");
display(y);
printf("\nResult of addition is:\n");
add(x,y);
getch();
}

void read(int *b[3])
{
for(i=0;i<3;i++)
{
 for(j=0;j<3;j++)
  scanf("%d",*(b+i)+j);
}
}

void display(int *c[3])
{
for(i=0;i<3;i++)
{
 for(j=0;j<3;j++)
  printf("%d\t",*(*(c+i)+j));
 printf("\n");
}
}

void add(int *d[3],int *e[3])
{
 int *c[3];
 for(i=0;i<3;i++)
 c[i]=(int *)malloc(3*sizeof(int));
for(i=0;i<3;i++)
{
 for(j=0;j<3;j++)
   *(*(c+i)+j)=*(*(d+i)+j)+*(*(e+i)+j);
}
printf("\n");
display(c);
}


Passing arrays using pointers
As we passed the variables onto the function based using pointer in the same way arrays are passed as arguments to functions, and their elements being access by the function. However, it’s more common to use pointer notation instead of array notation when arrays are passed to the function.


#define MAX 5
void multiply_array(int *ptr);
main()
{
    int myArray[MAX]={10,12,14,16,18},j;
    clrscr();
    multiply_array(myArray);
    for(j=0;j<MAX;j++)
printf(”myArray[%d]=”,myArray[j]);
    getch();
}

void multiply_array(int *ptr)
{
    int j;
    for(j=0;j<MAX;j++)
        *ptr++ *=2; /*here ptr points to elements of myArray*/
}
9.5 Pointers and strings
Strings are one-dimensional arrays of type char. In C and C++, a string is terminated by NULL or ‘\0’. String constants are written in double quotes. Suppose we want to store "Hello". We may either store it in  a string or we may ask the C compiler to store it at some location in memory and assign the address of the string in a char pointer. This is shown below:
            char str[]="Hello";
            char *p="Hello";
There is a subtle difference in usage of these two forms. For example, we cannot assign a string to another, whereas, we can assign a char pointer to another char pointer. This is shown in the following program.
main( )
{
   char str1[]="Hello";
   char str2[10];
   char *p="Hello";
   char *q;
   str2=str1;  //Error
   q=s;    //Works
   getch();
}
Also, once a string has been defined it can be initialised to another set of characters. Unlike strings, such an operation is perfectly valid with char pointers.
main( )
{
  char str1[]="hello";
  char *p="hello";
  str1="bye";  //Error
  p="bye";  //Works
  getch();
}


Pointer to string constant
Here, the pointer pointers to string constant. Pointer is increased by whom the value is holding.
Example:
main()
{
    char str1[]="This is a string stored in an array";
    char *str2="This is string stored using pointer";
    printf("%s",str1);
    printf("%s",str2);
    str2+=5;
    printf("%s",str2);
    getch();
}
Example:
#include <stdio.h>
#include<conio.h>
void output(char *ptr);
main()
{
    char s[]="I\'m string stored in an array";
    output(s);
    getch();
}
void output(char *ptr)
{
    while(*ptr)
    {
        printf("%c",*ptr++);
    }
}
A program to copy string form one array to another array
void CopyString(char *dest,char *src);
main()
{
    char source[20],destination[20];
    printf("Enter the string:");
    scanf("%s",source);
    CopyString(destination,source);
    printf("%s",destination);
    getch();
}
void CopyString(char *dest, char *src)
{
    while (*src!='\0')
        *dest++=*src++;
    *dest='\0';
}

Example:
main()
{
    char *ptr2array[7]={
                                         "Sunday",
                  "Monday",
                                         "Tuesday",
                                         "Wednesday",
                                         "Thursday",
                                         "Friday",
                                         "Saturday"
                                    };
    int j;
    clrscr();
    for(j=0;j<7;j++)
        printf(”\n%s",ptr2array[j]);
    getch();
}


Pointers and structure
C language allows declaring pointer to structure just like pointer to other ordinary variables. The declaration can be done in the following manner.
struct employee
{
    char *name;
    char *roll_no;
    int salary;
}*emp1;

Above declaration make pointer variable *emp1 of type struct employee. Now, here *emp1 is the pointer to the structure. So while accessing structure members we can use either (*emp1).name or emp1->name. Here, -> is termed as the member access operator for pointers.

Same arithmetic operation can be performed with pointer for structure as for any other datatype. Pointer to structure can perform all the operation that an ordinary pointer can do variables of different datatype.

Example:
#include<stdio.h>
#include<conio.h>
main( )
{
  struct student_record
    {
       char name[25];
       char reg_no[10];
       float average;
       char grade;
     }student[50],*ptr;
/* ptr is a pointer of type structure student_record */
int i,n;
printf("Number of students grades to be computed?");
scanf("%d",&n);
printf("%d",n);
for(i=0;i<n;i++)
{
  printf("\nStudent[%d]information:\n",i+1);
  printf("Name?");
  scanf("%s",student[i].name);
  printf("%s\n",student[i].name);
  printf("Register number?");
 scanf("%s",student[i].reg_no);
 printf("%s\n",student[i].reg_no);
 printf("Average Score?");
 scanf("%f",&student[i].average);
 printf("%8.2f\n",student[i].average);
}
/* pointer 'ptr' points to student[0] */
ptr=student;
/* Assigning grades to 'n' students*/
for(ptr=student;ptr<student+n;ptr++)
{
   if(ptr->average<30.0)
            ptr->grade='D';
 else if(ptr->average<50.0)
            ptr->grade='C';
else if(ptr->average<70.0)
            ptr->grade='B';
else
            ptr->grade='A';
}
/*Displaying Student Records*/
printf("\n");
printf("NAME    REGISTER_NUMBER   AVERAGE   GRADE\n");
printf("…………………………………………………………….\n");
for(ptr=student;ptr<student+n;ptr++)
{
            printf("%-20s%-10s",ptr->name,ptr->reg_no);
            printf("%10.2f %c\n",ptr->average ,ptr->grade);
}
getch();
}

Passing structure to function using reference
Structures may be passed to function either by value or by reference. However, they are usually passed by reference, i.e., the address of the structure is passed to the function. Let us consider the employee for instance.
Example:
#include<stdio.h>
#include<conio.h>
struct book
{
 char name[25];
 char author[25];
 int callno;
};

void display(struct book *);

main()
{
  struct book b1={"Let us C","YK",101};
  display(&b1);
  getch();
}

void display(struct book *b)
{
 printf("\n%s%s%d",ptr->name,ptr->autuor,ptr->callno);
}

Example:
#include<stdio.h>
#include<conio.h>
float grosscalc(struct employee *);

struct employee
{
    char name[20];
    float basic;
    float HRA;
}emp;

main()
{
    float gross;
    clrscr();
    printf("Enter the employee's name:");
    scanf("%s",emp.name);
    fflush(stdin);
    printf("Enter the employee's basic salary:");
    scanf("%f",&emp.basic);
    fflush(stdin);
    printf("Enter the employee's HRA:");
    scanf("%f",&emp.HRA);
    fflush(stdin);
    gross=grosscalc(&emp);
    printf("The employee %s's gross salary is Rs%0.0f",emp.name,gross);
    getch();
}

float grosscalc(struct employee *emp)   /*emp is a pointer of type struct employee*/
{
return(emp->basic+emp->HRA);              /*adds up the employee’s basic and HRA, and returns the result as gross salary*/
}          

Pointer is different from ordinary variable because we can use :
·        In situations when passing actual values is difficult or undesirable
·        To return more than one value from a function.
·        To pass arrays and string conveniently from one function to another.
·        To manipulate arrays more easily by moving pointers to them, instead of moving the arrays themselves
·        To create complex data structures like linked lists and binary tree etc.
·        To allocate the memory as per we need (dynamic memory allocation)


End of Chapter Nine
[ Note: If you have any problems regarding this then you can post the problem in comment box. we will try to solve this here. Or if you know any solution, you can also help :) ]

No comments:

Post a Comment