Users Online
· Guests Online: 35
· Members Online: 0
· Total Members: 188
· Newest Member: meenachowdary055
· Members Online: 0
· Total Members: 188
· Newest Member: meenachowdary055
Forum Threads
Newest Threads
No Threads created
Hottest Threads
No Threads created
Latest Articles
FAQ: C Structure and Unions
FAQ (Frequently Asked Questions) >C Structure and Unions |
01 What is Basic Difference Between an Array and a Structure in C?
Question: What is Basic Difference Between an Array and a Structure in C?
Answer: Though arrays and structures are composite data structures, they differ in various ways. An array is a sequence of elements of same type in consecutive memory locations. For example,
int balloons[10];
float rainfall[N];
‘balloons’ is an array of 10 integers in consecutive locations. An element of type ‘int’ on Linux takes 4 bytes of storage. Thus, ‘balloons’ is allocated 40 bytes of storage and name ‘balloons’ refers to the beginning of this block; more precisely to the first element. Further, name of an array is a pointer constant that is, for example,
int shots = 10;
int * const pi = &shots; /* 'pi' is a pointer constant */
‘pi’ is a pointer constant keeps pointing to ‘shots’. Likewise, ‘balloons’ can’t be made to point elsewhere, because ‘balloons’ is a fixed address in memory. Expression such as,
balloons += 1;
isn’t valid. Since, ‘balloons’, an array of integers, is a pointer constant or briefly a pointer or address, it can be passed as an argument to a function without need to copy the entire array to function argument. Thus, it allows functions to manipulate on the original values of array elements and not on the copy. For example,
#include <stdio.h>
void disp(const int *, const int);
int main(void)
{
int balloons[5] = {1,2,3,4,5};
disp(balloons, 5);
return 0;
}
void disp(const int *sb, const int count)
{
int i = 0;
while (i < count)
printf("balloons[%d] has %d balloons.n", i++, *(sb + i));
}
Notice that in function disp() we used ‘const’ keyword to prevent function from modifying contents of the array accidentally.
Now, discuss what a structure is? A structure is a data structure that can contain multiple different types of elements. For example,
/* structure declaration */
struct NEW {
int count;
char ch;
float avg;
struct NEW *ptr;
};
The above structure declaration is called structure template or design or pattern. This plays the same role as types ‘int’, ‘char’, ‘float’, etc.. We can, therefore, declare variable of this type, let’s see, how,
int main(void)
{
struct NEW var1, var2;
/* 'var1', 'var2' are two variables of struct NEW */
}
We can also use keyword ‘typedef’ to give new type name of ours’ choice to the above structure declaration as,
/* structure declaration using typedef */
typedef struct NEW {
int count;
char ch;
float avg;
struct NEW *ptr;
} Node;
‘Node’ is new type for the above structure declaration. Let’s declare variables of Node,
int main(void)
{
Node var1, var2; /* 'Node' is new type */
}
Elements comprising the structure declaration are its members. Let’s initialize ‘var1’, a variable of ‘Node’, below,
int main(void)
{
Node var2;
Node var1 = {100, 'K', 67.58, &var2};
}
Let’s access structure ‘var1’ members, using dot ‘.’ operator. Dot ‘.’ is used to access members of a structure variable when it’s known. For example,
var1.count; /* gives value 100 */
var1.ch; /* gives character 'K' */
var1.avg;
Unlike arrays, name of a structure isn’t a pointer constant or address. To pass a structure as a function argument, either pass structure by value or pass pointer to structure. For example,
int main(void)
{
Node var1, var2;
/* passing pointer to structure */
disp(&var1);
}
void disp(Node *p2s) /* 'p2s' is a pointer-to-type-Node*/
{
/* access members of 'var1' using "->" arrow operator */
p2s->count;
p2s->ch;
}
int main(void)
{
Node var1, var2;
/* passing structure by value */
disp(var1);
}
void disp(Node temp) /* 'temp' is a Node structure */
{
/* accessing copies of members of 'var1' using dot operator */
temp.count;
temp.ch;
}
Top
Question: What is Basic Difference Between an Array and a Structure in C?
Answer: Though arrays and structures are composite data structures, they differ in various ways. An array is a sequence of elements of same type in consecutive memory locations. For example,
int balloons[10];
float rainfall[N];
‘balloons’ is an array of 10 integers in consecutive locations. An element of type ‘int’ on Linux takes 4 bytes of storage. Thus, ‘balloons’ is allocated 40 bytes of storage and name ‘balloons’ refers to the beginning of this block; more precisely to the first element. Further, name of an array is a pointer constant that is, for example,
int shots = 10;
int * const pi = &shots; /* 'pi' is a pointer constant */
‘pi’ is a pointer constant keeps pointing to ‘shots’. Likewise, ‘balloons’ can’t be made to point elsewhere, because ‘balloons’ is a fixed address in memory. Expression such as,
balloons += 1;
isn’t valid. Since, ‘balloons’, an array of integers, is a pointer constant or briefly a pointer or address, it can be passed as an argument to a function without need to copy the entire array to function argument. Thus, it allows functions to manipulate on the original values of array elements and not on the copy. For example,
#include <stdio.h>
void disp(const int *, const int);
int main(void)
{
int balloons[5] = {1,2,3,4,5};
disp(balloons, 5);
return 0;
}
void disp(const int *sb, const int count)
{
int i = 0;
while (i < count)
printf("balloons[%d] has %d balloons.n", i++, *(sb + i));
}
Notice that in function disp() we used ‘const’ keyword to prevent function from modifying contents of the array accidentally.
Now, discuss what a structure is? A structure is a data structure that can contain multiple different types of elements. For example,
/* structure declaration */
struct NEW {
int count;
char ch;
float avg;
struct NEW *ptr;
};
The above structure declaration is called structure template or design or pattern. This plays the same role as types ‘int’, ‘char’, ‘float’, etc.. We can, therefore, declare variable of this type, let’s see, how,
int main(void)
{
struct NEW var1, var2;
/* 'var1', 'var2' are two variables of struct NEW */
}
We can also use keyword ‘typedef’ to give new type name of ours’ choice to the above structure declaration as,
/* structure declaration using typedef */
typedef struct NEW {
int count;
char ch;
float avg;
struct NEW *ptr;
} Node;
‘Node’ is new type for the above structure declaration. Let’s declare variables of Node,
int main(void)
{
Node var1, var2; /* 'Node' is new type */
}
Elements comprising the structure declaration are its members. Let’s initialize ‘var1’, a variable of ‘Node’, below,
int main(void)
{
Node var2;
Node var1 = {100, 'K', 67.58, &var2};
}
Let’s access structure ‘var1’ members, using dot ‘.’ operator. Dot ‘.’ is used to access members of a structure variable when it’s known. For example,
var1.count; /* gives value 100 */
var1.ch; /* gives character 'K' */
var1.avg;
Unlike arrays, name of a structure isn’t a pointer constant or address. To pass a structure as a function argument, either pass structure by value or pass pointer to structure. For example,
int main(void)
{
Node var1, var2;
/* passing pointer to structure */
disp(&var1);
}
void disp(Node *p2s) /* 'p2s' is a pointer-to-type-Node*/
{
/* access members of 'var1' using "->" arrow operator */
p2s->count;
p2s->ch;
}
int main(void)
{
Node var1, var2;
/* passing structure by value */
disp(var1);
}
void disp(Node temp) /* 'temp' is a Node structure */
{
/* accessing copies of members of 'var1' using dot operator */
temp.count;
temp.ch;
}
Top
02 What is Difference Between Structure Pattern, Template and Variable in C Language
Question: What is Difference Between Structure Pattern, Template and Variable in C Language?
Answer: Consider the declaration given below,
struct NODE {
struct NODE *link;
int value;
};
The above declaration is called structure template or pattern. This declaration tells compiler, while compiling it, how to store members and makes the computer not to allocate any storage to it. This plays the same role as other types as ‘int’, ‘char’, ‘float’, ‘double’ etc. Here, new type created is ‘struct NODE’.
We know how can we declare and initialize variables of any type, for example,
int junks = 10;
char colour[10] = {'y','e','l','l','o','w'};
float avg;
Likewise, we, firstly, try to create variables of type ‘struct NODE’,
struct NODE current;
struct NODE next = {¤t, 100}; /* next declared and initialized */
Since, ‘next’, a variable of ‘struct NODE’, contains two members viz. ‘link’, a pointer to a variable of type ‘struct NODE’ and an integer. We initialized ‘link’ with address of ‘current’, a variable of ‘struct NODE’ and value as 100.
Since, ‘link’, a member of ‘next’, is a ‘pointer-to-struct NODE’. Such structures are called self-referential structures.
We can use ‘typedef’ keyword to give structure template ‘struct NODE’ a new type name of ours’ choice. Let’s try this, now,
typedef struct NODE {
struct NODE *link;
int value;
} Node;
‘Node’ is created a new type. Now we rewrite the above declarations using ‘Node’ type as,
int main(void)
{
Node current;
Node next = {¤t, 100};
}
Notice also that each type, say ‘int’, ‘char’ or ‘float’ or some other, specifies amount of storage compiler allocates to their variables on a particular machine. Likewise, type ‘Node’ or ‘struct NODE’ specifies amount of storage to its variables on Linux. Use sizeof operator to evaluate size, in bytes, of any variable of type ‘Node’. For example,
size = sizeof(Node);
Top
Question: What is Difference Between Structure Pattern, Template and Variable in C Language?
Answer: Consider the declaration given below,
struct NODE {
struct NODE *link;
int value;
};
The above declaration is called structure template or pattern. This declaration tells compiler, while compiling it, how to store members and makes the computer not to allocate any storage to it. This plays the same role as other types as ‘int’, ‘char’, ‘float’, ‘double’ etc. Here, new type created is ‘struct NODE’.
We know how can we declare and initialize variables of any type, for example,
int junks = 10;
char colour[10] = {'y','e','l','l','o','w'};
float avg;
Likewise, we, firstly, try to create variables of type ‘struct NODE’,
struct NODE current;
struct NODE next = {¤t, 100}; /* next declared and initialized */
Since, ‘next’, a variable of ‘struct NODE’, contains two members viz. ‘link’, a pointer to a variable of type ‘struct NODE’ and an integer. We initialized ‘link’ with address of ‘current’, a variable of ‘struct NODE’ and value as 100.
Since, ‘link’, a member of ‘next’, is a ‘pointer-to-struct NODE’. Such structures are called self-referential structures.
We can use ‘typedef’ keyword to give structure template ‘struct NODE’ a new type name of ours’ choice. Let’s try this, now,
typedef struct NODE {
struct NODE *link;
int value;
} Node;
‘Node’ is created a new type. Now we rewrite the above declarations using ‘Node’ type as,
int main(void)
{
Node current;
Node next = {¤t, 100};
}
Notice also that each type, say ‘int’, ‘char’ or ‘float’ or some other, specifies amount of storage compiler allocates to their variables on a particular machine. Likewise, type ‘Node’ or ‘struct NODE’ specifies amount of storage to its variables on Linux. Use sizeof operator to evaluate size, in bytes, of any variable of type ‘Node’. For example,
size = sizeof(Node);
Top
03 In What Different ways can we Access Members of a Structure in C Language?
Question: In What Different ways can we Access Members of a Structure in C Language?
Answer: A structure, generally, comprises of one or more different types of members. For example,
typedef struct NODE {
struct NODE *link;
int value;
char add[50];
} Node;
Let’s declare variables of ‘Node’ structure below,
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
/* Let's access members of 'next' */
printf("'link' field of 'next' points at address %pn", next.link);
printf("'value' of 'next' is: %dn", next.value);
printf("'add' field of 'next' is: "%s"n", next.add);
}
Observe that we used dot ‘.’ operator to access the members of structure ‘next’. For example, ‘next.link’ is a pointer to ‘current’ ‘Node’ structure and gives address of ‘current’, ‘next.value’ is an integer gives 100, and so on. Observe the output below,
'link' of 'next' points at address 0x7ffff52463f0
'value' of 'next' is: 100
'add' field of 'next' is: "Building No. 100, xyz Lane, Bangalore"
What about if we need to pass ‘next’ ‘Node’ as a function argument. We can pass copy of ‘next’, instead, for example,
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
disp(next);
return 0;
}
void disp(Node new)
{
/* here we process on copy of 'next' 'Node' */
/* any changes made on the copy wouldn't affect the original data */
}
There’s a draw back associated with this approach and that is we, firstly, copied ‘next’ ‘Node’ from calling fun. into formal parameter ‘new’ ‘Node’ even if we needed to perform on just one member of structure. Further worse, any changes made to the copy wouldn’t reflect on original data. To fix this problem, we can return the modified copy back to calling function as,
int main(void)
{
next = disp(next);
return 0;
}
Node disp(Node new)
{
/* here we process on copy of next */
/* any changes made on the copy wouldn't affect the original data */
/* to make changes reflect into calling function */
return new;
}
This approach still not an efficient one as it requires copying Nodes two ways even if just one member is to be manipulated. If we could recall what we had done in case of arrays; we might approach the right trick! Yes! Correct! We need to pass pointer to ‘next’. Let’s see, how?
/*
* struct_mem_using_arrow.c -- program shows use of arrow to access struct
* members
*/
#include <stdio.h>
typedef struct NODE {
struct NODE *link;
int value;
char add[50];
} Node;
void disp(Node *);
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
/* Let's access members of 'next' */
disp(&next);
return 0;
}
void disp(Node *new)
{
printf("'link' points at address: %pn", new->link);
printf("'value' of 'next' is: %dn", new->value);
printf("'add' field of 'next' is: "%s"n", new->add);
}
Notice that we passed pointer to ‘next’ as an argument of function disp() which, as we know, should be received into pointer-to-Node in the function parameter which we declared as ‘new’. Then we used arrow operator ‘->’ to access members of ‘next’ Node. This way, we accessed and manipulated the original members of ‘next’. Note that if function doesn’t need to manipulate the members, use keyword ‘const’ to prevent function from accidentally modifying original data. For example,
void disp(const Node *new)
{
/* process the members */
}
Top
Question: In What Different ways can we Access Members of a Structure in C Language?
Answer: A structure, generally, comprises of one or more different types of members. For example,
typedef struct NODE {
struct NODE *link;
int value;
char add[50];
} Node;
Let’s declare variables of ‘Node’ structure below,
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
/* Let's access members of 'next' */
printf("'link' field of 'next' points at address %pn", next.link);
printf("'value' of 'next' is: %dn", next.value);
printf("'add' field of 'next' is: "%s"n", next.add);
}
Observe that we used dot ‘.’ operator to access the members of structure ‘next’. For example, ‘next.link’ is a pointer to ‘current’ ‘Node’ structure and gives address of ‘current’, ‘next.value’ is an integer gives 100, and so on. Observe the output below,
'link' of 'next' points at address 0x7ffff52463f0
'value' of 'next' is: 100
'add' field of 'next' is: "Building No. 100, xyz Lane, Bangalore"
What about if we need to pass ‘next’ ‘Node’ as a function argument. We can pass copy of ‘next’, instead, for example,
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
disp(next);
return 0;
}
void disp(Node new)
{
/* here we process on copy of 'next' 'Node' */
/* any changes made on the copy wouldn't affect the original data */
}
There’s a draw back associated with this approach and that is we, firstly, copied ‘next’ ‘Node’ from calling fun. into formal parameter ‘new’ ‘Node’ even if we needed to perform on just one member of structure. Further worse, any changes made to the copy wouldn’t reflect on original data. To fix this problem, we can return the modified copy back to calling function as,
int main(void)
{
next = disp(next);
return 0;
}
Node disp(Node new)
{
/* here we process on copy of next */
/* any changes made on the copy wouldn't affect the original data */
/* to make changes reflect into calling function */
return new;
}
This approach still not an efficient one as it requires copying Nodes two ways even if just one member is to be manipulated. If we could recall what we had done in case of arrays; we might approach the right trick! Yes! Correct! We need to pass pointer to ‘next’. Let’s see, how?
/*
* struct_mem_using_arrow.c -- program shows use of arrow to access struct
* members
*/
#include <stdio.h>
typedef struct NODE {
struct NODE *link;
int value;
char add[50];
} Node;
void disp(Node *);
int main(void)
{
Node current;
Node next = {¤t, 100, "Building No. 100, xyz Lane, Bangalore"};
/* Let's access members of 'next' */
disp(&next);
return 0;
}
void disp(Node *new)
{
printf("'link' points at address: %pn", new->link);
printf("'value' of 'next' is: %dn", new->value);
printf("'add' field of 'next' is: "%s"n", new->add);
}
Notice that we passed pointer to ‘next’ as an argument of function disp() which, as we know, should be received into pointer-to-Node in the function parameter which we declared as ‘new’. Then we used arrow operator ‘->’ to access members of ‘next’ Node. This way, we accessed and manipulated the original members of ‘next’. Note that if function doesn’t need to manipulate the members, use keyword ‘const’ to prevent function from accidentally modifying original data. For example,
void disp(const Node *new)
{
/* process the members */
}
Top
04 Explain Self-Referential Structures in C Programming with Examples
This C Tutorial explains Self-Referential Structures in C Programming with examples.
Consider the structure declaration below,
struct NODE {
struct NODE new; /* 'new' declared variable */
int value;
};
As we know that structure template tells compiler how to allocate storage to its members and makes computer not to allocate memory to them. When compiler reaches the line
struct NODE new;
template struct NODE is not fully defined. Further, its member ‘new’ of type struct NODE contains a member ‘new’ of type struct NODE which in turn contains a member ‘new’ again of type struct NODE and so on indefinitely. In such an instance, compiler can’t evaluate correctly how much storage to allocate to ‘new’ member of template struct NODE. So we observed here that a member of struct NODE can’t be a variable of type struct NODE. Then, how can we make structure struct NODE self-referential? Let’s take one more try, this time we declare a ‘pointer-to-struct NODE’ as a member of template struct NODE,
struct NODE {
struct NODE *new; /* 'new' a pointer-to-struct NODE */
int value;
};
As compiler starts compiling the template struct NODE and reaches line
struct NODE *new;
it finds ‘new’, a ‘pointer-to-struct NODE’, and also member of struct NODE template, it evaluates correctly how much bytes of storage to be allocated to ‘new’. On linux system, any pointer type takes 8 bytes of storage. There’s no problem in using ‘pointer-to-struct NODE’ as a member of struct NODE. Because ‘new’ is a ‘pointer-to-struct NODE’, structure struct NODE is called self-referential structure.
typedef struct NODE {
struct NODE *new;
int value;
}Node;
int main(void)
{
Node previous, current;
/* accessing members of 'previous' */
previous.new = ¤t;
/* previous.new is a 'pointer-to-struct NODE' */
previous.value = 100;
}
In above fragment of code, ‘previous.new’ is pointing to ‘current’ Node.
Self-referential structures have their applications in Advanced Data Structures like, Linked Lists, Binary Trees etc..
Top
This C Tutorial explains Self-Referential Structures in C Programming with examples.
Consider the structure declaration below,
struct NODE {
struct NODE new; /* 'new' declared variable */
int value;
};
As we know that structure template tells compiler how to allocate storage to its members and makes computer not to allocate memory to them. When compiler reaches the line
struct NODE new;
template struct NODE is not fully defined. Further, its member ‘new’ of type struct NODE contains a member ‘new’ of type struct NODE which in turn contains a member ‘new’ again of type struct NODE and so on indefinitely. In such an instance, compiler can’t evaluate correctly how much storage to allocate to ‘new’ member of template struct NODE. So we observed here that a member of struct NODE can’t be a variable of type struct NODE. Then, how can we make structure struct NODE self-referential? Let’s take one more try, this time we declare a ‘pointer-to-struct NODE’ as a member of template struct NODE,
struct NODE {
struct NODE *new; /* 'new' a pointer-to-struct NODE */
int value;
};
As compiler starts compiling the template struct NODE and reaches line
struct NODE *new;
it finds ‘new’, a ‘pointer-to-struct NODE’, and also member of struct NODE template, it evaluates correctly how much bytes of storage to be allocated to ‘new’. On linux system, any pointer type takes 8 bytes of storage. There’s no problem in using ‘pointer-to-struct NODE’ as a member of struct NODE. Because ‘new’ is a ‘pointer-to-struct NODE’, structure struct NODE is called self-referential structure.
typedef struct NODE {
struct NODE *new;
int value;
}Node;
int main(void)
{
Node previous, current;
/* accessing members of 'previous' */
previous.new = ¤t;
/* previous.new is a 'pointer-to-struct NODE' */
previous.value = 100;
}
In above fragment of code, ‘previous.new’ is pointing to ‘current’ Node.
Self-referential structures have their applications in Advanced Data Structures like, Linked Lists, Binary Trees etc..
Top
05 What are Mutually Dependent Structures in C?
Question: What are Mutually Dependent Structures in C?
Answer: Two structures, for example, say A and B, are called mutually dependent if one of members of each refers to other structure. For example,
struct A {
struct B b;
int value;
};
struct B {
struct A a;
float wool;
};
Can these structure declarations suffice condition for mutually dependent structures?
Surely, member ‘b’ of struct A refers to struct B while member ‘a’ of struct B refers to struct A. But what happens when you compile the above fragment of code. Compiler gives error as it processes line
struct B b;
and the error is struct B is not known before this line. So, we try to reverse the declarations as,
struct B {
struct A a;
float wool;
};
struct A {
struct B b;
int value;
};
Now, we put struct B declaration before struct A declaration and compiled the fragment of code. Again, same type of error and this is struct A is not known while compiling the line
struct A a;
Should we have used pointer as a member of first struct to refer to second structure
and vice-versa? Let us try this also,
struct B {
struct A *a;
float wool;
};
struct A {
struct B *b;
int value;
};
What about now? There’s no problem to compiler in deciding how much memory to allocate
to member ‘a’ of struct B i.e. in lines
struct B {
struct A *a;
because ‘a’ is a pointer. But ‘a’ is a pointer to struct A and struct A isn’t known to the compiler before this line. Though, struct A declaration is given after struct B declaration, compiler requires it before line
struct A *a;
This is done using concept of Incomplete or partial Declaration. Let us see a simple program to understand mutually dependent structures.
/*
* mutuallydependant.c -- program declares mutually dependent structures
* and access members of first using member of second which is a pointer
* to first
*/
/* program uses concept of Incomplete declarations */
#include <stdio.h>
struct A; /* Partial declaration for struct A */
struct B { /* NEW tag for mem-list */
int roll_no;
float marks;
struct A *p2A; /* 'p2A' is a ptr-to-struct of type A */
};
struct A {
float rain[5];
struct B *p2B; /* 'p2B' is a ptr-to-struct of type B */
char initial;
};
int main(void)
{
int i = 0;
struct B u;
struct A a = {{1.1, 2.43, 2.01, 3.34, 2.213}, &u, 'A'};
struct B b = {44, 58.0, &a};
puts("Lets access members of structure 'a' using pointer member "
"'p2A', pointer to structure 'a' and also a member of "
"structure 'b'n");
/* first member of structure 'a' is 'rain[5]' array */
printf("First member of 'a' is array 'rain of 5 floats': ");
for (i = 0; i < 5; i++)
printf("%.2f ", (b.p2A)->rain[i]);
puts("n");
/* second member of structure 'a' is pointer-to-structB */
printf("Second member of structure 'a' is a pointer to structure"
" 'u' of type struct B,n");
printf("Let us see the address of structure 'u': ");
printf("%p", (b.p2A)->p2B);
puts("n");
printf("Final member of structure 'a' is a character: ");
printf("%c", (b.p2A)->initial);
puts("n");
return 0;
}
Output of the program as follows,
Lets access members of structure 'a' using pointer member 'p2A',
pointer to structure 'a' and also a member of structure 'b'
First member of 'a' is array 'rain of 5 floats': 1.10 2.43 2.01 3.34 2.21
Second member of structure 'a' is a pointer to structure 'u' of type
struct B, Let us see the address of structure 'u': 0x7fff9ce0c020
Final member of structure 'a' is a character: A
Notice that, in above program, we declared incomplete declaration for struct A before struct B declaration letting compiler know there exists struct A declaration somewhere in the program. And compiler now knows how much memory to allocate to pointer member of a struct B referring to struct A and pointer member of struct A referring to struct B. Can you guess what’d happen if we had used variables instead of pointer members in the declarations? Though, it’s simple, better you Try it out!
Further, we accessed members of structure ‘a’ using pointer member ‘p2A’ of structure ‘b’ which is referring to structure ‘a’.
Top
Question: What are Mutually Dependent Structures in C?
Answer: Two structures, for example, say A and B, are called mutually dependent if one of members of each refers to other structure. For example,
struct A {
struct B b;
int value;
};
struct B {
struct A a;
float wool;
};
Can these structure declarations suffice condition for mutually dependent structures?
Surely, member ‘b’ of struct A refers to struct B while member ‘a’ of struct B refers to struct A. But what happens when you compile the above fragment of code. Compiler gives error as it processes line
struct B b;
and the error is struct B is not known before this line. So, we try to reverse the declarations as,
struct B {
struct A a;
float wool;
};
struct A {
struct B b;
int value;
};
Now, we put struct B declaration before struct A declaration and compiled the fragment of code. Again, same type of error and this is struct A is not known while compiling the line
struct A a;
Should we have used pointer as a member of first struct to refer to second structure
and vice-versa? Let us try this also,
struct B {
struct A *a;
float wool;
};
struct A {
struct B *b;
int value;
};
What about now? There’s no problem to compiler in deciding how much memory to allocate
to member ‘a’ of struct B i.e. in lines
struct B {
struct A *a;
because ‘a’ is a pointer. But ‘a’ is a pointer to struct A and struct A isn’t known to the compiler before this line. Though, struct A declaration is given after struct B declaration, compiler requires it before line
struct A *a;
This is done using concept of Incomplete or partial Declaration. Let us see a simple program to understand mutually dependent structures.
/*
* mutuallydependant.c -- program declares mutually dependent structures
* and access members of first using member of second which is a pointer
* to first
*/
/* program uses concept of Incomplete declarations */
#include <stdio.h>
struct A; /* Partial declaration for struct A */
struct B { /* NEW tag for mem-list */
int roll_no;
float marks;
struct A *p2A; /* 'p2A' is a ptr-to-struct of type A */
};
struct A {
float rain[5];
struct B *p2B; /* 'p2B' is a ptr-to-struct of type B */
char initial;
};
int main(void)
{
int i = 0;
struct B u;
struct A a = {{1.1, 2.43, 2.01, 3.34, 2.213}, &u, 'A'};
struct B b = {44, 58.0, &a};
puts("Lets access members of structure 'a' using pointer member "
"'p2A', pointer to structure 'a' and also a member of "
"structure 'b'n");
/* first member of structure 'a' is 'rain[5]' array */
printf("First member of 'a' is array 'rain of 5 floats': ");
for (i = 0; i < 5; i++)
printf("%.2f ", (b.p2A)->rain[i]);
puts("n");
/* second member of structure 'a' is pointer-to-structB */
printf("Second member of structure 'a' is a pointer to structure"
" 'u' of type struct B,n");
printf("Let us see the address of structure 'u': ");
printf("%p", (b.p2A)->p2B);
puts("n");
printf("Final member of structure 'a' is a character: ");
printf("%c", (b.p2A)->initial);
puts("n");
return 0;
}
Output of the program as follows,
Lets access members of structure 'a' using pointer member 'p2A',
pointer to structure 'a' and also a member of structure 'b'
First member of 'a' is array 'rain of 5 floats': 1.10 2.43 2.01 3.34 2.21
Second member of structure 'a' is a pointer to structure 'u' of type
struct B, Let us see the address of structure 'u': 0x7fff9ce0c020
Final member of structure 'a' is a character: A
Notice that, in above program, we declared incomplete declaration for struct A before struct B declaration letting compiler know there exists struct A declaration somewhere in the program. And compiler now knows how much memory to allocate to pointer member of a struct B referring to struct A and pointer member of struct A referring to struct B. Can you guess what’d happen if we had used variables instead of pointer members in the declarations? Though, it’s simple, better you Try it out!
Further, we accessed members of structure ‘a’ using pointer member ‘p2A’ of structure ‘b’ which is referring to structure ‘a’.
Top
06 Explain Structure in C Programming with Examples
This C Tutorial explains Structure and its initialization in C Programming with examples.
In order to declare and initialize a variable of some structure, say struct A, we need to declare structure template first. Structure template plays the same role as type ‘int’, ‘char’ or other types in C language. For example,
typedef struct A {
char a;
int b;
float c;
}sa; /* sa is a new type for the above template */
Template tells the compiler how to allocate storage to its members and makes computer not to store any space to them. List of elements in the template specifies its members. Now we declare variable and initialize them. For example,
/* struct_dec.c -- typedef allows to create new type */
#include <stdio.h>
/* structure declaration */
typedef struct A { /* typedef creates new type */
char surname[15];
int roll_no;
char initial[5];
float marks;
}New;
int main(void)
{
New x = {"smith", 34, "J", 67.38}; /* x is a variable of New */
New y[10]; /* 'y' an array of 10 New elements */
New *pstruct = &x; /* 'pstruct' is a pointer to 'x' */
return 0;
}
Notice that a structure variable is declared like variable of any other type, for example,
int a;
char b;
float c;
int marks[100];
and it’s initialized by writing up member’s values, in order specified in template, and enclosed in a pair of curly braces. For example, in above program,
New x = {"smith", 34, "J", 67.38}; /* 'x' is a variable of New */
Like we do in case of other types as, for example,
int x;
x = 10; /* x is assigned 10 */
Can we do the same with structure variables also? Won’t you like to try this out? For example,
int main(void)
{
New x; /* x is a variable of New */
x = {"smith", 34, "J", 67.38}; /* If this WORKS or FAILS? */
return 0;
}
So, what you noticed? Did this work fine? Or failed? Can you point out the reason of failure?
Top
This C Tutorial explains Structure and its initialization in C Programming with examples.
In order to declare and initialize a variable of some structure, say struct A, we need to declare structure template first. Structure template plays the same role as type ‘int’, ‘char’ or other types in C language. For example,
typedef struct A {
char a;
int b;
float c;
}sa; /* sa is a new type for the above template */
Template tells the compiler how to allocate storage to its members and makes computer not to store any space to them. List of elements in the template specifies its members. Now we declare variable and initialize them. For example,
/* struct_dec.c -- typedef allows to create new type */
#include <stdio.h>
/* structure declaration */
typedef struct A { /* typedef creates new type */
char surname[15];
int roll_no;
char initial[5];
float marks;
}New;
int main(void)
{
New x = {"smith", 34, "J", 67.38}; /* x is a variable of New */
New y[10]; /* 'y' an array of 10 New elements */
New *pstruct = &x; /* 'pstruct' is a pointer to 'x' */
return 0;
}
Notice that a structure variable is declared like variable of any other type, for example,
int a;
char b;
float c;
int marks[100];
and it’s initialized by writing up member’s values, in order specified in template, and enclosed in a pair of curly braces. For example, in above program,
New x = {"smith", 34, "J", 67.38}; /* 'x' is a variable of New */
Like we do in case of other types as, for example,
int x;
x = 10; /* x is assigned 10 */
Can we do the same with structure variables also? Won’t you like to try this out? For example,
int main(void)
{
New x; /* x is a variable of New */
x = {"smith", 34, "J", 67.38}; /* If this WORKS or FAILS? */
return 0;
}
So, what you noticed? Did this work fine? Or failed? Can you point out the reason of failure?
Top
07 How Pointer Arithmetic on Structures Differs from Pointer Arithmetic on Arrays in C Programming
Question: How Pointer Arithmetic on Structures Differs from Pointer Arithmetic on Arrays in C Programming?
Answer: This can better be understood by considering an example,
struct A {
int a;
float b;
char c[3];
};
int main(void)
{
struct A x = {10, 23.33, "hi"};
struct A *p2x = &x; /* 'p2x' is pointing to 'x' */
return 0;
}
Notice that ‘p2x’ is pointing to structure ‘x’. Then exp., for example,
p2x + 1;
results what? We know from pointer’s arithmetic that in exp.
p2x + 1;
1 is adjusted and added to value of ‘p2x’, which results in a value, an address, pointing to location immediately after structure ‘x’. Since, ‘x’ is a scalar and not a vector, therefore, it points to unidentified location. And we can’t know what could be there whether a structure of same type of something else! But if ‘x’ had been an array of structures, exp.
p2x + 1;
would point to next element in the array i.e. next structure. Be careful while writing such expressions because compilers don’t check such restrictions for you.
Notice the last member of ‘x’ is a string “hi”. Let’s access this through ‘p2x’,
p2x->c;
What’s the type of exp. p2x->c? This is character array or we can say it’s pointer to char! And as we know that an array is a pointer constant. This is not a valid L-Value! Let’s consider R-Value of the exp.
p2x->c;
The below exp.
p2x->c[0];
refers to first character ‘h’ of string “hi”, while
p2x->c[1];
refers to ‘i’ in “hi”. Explanation is simple! In exp.
p2x->c[0];
we performed indirection on p2x->c using the subscript value 0. And result is character ‘h’ where pointer p2x->c was pointing to. The equivalent exp. for
p2x->c[0];
could be rewritten as
*(p2x->c + 0);
Top
Question: How Pointer Arithmetic on Structures Differs from Pointer Arithmetic on Arrays in C Programming?
Answer: This can better be understood by considering an example,
struct A {
int a;
float b;
char c[3];
};
int main(void)
{
struct A x = {10, 23.33, "hi"};
struct A *p2x = &x; /* 'p2x' is pointing to 'x' */
return 0;
}
Notice that ‘p2x’ is pointing to structure ‘x’. Then exp., for example,
p2x + 1;
results what? We know from pointer’s arithmetic that in exp.
p2x + 1;
1 is adjusted and added to value of ‘p2x’, which results in a value, an address, pointing to location immediately after structure ‘x’. Since, ‘x’ is a scalar and not a vector, therefore, it points to unidentified location. And we can’t know what could be there whether a structure of same type of something else! But if ‘x’ had been an array of structures, exp.
p2x + 1;
would point to next element in the array i.e. next structure. Be careful while writing such expressions because compilers don’t check such restrictions for you.
Notice the last member of ‘x’ is a string “hi”. Let’s access this through ‘p2x’,
p2x->c;
What’s the type of exp. p2x->c? This is character array or we can say it’s pointer to char! And as we know that an array is a pointer constant. This is not a valid L-Value! Let’s consider R-Value of the exp.
p2x->c;
The below exp.
p2x->c[0];
refers to first character ‘h’ of string “hi”, while
p2x->c[1];
refers to ‘i’ in “hi”. Explanation is simple! In exp.
p2x->c[0];
we performed indirection on p2x->c using the subscript value 0. And result is character ‘h’ where pointer p2x->c was pointing to. The equivalent exp. for
p2x->c[0];
could be rewritten as
*(p2x->c + 0);
Top
08 Explain Nested structure in C with Examples
This C Tutorial explains Nested structure in C with examples and How can we access them.
Let’s see the structure declaration below,
struct A {
int a;
float b;
};
struct B {
int c;
float d;
struct A e;
};
So, what have you noticed here? The member ‘e’ of struct B is itself a structure of type struct A. While being compiled by the compiler, line,
struct A e;
doesn’t put any error. Actually, member ‘e’ of structure B is itself a structure, type struct A, which is already declared before structure type B. Therefore, compiler doesn’t have any problem in evaluating space allocation to member ‘e’ of structure B.
So, we can say that a structure whose member is itself a structure is called a nested structure. Let’s learn to access a nested structure, for example,
#include
/* structure A declared */
typedef struct A {
int a;
float b;
}New_a;
/* structure B declared */
typedef struct B {
int c;
float d;
struct A e; /* member 'e' is itself a structure */
}New_b;
int main(void)
{
/* Let's declare variables of New_a and New_b */
New_a bread;
New_b butter; /* 'butter' is a nested structure */
/* Let's access bread using dot operator */
bread.a = 10; /* assigned member a value 10 */
bread.b = 25.50;
/* Let's access butter using dot operator */
butter.c = 10;
butter.d = 50.00;
/* Let's access member 'e' which is a nested structure */
butter.e.a = 20;
butter.e.b = 20.00;
/* Display values of members of 'butter.e' structure */
printf("butter.e.a is %4d\n", butter.e.a);
printf("butter.e.b is %.2f\n", butter.e.b);
return 0;
}
Output of the above program follows,
butter.e.a is 20
butter.e.b is 20.00
Notice that ‘e’ is a member of structure butter and at the same time it’s a structure of type struct A. Therefore, we used dot operator to access ‘e’ in butter, as,
butter.e
but ‘butter.e’ is a structure of type struct A. struct A has two members viz. an integer and a float. To access these two members of
butter.e
we again used dot operator as,
butter.e.a = 20;
and assigned an integer value 20 to member ‘a’ of butter.e. Similarly, we accessed member ‘b’ of
butter.e
butter.e.b = 20.00;
and assigned it with float value.
Not just this way you can access nested structures. What if we don’t know the structure by name and we have a pointer to structure instead, for example,
New_b *p2b = &butter;
Then, how will you access members of ‘butter’ structure? We can use pointer with indirection as well as arrow operators to access them. Let’s understand difference between using pointer with indirection and arrow operator before we try them out to access members of butter. Notice that exp.
p2b;
is a pointer to ‘butter’ New_b structure. Applying indirection on this, i.e.
*p2b;
results in value where p2b is pointing to. As an R-Value, this is the value of entire structure ‘butter’ which can be thought of as equivalent to structure name ‘butter’. And as an L-Value, this refers to the entire location occupied by ‘butter’; wherein ‘butter’ members can receive new values. Let’s consider the R-Value to access the members of ‘butter’,
(*p2b).member_of_butter;
Notice the parenthesis used around ‘*p2b’. Since dot ‘.’ operator has higher precedence than ‘*’ operator. Parenthesis cause ‘*p2b’ to go first. Then ‘.’ operator selects member of ‘butter’. For example,
(*p2b).c; /* integer member of 'butter' */
Now, we try using arrow ‘->’ operator to access ‘butter’ and its members. Arrow operator has indirection built into it. Therefore, exp.
p2b->c;
means indirection performed on ‘p2b’ and selected member ‘c’ of ‘butter’. We prefer arrow operator because of its convenience. Let’s access members of ‘butter’ using pointer-to-butter rather than by name of ‘butter’,
printf("p2b->c is an integer %d\n", p2b->c);
printf("p2b->d is a float %f\n", p2b->d);
/* 'e' member is a nested structure, let's access this too */
printf("p2b->e.a is an integer %d\n", p2b->e.a);
printf("p2b->e.b is a float %f\n", p2b->e.b);
Let’s understand the expression,
p2b->e.a;
p2b->e selects member ‘e’ of ‘butter’, but ‘e’ is a structure of type struct A. Therefore, exp.
p2b->e
represents a strucute of type struct A. Structure A has two members, an integer and a float. To access their values, we used dot operator, like,
p2b->e.a;
selects integer member of ‘p2b->e’ structure. Likewise, we accessed float member,
p2b->e.b;
Though ‘.’ operator has higher precedence than ‘->’ operator, but their associativity is from left to right. Hence, in exp.
p2b->e.a;
‘p2b->e’ is evaluated first then dot operator gets evaluated.
Top
This C Tutorial explains Nested structure in C with examples and How can we access them.
Let’s see the structure declaration below,
struct A {
int a;
float b;
};
struct B {
int c;
float d;
struct A e;
};
So, what have you noticed here? The member ‘e’ of struct B is itself a structure of type struct A. While being compiled by the compiler, line,
struct A e;
doesn’t put any error. Actually, member ‘e’ of structure B is itself a structure, type struct A, which is already declared before structure type B. Therefore, compiler doesn’t have any problem in evaluating space allocation to member ‘e’ of structure B.
So, we can say that a structure whose member is itself a structure is called a nested structure. Let’s learn to access a nested structure, for example,
#include
/* structure A declared */
typedef struct A {
int a;
float b;
}New_a;
/* structure B declared */
typedef struct B {
int c;
float d;
struct A e; /* member 'e' is itself a structure */
}New_b;
int main(void)
{
/* Let's declare variables of New_a and New_b */
New_a bread;
New_b butter; /* 'butter' is a nested structure */
/* Let's access bread using dot operator */
bread.a = 10; /* assigned member a value 10 */
bread.b = 25.50;
/* Let's access butter using dot operator */
butter.c = 10;
butter.d = 50.00;
/* Let's access member 'e' which is a nested structure */
butter.e.a = 20;
butter.e.b = 20.00;
/* Display values of members of 'butter.e' structure */
printf("butter.e.a is %4d\n", butter.e.a);
printf("butter.e.b is %.2f\n", butter.e.b);
return 0;
}
Output of the above program follows,
butter.e.a is 20
butter.e.b is 20.00
Notice that ‘e’ is a member of structure butter and at the same time it’s a structure of type struct A. Therefore, we used dot operator to access ‘e’ in butter, as,
butter.e
but ‘butter.e’ is a structure of type struct A. struct A has two members viz. an integer and a float. To access these two members of
butter.e
we again used dot operator as,
butter.e.a = 20;
and assigned an integer value 20 to member ‘a’ of butter.e. Similarly, we accessed member ‘b’ of
butter.e
butter.e.b = 20.00;
and assigned it with float value.
Not just this way you can access nested structures. What if we don’t know the structure by name and we have a pointer to structure instead, for example,
New_b *p2b = &butter;
Then, how will you access members of ‘butter’ structure? We can use pointer with indirection as well as arrow operators to access them. Let’s understand difference between using pointer with indirection and arrow operator before we try them out to access members of butter. Notice that exp.
p2b;
is a pointer to ‘butter’ New_b structure. Applying indirection on this, i.e.
*p2b;
results in value where p2b is pointing to. As an R-Value, this is the value of entire structure ‘butter’ which can be thought of as equivalent to structure name ‘butter’. And as an L-Value, this refers to the entire location occupied by ‘butter’; wherein ‘butter’ members can receive new values. Let’s consider the R-Value to access the members of ‘butter’,
(*p2b).member_of_butter;
Notice the parenthesis used around ‘*p2b’. Since dot ‘.’ operator has higher precedence than ‘*’ operator. Parenthesis cause ‘*p2b’ to go first. Then ‘.’ operator selects member of ‘butter’. For example,
(*p2b).c; /* integer member of 'butter' */
Now, we try using arrow ‘->’ operator to access ‘butter’ and its members. Arrow operator has indirection built into it. Therefore, exp.
p2b->c;
means indirection performed on ‘p2b’ and selected member ‘c’ of ‘butter’. We prefer arrow operator because of its convenience. Let’s access members of ‘butter’ using pointer-to-butter rather than by name of ‘butter’,
printf("p2b->c is an integer %d\n", p2b->c);
printf("p2b->d is a float %f\n", p2b->d);
/* 'e' member is a nested structure, let's access this too */
printf("p2b->e.a is an integer %d\n", p2b->e.a);
printf("p2b->e.b is a float %f\n", p2b->e.b);
Let’s understand the expression,
p2b->e.a;
p2b->e selects member ‘e’ of ‘butter’, but ‘e’ is a structure of type struct A. Therefore, exp.
p2b->e
represents a strucute of type struct A. Structure A has two members, an integer and a float. To access their values, we used dot operator, like,
p2b->e.a;
selects integer member of ‘p2b->e’ structure. Likewise, we accessed float member,
p2b->e.b;
Though ‘.’ operator has higher precedence than ‘->’ operator, but their associativity is from left to right. Hence, in exp.
p2b->e.a;
‘p2b->e’ is evaluated first then dot operator gets evaluated.
Top
09 What is Difference in Accessing Structure Members Using Dot ‘.’ and Arrow Operator ‘->’ in C Language
Question: What is Difference in Accessing Structure Members Using Dot ‘.’ and Arrow Operator ‘->’ in C Language?
Answer: We know that we can access structure members in two different ways, one using dot ‘.’ operator and other using arrow ‘->’ operator. Let’s differentiate between two, consider an example,
/* dot_access.c -- program accesses structure members using dot operator */
#include <stdio.h>
/* structure declaration */
typedef struct student {
char srollno[10];
char sclass[10];
char name[25];
char fname[25];
char mname[25];
char add[200];
}Student;
void dot_access(Student const); /* prototype */
int main(void)
{
Student a = {"35M2K14", "cs", "Christine", "James", "Hayek",
"Post Box 1234, Park Avenue, UK"};
printf("Student a Information:\n");
dot_access(a); /* entire 'a' is passed */
return 0;
}
/* entire Student 'a' is copied into Student 'stu' */
/* 'stu' is a variable of Student, not a pointer */
void dot_access(Student const stu)
{
/* Let's access members of 'a' using dot operator */
print("roll no.: %s\n", stu.srollno);
printf("class: %s\n", stu.sclass);
printf("name: %s\n", stu.name);
printf("father's name: %s\n", stu.fname);
printf("mother's name: %s\n", stu.mname);
printf("And address: %s\n", stu.add);
}
Output as below,
Student a Information:
roll no.: 35M2K14
class: cs
name: Christine
father's name: James
mother's name: Hayek
And address: Post Box 1234, Park Avenue, UK
Let’s rewrite above program with access mechanism employed as arrow operator,
/*
* arrow_access.c -- program accesses structure members using arrow operator
*/
#include
typedef struct student {
char srollno[10];
char sclass[10];
char name[25];
char fname[25];
char mname[25];
char add[200];
}Student;
void arrow_access(Student const *); /* prototype */
int main(void)
{
Student a = {"35M2K14", "cs", "Christine", "James", "Hayek",
"Post Box 1234, Park Avenue, UK"};
printf("Student a Information:\n");
arrow_access(&a);
return 0;
}
void arrow_access(Student const *stu) /* 'stu' is a pointer-to-Student */
{
/* Let's access members of 'a' using arrow operator */
printf("roll no.: %s\n", stu->srollno);
printf("class: %s\n", stu->sclass);
printf("name: %s\n", stu->name);
printf("father's name: %s\n", stu->fname);
printf("mother's name: %s\n", stu->mname);
printf("And address: %s\n", stu->add);
}
Output as follows,
Student a Information:
roll no.: 35M2K14
class: cs
name: Christine
father's name: James
mother's name: Hayek
And address: Post Box 1234, Park Avenue, UK
No difference in the result! But which access method is more efficient than other, dot or arrow? As we know from our previous knowledge on Pointers, pointers are more efficient. Let’s try to explore this analytically.
In dot access mechanism, we copied, lump sum 300 bytes, Student ‘a’ from calling function to function parameter. Function parameter ‘stu’ gets copy of Student ‘a’ and performs on this copy. Since, dot_access() only displays information of a Student and not manipulates this. So we used ‘const’ keyword with function parameter to prevent dot_access() function from modifying any information in ‘stu’ Student.
Now, it’s turn to discuss arrow method. Just pointer to Student ‘a’ i.e. &a is copied to the pointer-to-Student ‘*stu’ at called function arrow_access(). Just 8 bytes copied. And using this pointer, we accessed the original contents of Student ‘a’ and displayed information. How about if you have to process just few members of the Student ‘a’? Is passing entire Student ‘a’ more efficient than passing pointer to it? Of course, pointers are more efficient!
Top
Question: What is Difference in Accessing Structure Members Using Dot ‘.’ and Arrow Operator ‘->’ in C Language?
Answer: We know that we can access structure members in two different ways, one using dot ‘.’ operator and other using arrow ‘->’ operator. Let’s differentiate between two, consider an example,
/* dot_access.c -- program accesses structure members using dot operator */
#include <stdio.h>
/* structure declaration */
typedef struct student {
char srollno[10];
char sclass[10];
char name[25];
char fname[25];
char mname[25];
char add[200];
}Student;
void dot_access(Student const); /* prototype */
int main(void)
{
Student a = {"35M2K14", "cs", "Christine", "James", "Hayek",
"Post Box 1234, Park Avenue, UK"};
printf("Student a Information:\n");
dot_access(a); /* entire 'a' is passed */
return 0;
}
/* entire Student 'a' is copied into Student 'stu' */
/* 'stu' is a variable of Student, not a pointer */
void dot_access(Student const stu)
{
/* Let's access members of 'a' using dot operator */
print("roll no.: %s\n", stu.srollno);
printf("class: %s\n", stu.sclass);
printf("name: %s\n", stu.name);
printf("father's name: %s\n", stu.fname);
printf("mother's name: %s\n", stu.mname);
printf("And address: %s\n", stu.add);
}
Output as below,
Student a Information:
roll no.: 35M2K14
class: cs
name: Christine
father's name: James
mother's name: Hayek
And address: Post Box 1234, Park Avenue, UK
Let’s rewrite above program with access mechanism employed as arrow operator,
/*
* arrow_access.c -- program accesses structure members using arrow operator
*/
#include
typedef struct student {
char srollno[10];
char sclass[10];
char name[25];
char fname[25];
char mname[25];
char add[200];
}Student;
void arrow_access(Student const *); /* prototype */
int main(void)
{
Student a = {"35M2K14", "cs", "Christine", "James", "Hayek",
"Post Box 1234, Park Avenue, UK"};
printf("Student a Information:\n");
arrow_access(&a);
return 0;
}
void arrow_access(Student const *stu) /* 'stu' is a pointer-to-Student */
{
/* Let's access members of 'a' using arrow operator */
printf("roll no.: %s\n", stu->srollno);
printf("class: %s\n", stu->sclass);
printf("name: %s\n", stu->name);
printf("father's name: %s\n", stu->fname);
printf("mother's name: %s\n", stu->mname);
printf("And address: %s\n", stu->add);
}
Output as follows,
Student a Information:
roll no.: 35M2K14
class: cs
name: Christine
father's name: James
mother's name: Hayek
And address: Post Box 1234, Park Avenue, UK
No difference in the result! But which access method is more efficient than other, dot or arrow? As we know from our previous knowledge on Pointers, pointers are more efficient. Let’s try to explore this analytically.
In dot access mechanism, we copied, lump sum 300 bytes, Student ‘a’ from calling function to function parameter. Function parameter ‘stu’ gets copy of Student ‘a’ and performs on this copy. Since, dot_access() only displays information of a Student and not manipulates this. So we used ‘const’ keyword with function parameter to prevent dot_access() function from modifying any information in ‘stu’ Student.
Now, it’s turn to discuss arrow method. Just pointer to Student ‘a’ i.e. &a is copied to the pointer-to-Student ‘*stu’ at called function arrow_access(). Just 8 bytes copied. And using this pointer, we accessed the original contents of Student ‘a’ and displayed information. How about if you have to process just few members of the Student ‘a’? Is passing entire Student ‘a’ more efficient than passing pointer to it? Of course, pointers are more efficient!
Top
10 Explain Structure Boundary Alignment in C with Examples
This C Tutorial explains boundary alignment for Structures with examples.
Actually, on certain machines, type ‘int’ is allocated storage which begins at address divisible by 4. Such type ‘int’ is called stringent data type. Because of this restriction structures begin at address required by boundary aligned of the stringent data type. Compiler is forbidden to skip bytes at the beginning of storage allocation to structures. Let’s consider and understand this issue through a simple C program,
/*
* balignment.c -- program displays the concept of boundary alignment with
* structure storage allocation
*/
#include
#include
typedef struct ALIGN1 {
char a;
int b;
char c;
}New1;
typedef struct ALIGN2 {
int b;
char a;
char c;
}New2;
int main(void)
{
unsigned add_x, add_y;
size_t sb;
New1 x = {'a', 10, 'b'};
New2 y = {20, 'c', 'd'};
puts("\n**Concept of Boundary Alignment**\n");
printf("size, in bytes, of New1 structure \'x\' and "
"New2 structure \'y\': %d, %d\n", sizeof(x), sizeof(y));
puts("");
printf("Address where \'x\' begins: %u, and \'y\' begins: %u\n",
&x, &y);
puts("");
printf("Let us access respective positions, from start, of each "
"member in \'x\' and \'y\'...\n");
puts("Positions in \'x\': \n");
sb = offsetof(New1, a);
printf("member \'x.a\' begins at: %d\n", sb);
sb = offsetof(New1, b);
printf("member \'x.b\' begins at: %d\n", sb);
sb = offsetof(New1, c);
printf("member \'x.c\' begins at: %d\n", sb);
puts("");
puts("Positions in \'y\': \n");
sb = offsetof(New2, b);
printf("member \'y.b\' begins at: %d\n", sb);
sb = offsetof(New2, a);
printf("member \'y.a\' begins at: %d\n", sb);
sb = offsetof(New2, c);
printf("member \'y.c\' begins at: %d\n", sb);
puts("");
return 0;
}
Output of the above program is as follows,
**Concept of Boundary Alignment**
size, in bytes, of New1 structure 'x' and New2 structure 'y': 12, 8
Address where 'x' begins: 4097266304, and 'y' begins: 4097266288
Let us access respective positions, from start, of each member in 'x' and
'y'...
Positions in 'x':
member 'x.a' begins at: 0
member 'x.b' begins at: 4
member 'x.c' begins at: 8
Positions in 'y':
member 'y.b' begins at: 0
member 'y.a' begins at: 4
member 'y.c' begins at: 5
Notice that structures ‘x’ and ‘y’ both begin at address divisible by four! Further, notice that structure with member list declaration in which stringent data type is listed first takes less storage than structure in which stringent type is declared after first position. Notice in above program, structures both ‘x’ and ‘y’ have the same member list declaration with members being declared in different order but they are allocated different amount of storage. This is due to boundary alignment required by stringent data type.
Fortunately, there’s a ‘macro’ named offsetof(), defined in header, that we used to determine the respective positions, in bytes, from the beginning of structure, of different members in two structures. And so we can, now, easily calculate why they allocated different storage. Syntax of offsetof() macro is as follows,
size_t offsetof(structure_name, member_name);
First argument is name of structure and second is member of structure whose position is to be determined.
Remember that to reduce memory wastage due to boundary alignment requirement of stringent data type, declare the stringent data type at the top in member list declaration.
Top
This C Tutorial explains boundary alignment for Structures with examples.
Actually, on certain machines, type ‘int’ is allocated storage which begins at address divisible by 4. Such type ‘int’ is called stringent data type. Because of this restriction structures begin at address required by boundary aligned of the stringent data type. Compiler is forbidden to skip bytes at the beginning of storage allocation to structures. Let’s consider and understand this issue through a simple C program,
/*
* balignment.c -- program displays the concept of boundary alignment with
* structure storage allocation
*/
#include
#include
typedef struct ALIGN1 {
char a;
int b;
char c;
}New1;
typedef struct ALIGN2 {
int b;
char a;
char c;
}New2;
int main(void)
{
unsigned add_x, add_y;
size_t sb;
New1 x = {'a', 10, 'b'};
New2 y = {20, 'c', 'd'};
puts("\n**Concept of Boundary Alignment**\n");
printf("size, in bytes, of New1 structure \'x\' and "
"New2 structure \'y\': %d, %d\n", sizeof(x), sizeof(y));
puts("");
printf("Address where \'x\' begins: %u, and \'y\' begins: %u\n",
&x, &y);
puts("");
printf("Let us access respective positions, from start, of each "
"member in \'x\' and \'y\'...\n");
puts("Positions in \'x\': \n");
sb = offsetof(New1, a);
printf("member \'x.a\' begins at: %d\n", sb);
sb = offsetof(New1, b);
printf("member \'x.b\' begins at: %d\n", sb);
sb = offsetof(New1, c);
printf("member \'x.c\' begins at: %d\n", sb);
puts("");
puts("Positions in \'y\': \n");
sb = offsetof(New2, b);
printf("member \'y.b\' begins at: %d\n", sb);
sb = offsetof(New2, a);
printf("member \'y.a\' begins at: %d\n", sb);
sb = offsetof(New2, c);
printf("member \'y.c\' begins at: %d\n", sb);
puts("");
return 0;
}
Output of the above program is as follows,
**Concept of Boundary Alignment**
size, in bytes, of New1 structure 'x' and New2 structure 'y': 12, 8
Address where 'x' begins: 4097266304, and 'y' begins: 4097266288
Let us access respective positions, from start, of each member in 'x' and
'y'...
Positions in 'x':
member 'x.a' begins at: 0
member 'x.b' begins at: 4
member 'x.c' begins at: 8
Positions in 'y':
member 'y.b' begins at: 0
member 'y.a' begins at: 4
member 'y.c' begins at: 5
Notice that structures ‘x’ and ‘y’ both begin at address divisible by four! Further, notice that structure with member list declaration in which stringent data type is listed first takes less storage than structure in which stringent type is declared after first position. Notice in above program, structures both ‘x’ and ‘y’ have the same member list declaration with members being declared in different order but they are allocated different amount of storage. This is due to boundary alignment required by stringent data type.
Fortunately, there’s a ‘macro’ named offsetof(), defined in header, that we used to determine the respective positions, in bytes, from the beginning of structure, of different members in two structures. And so we can, now, easily calculate why they allocated different storage. Syntax of offsetof() macro is as follows,
size_t offsetof(structure_name, member_name);
First argument is name of structure and second is member of structure whose position is to be determined.
Remember that to reduce memory wastage due to boundary alignment requirement of stringent data type, declare the stringent data type at the top in member list declaration.
Top
11 Can a Function in C Obtain Structures as Formal Arguments and Return Structures as Return Values
Question: Can a Function in C Obtain Structures as Formal Arguments and Return Structures as Return Values?
Answer: Of course! A structure is a scalar variable like any other variable and therefore can be used wherever a variable is used. As we know that passing an argument by value in C requires copy of argument to be given to function. This requires entire structure to be copied to stack and discarded later. Let’s consider a simple program, for example,
/*copy_struct.c -- program creates copy of structure */
#include
struct A {
int a;
char b[10];
};
struct A copys(struct A); /* function prototype */
int main(void)
{
struct A x = {10, "hello"};
struct A y;
puts("Accessing y's members before calling to copys() ");
printf("y.a is an integer: %d\n", y.a);
printf("y.b is a string: %s\n", y.b);
puts("");
/* pass 'x' to copy fun. */
y = copys(x);
puts("Accessing y's members after calling copys() ");
printf("y.a is an integer: %d\n", y.a);
printf("y.b is a string: %s\n", y.b);
puts("");
return 0;
}
struct A copys(struct A temp)
{
return temp;
}
Output as follows,
Accessing y's members before calling to copys()
y.a is an integer: 0
y.b is a string:
Accessing y's members after calling to copys()
y.a is an integer: 10
y.b is a string: hello
Notice that we called copys() and passed structure ‘x’ to it; the entire structure copied into function argument ‘temp’, then function without doing something useful on the copy of ‘x’ returned it to calling function. ‘temp’ structure is copied back into structure ‘y’ in the calling program. This way, we copied the entire structure twice. Structure ‘x’ occupies 16 bytes, so, we copied 32 bytes in two way. Of course, this approach gives correct result but this isn’t efficient. Worse it further, if only one member is to be manipulated, why we pass entire structure? Let’s try pointer technique. Unlike arrays, structure name isn’t an address. Instead, pass pointer to structure, for example,
&x; /* pointer to structure 'x' */
We here slightly modified structure declaration as,
struct A {
int a;
char *b;
};
In order to copy structure ‘x’ to structure ‘y’, function call looks like,
void copys(&x, &y);
and function definition becomes,
void copys(struct A const *x, struct A *y)
{
y->a = x->a;
y->b = x->b;
}
And output is as follows,
Accessing y's members before calling to copys()
y.a is an integer: 0
y.b is a string: 1�I��^H��H���PTI���^F@
Accessing y's members after calling to copys()
y.a is an integer: 10
y.b is a string: hello
Notice here that we passed pointer to structure as argument to function, we copied 12
bytes here, then used indirection on pointers to access member’s of two structures and
copied structure ‘x’ directly to structure ‘y’. Now, we can access any or all members of structure. Further, because function worked on original data it didn’t return any value so it’s type is void. In order to prevent copys() from modifying the original contents of structure ‘x’, we used ‘const’ keyword in the function parameter.
So what you observe hare is that it’s always efficient to use pointer to access structures in function rather than passing structure by value. The bigger the structure, more efficient pointer technique is!
The only draw back associated with pointers is that they access original contents of structure directly. There are chances pointer modifies the original content. To prevent this, use ‘const’ keyword!
Top
Question: Can a Function in C Obtain Structures as Formal Arguments and Return Structures as Return Values?
Answer: Of course! A structure is a scalar variable like any other variable and therefore can be used wherever a variable is used. As we know that passing an argument by value in C requires copy of argument to be given to function. This requires entire structure to be copied to stack and discarded later. Let’s consider a simple program, for example,
/*copy_struct.c -- program creates copy of structure */
#include
struct A {
int a;
char b[10];
};
struct A copys(struct A); /* function prototype */
int main(void)
{
struct A x = {10, "hello"};
struct A y;
puts("Accessing y's members before calling to copys() ");
printf("y.a is an integer: %d\n", y.a);
printf("y.b is a string: %s\n", y.b);
puts("");
/* pass 'x' to copy fun. */
y = copys(x);
puts("Accessing y's members after calling copys() ");
printf("y.a is an integer: %d\n", y.a);
printf("y.b is a string: %s\n", y.b);
puts("");
return 0;
}
struct A copys(struct A temp)
{
return temp;
}
Output as follows,
Accessing y's members before calling to copys()
y.a is an integer: 0
y.b is a string:
Accessing y's members after calling to copys()
y.a is an integer: 10
y.b is a string: hello
Notice that we called copys() and passed structure ‘x’ to it; the entire structure copied into function argument ‘temp’, then function without doing something useful on the copy of ‘x’ returned it to calling function. ‘temp’ structure is copied back into structure ‘y’ in the calling program. This way, we copied the entire structure twice. Structure ‘x’ occupies 16 bytes, so, we copied 32 bytes in two way. Of course, this approach gives correct result but this isn’t efficient. Worse it further, if only one member is to be manipulated, why we pass entire structure? Let’s try pointer technique. Unlike arrays, structure name isn’t an address. Instead, pass pointer to structure, for example,
&x; /* pointer to structure 'x' */
We here slightly modified structure declaration as,
struct A {
int a;
char *b;
};
In order to copy structure ‘x’ to structure ‘y’, function call looks like,
void copys(&x, &y);
and function definition becomes,
void copys(struct A const *x, struct A *y)
{
y->a = x->a;
y->b = x->b;
}
And output is as follows,
Accessing y's members before calling to copys()
y.a is an integer: 0
y.b is a string: 1�I��^H��H���PTI���^F@
Accessing y's members after calling to copys()
y.a is an integer: 10
y.b is a string: hello
Notice here that we passed pointer to structure as argument to function, we copied 12
bytes here, then used indirection on pointers to access member’s of two structures and
copied structure ‘x’ directly to structure ‘y’. Now, we can access any or all members of structure. Further, because function worked on original data it didn’t return any value so it’s type is void. In order to prevent copys() from modifying the original contents of structure ‘x’, we used ‘const’ keyword in the function parameter.
So what you observe hare is that it’s always efficient to use pointer to access structures in function rather than passing structure by value. The bigger the structure, more efficient pointer technique is!
The only draw back associated with pointers is that they access original contents of structure directly. There are chances pointer modifies the original content. To prevent this, use ‘const’ keyword!
Top
12 Explain Bit Fields in C Language with Examples
This C Tutorial explains Bit Fields in C Language with examples.
Structures in C are capable of implementing bit fields. Bit fields are declared as other structure declarations with difference that member’s are fields of one or more bits. These variable length fields are stored together in one or more integers. This means that bit fields allow us to access particular fields stored in an integer. Let’s see how can we declare a structure with bit fields,
struct CHAR {
unsigned ch : 7;
unsigned font : 6;
unsigned size : 19;
};
Notice that bit fields are declared as normal structure declaration but with two limitations, first, all member’s (bit fields) are declared to be unsigned and second each member is followed by colon and an integer. Integer specifies no. of bits in a particular field.
Above declaration is from a text formatting program, which uses concept of bit fields to implement several different characteristics of a character viz. no. of characters,
different fonts, and font sizes etc.. Member ‘ch’ takes 7 bits to represent all possible 128 different characters, ‘font’ takes 6 bits to handle all 64 different possibilities and ‘size’ takes 19 bits to suffice for 2 raised to power 19 possibilities. All three bit fields are stored in one integer on machine with word size 32-bits. Let’s create a variable of CHAR structure,
struct CHAR ch1;
On machines with word size of 16-bits, compiler will flag the above declaration as illegal. While on machines with word size of 32 bits, compiler packs them in one integer but in which order i.e. either from left to right or from right to left.
Because of several implementation dependencies, bit fields work differently on different systems. Programs intended to be portable should avoid bit fields. Let’s, first, see these limitations,
1. Since bit fields are type ‘int’. And an ‘int’ can be interpreted as signed or unsigned on particular machine. It’s a better idea to explicitly declare bit fields as unsigned.
2. Order of bit fields in an integer, is either from left to right or from right to left.
3. A bit field declaration on machine with word size of 32-bits may not work on machine with word size of 16-bits.
4. If a declaration specifies two bit fields, and second is too large to fit in the bits left over from the first, compiler can either store the second in next word in memory or immediately after the first with overlapping boundary between memory locations.
Thus far, we have seen how bit fields reduced the memory wastage by packing variable length fields into one or more integers. This savings becomes important when hundreds of such structures are created.
Let’s understand bit fields implementation through a practical example, that might be found in some operating system. The code to operate the floppy disk must communicate with the controller for the disk. Often these device controllers contain several registers, each of which contains many different values all packed together into one integer. A bit field is a convenient way to access the individual values. Let’s have the declaration for one such register, on a machine which allocated bit fields
from right to left, the following declaration would allow easy access to various fields in the register,
struct DISK_REGISTER_FORMAT {
unsigned command : 5;
unsigned sector : 5;
unsigned track : 9;
unsigned error_code : 8;
unsigned head_loaded : 1;
unsigned write_protect : 1;
unsigned disk_spinning : 1;
unsigned error_occurred : 1;
unsigned ready : 1;
};
If this disk register is accessed at the memory address Oxabcfff12, we can define a pointer constant as,
#define DISK_REGISTER ((struct DISK_REGISTER_FORMAT *)Oxabcfff12)
With this preparation, the code needed to actually access the disk register is simple, consider for example,
/*
* tell the controller which sector and track to access and perform read
* operation
*/
DISK_REGISTER->sector = new_sector;
DISK_REGISTER->track = new_track;
DISK_REGISTER->command= READ;
/* wait until READ operation done indicated by 'ready' becoming true */
while (!DISK_REGISTER->ready)
;
/* Now, check for any errors if occurred */
if (DISK_REGISTER->error_occurred)
switch (DISK_REGISTER->error_code) {
/* various cases */
}
So, how beautiful was it that we accessed individual fields in an integer using bit fields concept!
Top
This C Tutorial explains Bit Fields in C Language with examples.
Structures in C are capable of implementing bit fields. Bit fields are declared as other structure declarations with difference that member’s are fields of one or more bits. These variable length fields are stored together in one or more integers. This means that bit fields allow us to access particular fields stored in an integer. Let’s see how can we declare a structure with bit fields,
struct CHAR {
unsigned ch : 7;
unsigned font : 6;
unsigned size : 19;
};
Notice that bit fields are declared as normal structure declaration but with two limitations, first, all member’s (bit fields) are declared to be unsigned and second each member is followed by colon and an integer. Integer specifies no. of bits in a particular field.
Above declaration is from a text formatting program, which uses concept of bit fields to implement several different characteristics of a character viz. no. of characters,
different fonts, and font sizes etc.. Member ‘ch’ takes 7 bits to represent all possible 128 different characters, ‘font’ takes 6 bits to handle all 64 different possibilities and ‘size’ takes 19 bits to suffice for 2 raised to power 19 possibilities. All three bit fields are stored in one integer on machine with word size 32-bits. Let’s create a variable of CHAR structure,
struct CHAR ch1;
On machines with word size of 16-bits, compiler will flag the above declaration as illegal. While on machines with word size of 32 bits, compiler packs them in one integer but in which order i.e. either from left to right or from right to left.
Because of several implementation dependencies, bit fields work differently on different systems. Programs intended to be portable should avoid bit fields. Let’s, first, see these limitations,
1. Since bit fields are type ‘int’. And an ‘int’ can be interpreted as signed or unsigned on particular machine. It’s a better idea to explicitly declare bit fields as unsigned.
2. Order of bit fields in an integer, is either from left to right or from right to left.
3. A bit field declaration on machine with word size of 32-bits may not work on machine with word size of 16-bits.
4. If a declaration specifies two bit fields, and second is too large to fit in the bits left over from the first, compiler can either store the second in next word in memory or immediately after the first with overlapping boundary between memory locations.
Thus far, we have seen how bit fields reduced the memory wastage by packing variable length fields into one or more integers. This savings becomes important when hundreds of such structures are created.
Let’s understand bit fields implementation through a practical example, that might be found in some operating system. The code to operate the floppy disk must communicate with the controller for the disk. Often these device controllers contain several registers, each of which contains many different values all packed together into one integer. A bit field is a convenient way to access the individual values. Let’s have the declaration for one such register, on a machine which allocated bit fields
from right to left, the following declaration would allow easy access to various fields in the register,
struct DISK_REGISTER_FORMAT {
unsigned command : 5;
unsigned sector : 5;
unsigned track : 9;
unsigned error_code : 8;
unsigned head_loaded : 1;
unsigned write_protect : 1;
unsigned disk_spinning : 1;
unsigned error_occurred : 1;
unsigned ready : 1;
};
If this disk register is accessed at the memory address Oxabcfff12, we can define a pointer constant as,
#define DISK_REGISTER ((struct DISK_REGISTER_FORMAT *)Oxabcfff12)
With this preparation, the code needed to actually access the disk register is simple, consider for example,
/*
* tell the controller which sector and track to access and perform read
* operation
*/
DISK_REGISTER->sector = new_sector;
DISK_REGISTER->track = new_track;
DISK_REGISTER->command= READ;
/* wait until READ operation done indicated by 'ready' becoming true */
while (!DISK_REGISTER->ready)
;
/* Now, check for any errors if occurred */
if (DISK_REGISTER->error_occurred)
switch (DISK_REGISTER->error_code) {
/* various cases */
}
So, how beautiful was it that we accessed individual fields in an integer using bit fields concept!
Top
13 Explain Unions in C Language with Examples
This C Tutorial explains Union and its initialization in C Language with examples.
A union is altogether different from structure but declared like structure. For example,
union {
int x;
float y;
char c;
} val;
Notice that in above declaration, union is declared just like structure but amount of memory allocated to union is as large as the largest member of the union. Since, ‘int’ and ‘float’ both take 4 bytes of storage on Linux and ‘char’ takes just 1 byte. Therefore, ‘val’ is allocated 4 bytes of storage. This means that union ‘val’ is allocated enough memory to accommodate the largest member of it.
What about the other member’s of ‘val’? Where else will they be stored? Actually, unions are useful where all member’s of it refer to same memory location but different member’s occupy the same memory at different times. For example,
/* udec.c -- program declares a union and computes it's size */
#include
/* union declaration */
typedef union {
float marks;
char str[20];
int count;
} Record;
int main(void)
{
Record new;
puts("**Program computes size allocated to 'new'**");
printf("%d bytes allocated to 'new' Record.n", sizeof(new));
return 0;
}
Output follows,
**Program computes size allocated to 'new'**
20 bytes allocated to 'new' Record.
Notice that ‘new’ Record is allocated 20 bytes which is size of ‘str’, a charater array, the largest member of ‘new’ Record. Now, this memory can be used by all of the members of ‘new’ but not at the same time. Let’s initialize ‘new’,
Record new = {23.34, "hello", 200};
What do you notice? There’s a warning, when you compile this line, and this is as,
warning: excess elements in union initializer [enabled by default]
This warning is due to the fact that only one member, only first, can initialize the ‘new’ Record. If you initialize ‘new’ Record with value of second or third member, then value gets type cast to type of first member and will be interpreted accordingly.
Okay! We run the program and observe the output below,
**Program computes size allocated to 'new'**
20 bytes allocated to 'new' Record.
Let's access 'new' member's...
new.marks is 23.34
new.str is R��A
new.count is 1102755922
Notice that only first member, ‘marks’, gets the right value. What happened with other two member’s values? Actually, when we had initialized ‘new’, 20 bytes occupied by value of first member ‘marks’ and not by any of other members. When we wished to obtain the value of ‘marks’, bits in that memory location interpreted as float and right value got printed. And when next statement executed, bits in the same location interpreted as a string and finally bits in the same location interpreted as an integer value. Therefore, wrong result for other last two members.
Top
This C Tutorial explains Union and its initialization in C Language with examples.
A union is altogether different from structure but declared like structure. For example,
union {
int x;
float y;
char c;
} val;
Notice that in above declaration, union is declared just like structure but amount of memory allocated to union is as large as the largest member of the union. Since, ‘int’ and ‘float’ both take 4 bytes of storage on Linux and ‘char’ takes just 1 byte. Therefore, ‘val’ is allocated 4 bytes of storage. This means that union ‘val’ is allocated enough memory to accommodate the largest member of it.
What about the other member’s of ‘val’? Where else will they be stored? Actually, unions are useful where all member’s of it refer to same memory location but different member’s occupy the same memory at different times. For example,
/* udec.c -- program declares a union and computes it's size */
#include
/* union declaration */
typedef union {
float marks;
char str[20];
int count;
} Record;
int main(void)
{
Record new;
puts("**Program computes size allocated to 'new'**");
printf("%d bytes allocated to 'new' Record.n", sizeof(new));
return 0;
}
Output follows,
**Program computes size allocated to 'new'**
20 bytes allocated to 'new' Record.
Notice that ‘new’ Record is allocated 20 bytes which is size of ‘str’, a charater array, the largest member of ‘new’ Record. Now, this memory can be used by all of the members of ‘new’ but not at the same time. Let’s initialize ‘new’,
Record new = {23.34, "hello", 200};
What do you notice? There’s a warning, when you compile this line, and this is as,
warning: excess elements in union initializer [enabled by default]
This warning is due to the fact that only one member, only first, can initialize the ‘new’ Record. If you initialize ‘new’ Record with value of second or third member, then value gets type cast to type of first member and will be interpreted accordingly.
Okay! We run the program and observe the output below,
**Program computes size allocated to 'new'**
20 bytes allocated to 'new' Record.
Let's access 'new' member's...
new.marks is 23.34
new.str is R��A
new.count is 1102755922
Notice that only first member, ‘marks’, gets the right value. What happened with other two member’s values? Actually, when we had initialized ‘new’, 20 bytes occupied by value of first member ‘marks’ and not by any of other members. When we wished to obtain the value of ‘marks’, bits in that memory location interpreted as float and right value got printed. And when next statement executed, bits in the same location interpreted as a string and finally bits in the same location interpreted as an integer value. Therefore, wrong result for other last two members.
Top
14 How Unions Differ from Structures in C
Question: How Unions Differ from Structures in C?
Answer: Unions and structures are declared alike but they work differently. Let’s discuss differences between them. Consider the declarations below,
typedef union {
int a;
float b;
char c;
} A_union;
typedef struct {
int a;
float b;
char c;
} B_struct;
Notice here that both ‘A_union’ and ‘B_struct’ have the same member list declaration but storage amount allocated to their variables differs. Not taking into account boundary alignment on certain systems, type ‘B_struct’ allocates 9 bytes to its variables while type ‘A_union’ allocates storage as large as largest member of it that is 4 bytes, since both ‘float’ and ‘int’ takes 4 bytes on Linux machine.
Since storage is allocated to all members in a structure, we can access either or all members at all times. On the contrary, union is allocated storage as the size of largest member of it. Only one member of it can be accessed at a time. Actually, a union is useful where its different members can access the same memory location but at different times. For example,
int main(void)
{
A_union x; /* 'x' is allocated 4 bytes of storage */
x.a = 10; /* accessed this storage as integer */
printf("x.a is an integer: %dn", x.a);
x.b = 23.34; /* accessed the same storage, this time, as 'float' */
printf("x.b is a float: %.2fn", x.b);
x.c = 'A'; /* same storage accessed as character this time */
printf("x.c is a character: %cn", x.c);
return 0;
}
Output of the above program as follows,
Memory allocated to 'x' of type A_union is: 4 bytes.
x.a is an integer: 10
x.b is a float: 23.34
x.c is a character: A
So, what you noticed in the output of above program, same memory location, 4 bytes allocated to ‘x’, is accessed by each of its member’s but at different times.
Let’s see if we can initialize all members of ‘x’, as we had initialized structure members several times earlier,
int main(void)
{
/* initializing all members of 'x' */
A_union x = {10, 23.34, 'A'};
return 0;
}
Output of the program is as follows,
In function ‘main’:
warning: excess elements in union initializer [enabled by default]
warning: (near initialization for ‘x’) [enabled by default]
warning: excess elements in union initializer [enabled by default]
warning: (near initialization for ‘x’) [enabled by default]
Notice here that you can’t initialize all members of union ‘x’ in the same memory location, in just 4 bytes allocated to ‘x’. Does this mean if we can initialize either of the members of ‘x’? Let’s try this also,
int main(void)
{
/* initializing only one member 'x' */
A_union x = {23.34}; /* float value initializing the 'x' */
printf("Memory allocated to 'x' of A_union is: %d bytes.n",
sizeof(x));
puts("");
printf("x.a is an integer: %dn", x.a);
printf("x.b is a float: %.2fn", x.b);
return 0;
}
Let’s analyse the output below,
Memory allocated to 'x' of A_union is: 4 bytes.
x.a is an integer: 23
x.b is a float: 0.00
So, what you noticed here? We tried to initialize the memory location with float value ‘23.34’. Since first member of ‘x’ is an integer, initializer ‘23.34’ implicitly type cast to an integer value ’23’, saved ’23’ into that memory location and printed this when we wished to obtain that value. When bits in the same memory location interpreted as a float value because of ‘%f’ format specifier of next printf statement, a float value ‘0.00’ printed. Actually, integer value ’23’ now in the memory location again type cast to float value and printed as ‘0.00’.
So, we here observed that only the first member of union can be initialized and same memory location can be accessed by all members of union but at different times.
Now, question is where do we use unions and where structures? We’ll see this later.
Top
Question: How Unions Differ from Structures in C?
Answer: Unions and structures are declared alike but they work differently. Let’s discuss differences between them. Consider the declarations below,
typedef union {
int a;
float b;
char c;
} A_union;
typedef struct {
int a;
float b;
char c;
} B_struct;
Notice here that both ‘A_union’ and ‘B_struct’ have the same member list declaration but storage amount allocated to their variables differs. Not taking into account boundary alignment on certain systems, type ‘B_struct’ allocates 9 bytes to its variables while type ‘A_union’ allocates storage as large as largest member of it that is 4 bytes, since both ‘float’ and ‘int’ takes 4 bytes on Linux machine.
Since storage is allocated to all members in a structure, we can access either or all members at all times. On the contrary, union is allocated storage as the size of largest member of it. Only one member of it can be accessed at a time. Actually, a union is useful where its different members can access the same memory location but at different times. For example,
int main(void)
{
A_union x; /* 'x' is allocated 4 bytes of storage */
x.a = 10; /* accessed this storage as integer */
printf("x.a is an integer: %dn", x.a);
x.b = 23.34; /* accessed the same storage, this time, as 'float' */
printf("x.b is a float: %.2fn", x.b);
x.c = 'A'; /* same storage accessed as character this time */
printf("x.c is a character: %cn", x.c);
return 0;
}
Output of the above program as follows,
Memory allocated to 'x' of type A_union is: 4 bytes.
x.a is an integer: 10
x.b is a float: 23.34
x.c is a character: A
So, what you noticed in the output of above program, same memory location, 4 bytes allocated to ‘x’, is accessed by each of its member’s but at different times.
Let’s see if we can initialize all members of ‘x’, as we had initialized structure members several times earlier,
int main(void)
{
/* initializing all members of 'x' */
A_union x = {10, 23.34, 'A'};
return 0;
}
Output of the program is as follows,
In function ‘main’:
warning: excess elements in union initializer [enabled by default]
warning: (near initialization for ‘x’) [enabled by default]
warning: excess elements in union initializer [enabled by default]
warning: (near initialization for ‘x’) [enabled by default]
Notice here that you can’t initialize all members of union ‘x’ in the same memory location, in just 4 bytes allocated to ‘x’. Does this mean if we can initialize either of the members of ‘x’? Let’s try this also,
int main(void)
{
/* initializing only one member 'x' */
A_union x = {23.34}; /* float value initializing the 'x' */
printf("Memory allocated to 'x' of A_union is: %d bytes.n",
sizeof(x));
puts("");
printf("x.a is an integer: %dn", x.a);
printf("x.b is a float: %.2fn", x.b);
return 0;
}
Let’s analyse the output below,
Memory allocated to 'x' of A_union is: 4 bytes.
x.a is an integer: 23
x.b is a float: 0.00
So, what you noticed here? We tried to initialize the memory location with float value ‘23.34’. Since first member of ‘x’ is an integer, initializer ‘23.34’ implicitly type cast to an integer value ’23’, saved ’23’ into that memory location and printed this when we wished to obtain that value. When bits in the same memory location interpreted as a float value because of ‘%f’ format specifier of next printf statement, a float value ‘0.00’ printed. Actually, integer value ’23’ now in the memory location again type cast to float value and printed as ‘0.00’.
So, we here observed that only the first member of union can be initialized and same memory location can be accessed by all members of union but at different times.
Now, question is where do we use unions and where structures? We’ll see this later.
Top