Interview Preparation topic : Structures and Unions
Structures are user defined datatypes similar to arrays, only they can store elements of different datatypes. These elements in structures are called fields.
Structures are useful to maintain records of various different things where each entity in the record will have common fields.
Declaration of a structure:
struct structure-name
{
datatype variable1;
datatype variable2;
datatype variable3;
…
};
Here, struct is the keyword used to declare a structure with the name structure-name.
Suppose we have to define a point in a two-dimensional plane having some value on the x-coordinate and some on the y-coordinate.
This will be done using the above given syntax:
struct point
{
float x;
float y;
};
Now, we will define a variable with this datatype i.e. struct point:
struct point p1;
We can assign values to the fields of this structure using the following syntax:
p1.x = 1.5;
p1.y = 2;
User defined datatypes are treated the same way as standard datatypes.
Hence, we can perform various operations on this structure which can be performed on any other datatypes like declaring a variable of a datatype(as seen above), initializing a variable of a datatype, passing a datatype to any function or returning that datatype from a function.
Some examples are given below-
Declaring an array of structures:
After defining a structure named point and declaring its variable we will now see how to create an array of these variables.
struct point
{
int x;
int y;
};
struct point pts[10];
for(int i = 0; i < 10; i++)
{
pts[i].x = i ;
pts[i].y = I;
}
This creates an array of struct similar to an array of say int or float.
This array will create a contiguous block of memory with different cells of struct datatype but each cell can have a subfield of its own.
Returning struct from a function:
Similar to functions returning integer values we can have them return a structure.
Here foo is a function with two int parameters and a return type struct.
struct point foo(int x, int y)
{
struct point p1;
p1.x = x;
p1.y = y;
return p1;
}
We will store the struct returned by this function into another variable of similar datatype.
int main()
{
int x, y;
struct point p2;
scanf(“%d%d”,&x,&y);
p2 = foo(x,y);
return 0;
}
Initializing structures:
Initializing a structure is similar to initializing an array, the values to be assigned are entered in curly braces separated by a comma.
But we need to be careful in assigning these values in the same order as the fields in the structure have been declared.
struct point p1 = {1,2};
Pointers to structures:
After declaring a struct and initializing its variable, we now see how to pass a structure as a parameter to a function using a pointer.
This will help optimize your code because now will be able to pass only one pointer instead of an entire struct.
int slope(struct point *p1)
{
int slopeVal = ((*p1).y)/((*p1).x);
return slopeVal;
}
int main()
{
slope(&p1);
return 0;
}
*p1 is a pointer to struct p1. For accessing the fields of p1 we will use *p1.x and *p1.y.
The brackets around *p1 are essential here because we are pointing towards the address of *pr and then take its subfield.
There is an alternative to this in C i.e. p1->x
So, (*p1).x is similar to p1->x
Unions in C
Unions like structures are user defined datatypes having custom fields of different datatypes as created by the user in the same memory location.
But only one member can hold a value at a given time.
The definition and declaration of a Union are done similarly to structures.
Here the keyword used is union.
The value that is initialized the latest will hold true corrupting all the other fields as only one memory location is available.
So, substitution of value to any field will overwrite that memory location and only that field will occupy the location and hold its latest substituted value.
Example:
union Record {
char name[15];
int number;
float val;
};
int main( ) {
union Record myRecord;
myRecord.number = 10;
myRecord.val = 220.5;
strcpy( myRecord.name, "Nancy");
printf( "myRecord.number : %d\n", myRecord.number);
printf( " myRecord.val : %f\n", myRecord.val);
printf( "myRecord.name : %s\n", myRecord.name);
return 0;
}
This will give you the following output on console:
myRecord.number : 1668178254
myRecord.val : 4397336631212735725568.000000
myRecord.name : Nancy
Note, the values of fileds number and val have been corrupted as that memory location is now occupied by the field name containing the string Nancy.
Instead if you just print the values after assigning them you will see that the variables hold those values correctly at that instance.