Previous | Home | Next |
ADDITIONAL FEATURES OF STRUCTURE
The values of a structure variable can be assigned to another structure variable of the same type using the assignment operator. It is not necessary to copy the structure elements piece-meal. Obviously, programmers prefer assignment to piece-meal copying. This is shown in the following example.
main( )
{ struct employee { char name[10] ; int age ; float salary ; } ; struct employee e1 = { "Sanjay", 30, 5500.50 } ; struct employee e2, e3 ; /* piece-meal copying */ strcpy ( e2.name, e1.name ) ; e2.age = e1.age ; e2.salary = e1.salary ; /* copying all elements at one go */ e3 = e2 ; printf ( "\n%s %d %f", e1.name, e1.age, e1.salary ) ; printf ( "\n%s %d %f", e2.name, e2.age, e2.salary ) ; printf ( "\n%s %d %f", e3.name, e3.age, e3.salary ) ; }; |
Output: The output of the program would be...
Sanjay 30 5500.500000
Sanjay 30 5500.500000
Sanjay 30 5500.500000
Ability to copy the contents of all structure elements of one variable into the corresponding elements of another structure variable is rather surprising, since C does not allow assigning the contents of one array to another just by equating the two. As we saw earlier, for copying arrays we have to copy the contents of the array element by element.
This copying of all structure elements at one go has been possible only because the structure elements are stored in contiguous memory locations.
One structure can be nested within another structure. Using this facility complex data types can be created. The following program shows nested structures at work.
main( )
{ struct address { char phone[15] ; char city[25] ; int pin ; } ; struct emp { char name[25] ; struct address a ; } ; struct emp e = { "jeru", "531046", "nagpur", 10 }; printf ( "\nname = %s phone = %s", e.name, e.a.phone ) ; printf ( "\ncity = %s pin = %d", e.a.city, e.a.pin ) ; }; |
Output: output of the above program
name = jeru phone = 531046
city = nagpur pin = 10
Notice the method used to access the element of a structure that is part of another structure. For this the dot operator is used twice, as in the expression,
e.a.pin or e.a.city
Of course, the nesting process need not stop at this level. We can nest a structure within a structure, within another structure, for example:
maruti.engine.bolt.large.qty
Like an ordinary variable, a structure variable can also be passed to a function. We may either pass individual structure elements or the entire structure variable at one go. Let us examine both the approaches one by one using suitable programs.
/* Passing individual structure elements */
main( ) { struct book { char name[25] ; char author[25] ; int callno ; } ; struct book b1 = { "Let us C", "YPK", 101 } ; display ( b1.name, b1.author, b1.callno ) ; } display ( char *s, char *t, int n ) { printf ( "\n%s %s %d", s, t, n ) ; } |
Output: output of the
above program
Let us C YPK 101
Observe that in the declaration of the structure, name and
author have been declared as arrays. Therefore, when we call the function display( ) using,
display ( b1.name, b1.author, b1.callno ) ; |
we are passing the base addresses of the arrays name and author, but the value stored in callno. Thus, this is a mixed call—a call by reference as well as a call by value. It can be immediately realized that to pass individual elements would become more tedious as the number of structure elements go on increasing. A better way would be to pass the entire structure variable at a time. This method is shown in the following program.
struct book
{ char name[25] ; char author[25] ; int callno ; } ; main( ) { struct book b1 = { "Let us C", "YPK", 101 } ; display ( b1 ) ; } display ( struct book b ) { printf ( "\n%s %s %d", b.name, b.author, b.callno ) ; }; |
Output: output of the
above program
Note that here the calling of function display( ) becomes quite compact,
display ( b1 );
Having collected what is being passed to the display( ) function, the question comes, how do we define the formal arguments in the function. We cannot say,
struct book b1;
because the data type struct book is not known to the function display( ). Therefore, it becomes necessary to define the structure type struct book outside main( ), so that it becomes known to all functions in the program. The way we can have a pointer pointing to an int, or a pointer pointing to a char, similarly we can have a pointer pointing to a struct. Such pointers are known as ‘structure pointers’.
Let us look at a program that demonstrates the usage of a structure pointer.
main( )
{ struct book { char name[25] ; char author[25] ; int callno ; } ; struct book b1 = { "Let us C", "YPK", 101 } ; struct book *ptr ; ptr = &b1 ; printf ( "\n%s %s %d", b1.name, b1.author, b1.callno ) ; printf ( "\n%s %s %d", ptr->name, ptr->author, ptr->callno ) ; } |
The first printf( ) is as usual. The second printf( )
however is peculiar. We can’t use ptr.name or ptr.callno because ptr is not a structure variable but a pointer to a structure, and
the dot operator requires a structure variable on its left. In such cases C
provides an operator ->, called an arrow operator to refer to the structure
elements. Remember that on the left hand side of the ‘.’ structure operator,
there must always be a structure variable, whereas on the left hand side of the
‘->’ operator there must always be a pointer to a structure.
/* Passing address of a structure variable */
struct book { char name[25] ; char author[25] ; int callno ; } ; main( ) { struct book b1 = { "Let us C", "YPK", 101 } ; display ( &b1 ) ; } display ( struct book *b ) { printf ( "\n%s %s %d", b->name, b->author, b->callno ) ; } |
And here is the output...
Let us C YPK 101
Again note that to access the structure elements using pointer to a structure we have to use the ‘->’ operator. Also, the structure struct book should be declared outside main( ) such that this data type is available to display( ) while declaring pointer to the structure.
Consider the following code snippet:
struct emp
{ int a ; char ch ; float s ; } ; struct emp e ; printf ( "%u %u %u", &e.a, &e.ch, &e.s ) ; |
If we execute this program using TC/TC++ compiler we get the addresses as:
65518 65520 65521
Previous | Home | Next |