Structures in C
Structures in C
member definition;
member definition;
...
member definition;
} [one or more structure variables];
The structure tag is optional and each member definition is a normal variable
definition, such as int i; or float f; or any other valid variable definition. At the end of the
structure's definition, before the final semicolon, you can specify one or more structure
variables but it is optional. Here is the way you would declare the Book structure −
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
#include <stdio.h>
#include <string.h>
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( ) {
/* book 1 specification */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali");
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* book 2 specification */
strcpy( Book2.title, "Telecom Billing");
strcpy( Book2.author, "Zara Ali");
strcpy( Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700
Structures as Function Arguments
You can pass a structure as a function argument in the same way as you pass any
other variable or pointer.
Live Demo
#include <stdio.h>
#include <string.h>
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
/* function declaration */
void printBook( struct Books book );
int main( ) {
/* book 1 specification */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali");
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* book 2 specification */
strcpy( Book2.title, "Telecom Billing");
strcpy( Book2.author, "Zara Ali");
strcpy( Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700
Pointers to Structures
You can define pointers to structures in the same way as you define pointer to any
other variable −
struct Books *struct_pointer;
Now, you can store the address of a structure variable in the above defined pointer
variable. To find the address of a structure variable, place the '&'; operator before the
structure's name as follows −
struct_pointer = &Book1;
To access the members of a structure using a pointer to that structure, you must use
the → operator as follows −
struct_pointer->title;
#include <stdio.h>
#include <string.h>
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
/* function declaration */
void printBook( struct Books *book );
int main( ) {
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali");
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* book 2 specification */
strcpy( Book2.title, "Telecom Billing");
strcpy( Book2.author, "Zara Ali");
strcpy( Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700
Bit Fields
Bit Fields allow the packing of data in a structure. This is especially useful when
memory or data storage is at a premium. Typical examples include −
Packing several objects into a machine word. e.g. 1 bit flags can be compacted.
Reading external file formats -- non-standard file formats could be read in, e.g.,
9-bit integers.
C allows us to do this in a structure definition by putting :bit length after the variable.
For example −
struct packed_struct {
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;
Here, the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4-bit type and a
9-bit my_int.
C automatically packs the above bit fields as compactly as possible, provided that the
maximum length of the field is less than or equal to the integer word length of the
computer. If this is not the case, then some compilers may allow memory overlap for
the fields while others would store the next field in the next word.
Nested Structure in C
C provides us the feature of nesting one structure within another structure by using
which, complex data types are created. For example, we may need to store the address
of an entity employee in a structure. The attribute address may also have the subparts
as street number, city, state, and pin code. Hence, to store the address of the
employee, we need to store the address of the employee into a separate structure and
nest the structure address into the structure employee. Consider the following program.
1. #include<stdio.h>
2. struct address
3. {
4. char city[20];
5. int pin;
6. char phone[14];
7. };
8. struct employee
9. {
10. char name[20];
11. struct address add;
12.};
13.void main ()
14.{
15. struct employee emp;
16. printf("Enter employee information?\n");
17. scanf("%s %s %d %s",emp.name,emp.add.city, emp.add.pin, emp.add.phone);
18. printf("Printing the employee information....\n");
19. printf("name: %s\nCity: %s\nPincode: %d\nPhone: %s
",emp.name,emp.add.city,emp.add.pin,emp.add.phone);
20.}
Output
Enter employee information?
Arun
Delhi
110001
1234567890
name: Arun
City: Delhi
Pincode: 110001
Phone: 1234567890
struct node {
int data1;
char data2;
};
int main()
return 0;
}
In the above example ‘link’ is a pointer to a structure of type ‘node’. Hence, the
structure ‘node’ is a self-referential structure with ‘link’ as the referencing
pointer.
An important point to consider is that the pointer should be initialized properly
before accessing, as by default it contains garbage value.
Types of Self Referential Structures
1. Self Referential Structure with Single Link
2. Self Referential Structure with Multiple Links
Self Referential Structure with Single Link: These structures can have only
one self-pointer as their member. The following example will show us how to
connect the objects of a self-referential structure with the single link and access
the corresponding data members. The connection formed is shown in the
following figure.
#include <stdio.h>
struct node {
int data1;
char data2;
int main()
// Initialization
ob1.link = NULL;
ob1.data1 = 10;
ob1.data2 = 20;
// Initialization
ob2.link = NULL;
ob2.data1 = 30;
ob2.data2 = 40;
printf("%d", ob1.link->data1);
printf("\n%d", ob1.link->data2);
return 0;
Output:
30
40
Self Referential Structure with Multiple Links: Self referential structures with
multiple links can have more than one self-pointers. Many complicated data
structures can be easily constructed using these structures. Such structures
can easily connect to more than one nodes at a time. The following example
shows one such structure with more than one links.
The connections made in the above example can be understood using the
following figure.
#include <stdio.h>
struct node {
int data;
};
int main()
// Initialization
ob1.prev_link = NULL;
ob1.next_link = NULL;
ob1.data = 10;
// Initialization
ob2.prev_link = NULL;
ob2.next_link = NULL;
ob2.data = 20;
// Initialization
ob3.prev_link = NULL;
ob3.next_link = NULL;
ob3.data = 30;
// Forward links
ob1.next_link = &ob2;
ob2.next_link = &ob3;
// Backward links
ob2.prev_link = &ob1;
ob3.prev_link = &ob2;
printf("%d\t", ob1.next_link->data);
printf("%d\n", ob1.next_link->next_link->data);
printf("%d\t", ob2.prev_link->data);
printf("%d\t", ob2.data);
printf("%d\n", ob2.next_link->data);
printf("%d\t", ob3.prev_link->prev_link->data);
printf("%d\t", ob3.prev_link->data);
printf("%d", ob3.data);
return 0;
Output:
10 20 30
10 20 30
10 20 30
In the above example we can see that ‘ob1’, ‘ob2’ and ‘ob3’ are three objects of
the self referential structure ‘node’. And they are connected using their links in
such a way that any of them can easily access each other’s data. This is the
beauty of the self referential structures. The connections can be manipulated
according to the requirements of the programmer.
Remember, this keyword adds a new name for some existing data type but
does not create a new type.
Syntax
Using typedef struct results in a cleaner, more readable code, and saves the
programmer keystrokes. However, it also leads to a more cluttered global
namespace which can be problematic for large programs.
#include<stdio.h>
struct Point{
int x;
int y;
};
typedef struct Point Point;
int main() {
Point p1;
p1.x = 1;
p1.y = 3;
printf("%d \n", p1.x);
printf("%d \n", p1.y);
return 0;
}
Output
1
3