Programming in C - 1BEIT105/205
Module 5
Structures, Unions, Enumerations, and typedef: Structures, Arrays of Structures, Passing Structure to
Functions, Structure Pointers, Arrays and Structures within Structures, Unions, Bit-Fields, Enumerations,
Using sizeof to Ensure Portability, typedef.
Introduction
➤ The C language gives you five ways to create a custom data type:
▪ The structure, which is a grouping of variables under one name and is called an aggregate data type.
▪ The union, which enables the same piece of memory to be defined as two or more different types of
variables.
▪ The bit-field, which is a special type of structure or union element that allows easy access to
individual bits.
▪ The enumeration, which is a list of named integer constants.
▪ The typedef keyword, which defines a new name for an existing type.
➤ Each of these features is described in this chapter.
Structures
➤ A structure is a collection of variables referenced under one name, providing a convenient means
of keeping related information together.
➤ A structure declaration forms a template that can be used to create structure objects (that is,
instances of a structure).
➤ The variables that make up the structure are called members. (Structure members are also
commonly referred to as elements or fields.)
➤ Usually, the members of a structure are logically related. For example, the name and address
information in a mailing list would normally be represented in a structure.
➤ The following code fragment shows how to declare a structure that defines the name and address
fields.
➤ The keyword struct tells the compiler that a structure is being declared.
Programming in C - 1BEIT105/205
struct addr
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
};
The declaration is terminated by a semicolon. This is because a structure declaration is a
statement.
Also, the structure tag addr identifies this particular data structure and is its type specifier.
At this point, no variable has actually been created. Only the form of the data has been defined.
When you declare a structure, you are defining an aggregate type, not a variable.
Not until you declare a variable of that type does one actually exist.
To declare a variable (that is, a physical object) of type addr, write
struct addr addr_info;
➤ This declares a variable of type addr called addr_info. Thus, addr describes the form of a
structure (its type), and addr_info is an instance (an object) of the structure.
➤ When a structure variable (such as addr_info) is declared, the compiler automatically allocates
sufficient memory to accommodate all of its members.
➤ Figure below shows how addr_info appears in memory, assuming 4-byte long integers.
You can also declare one or more objects when you declare a structure. For example,
struct addr {
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_info, binfo, cinfo;
➤ This declares multiple variables (addr_info, binfo, cinfo) of type addr.
Memory representation (approximate):
Name → 30 bytes
Street → 40 bytes
City → 20 bytes
State → 3 bytes
Zip → 4 bytes
Figure 7-1: The addr_info structure in memory
➤ If you only need one structure variable, the structure tag is not needed. This means that
Programming in C - 1BEIT105/205
struct {
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_info;
declares one variable named addr_info as defined by the structure preceding it.
➤ The general form of a structure declaration is
struct tag {
type member-name;
type member-name;
type member-name;
....
} structure-variables;
where either tag or structure-variables may be omitted, but not both.
Accessing Structure Members
➤ The Dot Operator
▪ Individual members of a structure are accessed using the . operator (the dot operator).
▪ General Form: [Link]-name
▪ Example: To assign a value to the zip field of the structure variable addr_info:
addr_info.zip = 12345;
▪ To display the value:
printf("%lu", addr_info.zip);
Strings and Character Access
➤ If a structure member is an array, you can pass it to functions like gets():
gets(addr_info.name);
▪ This passes a character pointer to the start of the name member.
➤ Indexing Individual Elements: To access a specific character within a structure’s array, place the
subscript after the element’s name:
for(t = 0; addr_info.name[t]; ++t)
putchar(addr_info.name[t]);
Programming in C - 1BEIT105/205
➤ Key Distinction: addr_info is the name of the entire structure object.
▪ name is an element of that structure.
➤ Rule: Always index the member, not the structure variable.
Structure Assignments
➤ The information in one structure can be assigned to another structure of the same type using a single
assignment statement.
➤ Benefit: You do not need to assign the value of each member separately.
➤ Example Code:
Here, after the assignment y = x;, all values stored in x are copied into the corresponding members of
y.
#include <stdio.h>
int main(void)
{
struct {
int a;
int b;
} x, y;
x.a = 10;
y = x; /* assign one structure to another */
printf("%d", y.a);
return 0;
}
Output:
10
Task — Syntax Example
Task Syntax Example
Assigning a value [Link] = value;
Reading a value printf("%d", [Link]);
Accessing Array Index [Link][index]
Cloning a Structure struct_B = struct_A;
Quiz Time
Programming in C - 1BEIT105/205
Which keyword is used to define a structure in C?
A) class
B) struct
C) define
D) union
Exam tip:
Always remember the syntax of structures and practice writing small programs. Understanding how to
declare, initialize, and access structure members using the dot (.) operator can help you score easy
marks in exams.
Arrays of Structures
Structures are often arrayed. To declare an array of structures, you must first define a structure and
then declare an array variable of that type. For example, to declare a 100-element array of structures of
type addr defined earlier, write
struct addr addr_list[100];
This creates 100 sets of variables that are organized as defined in the structure addr.
To access a specific structure, index the array name. For example, to print the ZIP code of structure 3,
write
printf("%lu", addr_list[2].zip);
Like all array variables, arrays of structures begin indexing at 0.
To review: When you want to refer to a specific structure within an array of structures, index the
structure array name. When you want to index a specific element of a structure, index the element.
Thus, the following statement assigns 'X' to the first character of name in the third structure of
addr_list.
addr_list[2].name[0] = 'X';
A Mailing List Example
To illustrate how structures and arrays of structures are used, this section develops a simple mailing
list program that uses an array of structures to hold the address information. In this example, the stored
information includes name, street, city, state, and ZIP code.
The address information is held in an array of addr structures, as shown here:
struct addr {
char name[30];
Programming in C - 1BEIT105/205
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_list[MAX];
Notice that the zip field is an unsigned long integer. Frankly, it is more common to store postal codes
using a character string because it accommodates postal codes that use letters as well as numbers (as
used by Canada and other countries). However, this example stores the ZIP code in an integer as a
means of illustrating a numeric structure element.
The first function needed for the program is main(), shown here:
int main(void)
{
char choice;
init_list(); /* initialize the structure array */
for(;;) {
choice = menu_select();
switch(choice) {
case 1: enter();
break;
case 2: delete();
break;
case 3: list();
break;
case 4: exit(0);
}
}
return 0;
}
The function begins by initializing the structure array and then responds to menu selections.
The function init_list() prepares the structure array for use by putting a null character into the first
byte of the name field for each structure in the array. The program assumes that an array element is not
in use if name is empty. The init_list() function is shown here:
/* Initialize the list. */
void initlist(void)
{
register int t;
for(t = 0; t < MAX; ++t)
addr_list[t].name[0] = '\0';
}
The menu_select() function displays the menu and returns the user's selection.
/* Get a menu selection. */
int menu_select(void)
{
char s[80];
int c;
Programming in C - 1BEIT105/205
printf("1. Enter a name\n");
printf("2. Delete a name\n");
printf("3. List the file\n");
printf("4. Quit\n");
do {
printf("\nEnter your choice: ");
gets(s);
c = atoi(s);
} while(c < 0 || c > 4);
return c;
}
The enter() function prompts the user for input and stores the information in the next free structure.
If the array is full, the message List Full is displayed. find_free() searches the structure array for an
unused element.
/* Input addresses into the list. */
void enter(void)
{
int slot;
char s[80];
slot = find_free();
if(slot == -1) {
printf("\nList Full");
return;
}
printf("Enter name: ");
gets(addr_list[slot].name);
printf("Enter street: ");
gets(addr_list[slot].street);
}
printf("Enter city: ");
gets(addr_list[slot].city);
printf("Enter state: ");
gets(addr_list[slot].state);
printf("Enter zip: ");
gets(s);
addr_list[slot].zip = strtoul(s, '\0', 10);
}
/* Find an unused structure. */
int find_free(void)
{
register int t;
for(t = 0; addr_list[t].name[0] && t < MAX; ++t)
;
if(t == MAX) return -1; /* no slots free */
return t;
}
Notice that find_free() returns a −1 if every structure array variable is in use. This is a safe number
because there cannot be a −1 element in an array.
Programming in C - 1BEIT105/205
The delete() function asks the user to specify the index of the address that needs to be deleted. The
function then puts a null character in the first character position of the name field.
/* Delete an address. */
void delete(void)
{
register int slot;
char s[80];
printf("Enter record #: ");
gets(s);
slot = atoi(s);
if(slot >= 0 && slot < MAX)
addr_list[slot].name[0] = '\0';
}
The final function needed by the program is list(), which prints the entire mailing list on the screen.
C does not define a standard function that sends output to the printer because of the wide variation
among computing environments. However, all C compilers provide some means to accomplish this.
You might want to add printing capability to the mailing list program on your own.
/* Display the list on the screen. */
void list(void)
{
register int t;
for(t = 0; t < MAX; ++t) {
if(addr_list[t].name[0]) {
printf("%s\n", addr_list[t].name);
printf("%s\n", addr_list[t].street);
printf("%s\n", addr_list[t].city);
printf("%s\n", addr_list[t].state);
printf("%lu\n\n", addr_list[t].zip);
}
}
printf("\n\n");
}
The complete mailing list program is shown next. If you have any remaining doubts about structures,
enter this program into your computer and study its execution, making changes and watching their
effects.
/* A simple mailing list example using an array of structures. */
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct addr {
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_list[MAX];
Programming in C - 1BEIT105/205
Here is the complete combined C program from all the parts:
/* A simple mailing list example using an array of structures. */
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct addr {
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_list[MAX];
/* Function prototypes */
void init_list(void), enter(void);
void delete(void), list(void);
int menu_select(void), find_free(void);
int main(void)
{
char choice;
init_list(); /* initialize the structure array */
for(;;) {
choice = menu_select();
switch(choice) {
case 1: enter();
break;
case 2: delete();
break;
case 3: list();
break;
case 4: exit(0);
}
}
return 0;
}
/* Initialize the list */
void init_list(void)
{
int t;
for(t = 0; t < MAX; ++t)
addr_list[t].name[0] = '\0';
}
/* Get menu selection */
int menu_select(void)
{
char s[80];
int c;
printf("1. Enter a name\n");
Programming in C - 1BEIT105/205
printf("2. Delete a name\n");
printf("3. List the file\n");
printf("4. Quit\n");
do {
printf("\nEnter your choice: ");
gets(s);
c = atoi(s);
} while(c < 0 || c > 4);
return c;
}
/* Input addresses */
void enter(void)
{
int slot;
char s[80];
slot = find_free();
if(slot == -1) {
printf("\nList Full");
return;
}
printf("Enter name: ");
gets(addr_list[slot].name);
printf("Enter street: ");
gets(addr_list[slot].street);
printf("Enter city: ");
gets(addr_list[slot].city);
printf("Enter state: ");
gets(addr_list[slot].state);
printf("Enter zip: ");
gets(s);
addr_list[slot].zip = strtoul(s, NULL, 10);
}
/* Find free slot */
int find_free(void)
{
int t;
for(t = 0; t < MAX; ++t)
if(addr_list[t].name[0] == '\0')
return t;
return -1;
}
/* Delete address */
void delete(void)
{
int slot;
char s[80];
printf("Enter record #: ");
Programming in C - 1BEIT105/205
gets(s);
slot = atoi(s);
if(slot >= 0 && slot < MAX)
addr_list[slot].name[0] = '\0';
}
/* Display list */
void list(void)
{
int t;
for(t = 0; t < MAX; ++t) {
if(addr_list[t].name[0]) {
printf("%s\n", addr_list[t].name);
printf("%s\n", addr_list[t].street);
printf("%s\n", addr_list[t].city);
printf("%s\n", addr_list[t].state);
printf("%lu\n\n", addr_list[t].zip);
}
}
printf("\n");
}
Sample Output (Example Run)
1. Enter a name
2. Delete a name
3. List the file
4. Quit
Enter your choice: 1
Enter name: John
Enter street: MG Road
Enter city: Bangalore
Enter state: KA
Enter zip: 560001
Enter your choice: 3
John
MG Road
Bangalore
KA
560001
Enter your choice: 4
Recall
Arrays of Structures
➤ Structures are often arrayed.
➤ Declaration:
struct type Variable_name[size_of_array];
Programming in C - 1BEIT105/205
➤ For Example: to declare a 100-element array of structures of type addr defined earlier, write
struct addr addr_list[100];
// This creates 100 sets of variables that are organized as defined in the structure addr.
➤ To access a specific structure, index the array name.
➤ For example, to print the ZIP code of structure 3, write
printf("%lu", addr_list[2].zip);
➤ Like all array variables, arrays of structures begin indexing at 0.
Passing Structure to Functions
➤ There are two passing:
1. Passing Structure Members to Functions
2. Passing Entire Structures to Functions
1. Passing Structure Members to Functions
➤ When you pass a member of a structure to a function, you are passing the value of that member to
the function.
➤ It is irrelevant that the value is obtained from a member of a structure.
➤ For example, consider this structure:
struct fred
{
char x;
int y;
float z;
char s[10];
} mike;
Here are examples of each member being passed to a function:
func(mike.x); /* passes character value of x */
func2(mike.y); /* passes integer value of y */
func3(mike.z); /* passes float value of z */
func4(mike.s); /* passes address of string s */
func(mike.s[2]); /* passes character value of s[2] */
Programming in C - 1BEIT105/205
If you wish to pass the address of an individual structure member, put the & operator before the
structure name. For example, to pass the address of the members of the structure mike, write
func(&mike.x); /* passes address of character x */
func2(&mike.y); /* passes address of integer y */
func3(&mike.z); /* passes address of float z */
func4(mike.s); /* passes address of string s */
func(&mike.s[2]); /* passes address of character s[2] */
Note that the & operator precedes the structure name, not the individual member name. Note also that s
already signifies an address, so no & is required.
2. Passing Entire Structures to Functions
➤ When a structure is used as an argument to a function, the entire structure is passed using the
normal call-by-value method. This means that any changes made to the contents of the parameter
inside the function do not affect the structure passed as the argument.
➤ When using a structure as a parameter, remember that the type of the argument must match the type
of the parameter.
➤ For example, in the following program, both the argument arg and the parameter parm are declared
as the same type of structure.
#include <stdio.h>
/* Define a structure type. */
struct struct_type {
int a, b;
char ch;
};
void f1(struct struct_type parm);
int main(void)
{
struct struct_type arg;
arg.a = 1000;
f1(arg);
return 0;
}
void f1(struct struct_type parm)
{
printf("%d", parm.a);
}
Output:
1000
Programming in C - 1BEIT105/205
➤ When passing structures, the type of the argument must match the type of the parameter.
➤ It is not sufficient for them simply to be physically similar; their type names must match.
➤ For example, the following version of the preceding program is incorrect and will not compile
because the type name of the argument used to call f1() differs from the type name of its parameter.
/* This program is incorrect and will not compile. */
#include <stdio.h>
/* Define a structure type. */
struct struct_type {
int a, b;
char ch;
};
/* Define a structure similar to struct_type,
but with a different name. */
struct struct_type2 {
int a, b;
char ch;
};
void f1(struct struct_type2 parm);
int main(void)
{
struct struct_type arg;
arg.a = 1000;
f1(arg); /* type mismatch */
return 0;
}
void f1(struct struct_type2 parm)
{
printf("%d", parm.a);
}
Why This Program Is Incorrect
➤ Even though both structures have the same data members, they are different types.
➤ In C, structure types are identified by their type names, not by their contents.
➤ f1() expects an argument of type struct struct_type2.
➤ But main() passes an argument of type struct struct_type.
Programming in C - 1BEIT105/205
❌ This causes a type mismatch error, so the program will not compile.
✔ Same structure members ≠ Same structure type
✔ Structure names must match exactly
Structure Pointers
➤ C allows pointers to structures just as it allows pointers to any other type of object.
➤ Declaring a Structure Pointer
Like other pointers, structure pointers are declared by placing * in front of a structure variable’s name.
For example, assuming the previously defined structure addr, the following declares addr_pointer as
a pointer to data of that type:
struct addr *addr_pointer;
Using Structure Pointers
➤ Structure pointers are used to work with structures efficiently
➤ They avoid copying entire structures during function calls
➤ Structure pointers are especially useful for large structures
➤ This topic mainly focuses on passing structures by reference
➤ There are two primary uses of structure pointers:
○ Passing structures to functions using call by reference
○ Creating dynamic data structures (linked lists, etc.)
➤ This chapter covers only call by reference
➤ When structures are passed by value:
• Entire structure is copied
• Data is pushed onto the stack
➤ This creates extra overhead
Programming in C - 1BEIT105/205
➤ Performance reduces when:
• Structure has many members
• Structure contains arrays
➤ Arguments are passed on the stack
Problem with Passing Structures by Value
Passing structures by value is inefficient because the entire structure is copied, leading to extra
memory usage and reduced performance.
➤ Solution – Passing Structure Pointers
• Pass the address of the structure instead of the whole structure
• Only the address is pushed onto the stack
• Results in:
▪ Faster execution
▪ Less memory usage
• Allows functions to modify original structure data
struct bal {
float balance;
char name[80];
} person;
➤ Declaring Structure
▪ person is a structure variable
struct bal *p;
➤ Declaring Structure Pointer
▪ p is a pointer to a structure bal
p = &person;
▪ & operator gives the address of structure variable
▪ Pointer p now points to person
Programming in C - 1BEIT105/205
➤ Use dot operator (.) when using structure variable
➤ Use arrow operator (->) when using structure pointer
For Example:
p->balance;
➤ Arrow operator replaces dot operator when using pointers
➤ Arrow operator (->): Used to access structure members through a pointer
Dot → Structure
Arrow → Structure Pointer
Example Program – Software Timer
Displays hours, minutes, and seconds
• Uses structure pointer to update and display time
• Demonstrates:
▪ Call by reference
▪ Arrow operator usage
▪ Performance efficiency
/* Display a software timer. */
#include <stdio.h>
#define DELAY 128000
struct my_time {
int hours;
int minutes;
int seconds;
};
void display(struct my_time *t);
void update(struct my_time *t);
void delay(void);
int main(void)
{
struct my_time systime;
[Link] = 0;
[Link] = 0;
[Link] = 0;
for(;;) {
update(&systime);
display(&systime);
Programming in C - 1BEIT105/205
return 0;
}
void update(struct my_time *t)
{
t->seconds++;
if(t->seconds == 60) {
t->seconds = 0;
t->minutes++;
}
if(t->minutes == 60) {
t->minutes = 0;
t->hours++;
}
if(t->hours == 24)
t->hours = 0;
delay();
}
void display(struct my_time *t)
{
printf("%02d:", t->hours);
printf("%02d:", t->minutes);
printf("%02d\n", t->seconds);
}
void delay(void)
{
long int t;
/* change this as needed */
for(t = 1; t < DELAY; ++t);
}
✅ Output (Running Example)
00:00:01
00:00:02
00:00:03
00:00:04
...
00:00:59
00:01:00
00:01:01
...
� Important Concepts Used
Structure + Structure Pointer
Arrow operator (->)
Call by reference
Programming in C - 1BEIT105/205
Time logic (seconds → minutes → hours)
Infinite loop (for(;;))
Quiz Time
Which operator is used to access structure members through a structure pointer in C?
A) .
B) ->
C) &
D) *
✅ Correct Answer:
B) ->
Exam Tip:
In programs involving structure pointers, always check:
Use & while passing the structure
Use -> inside the function
Use . when accessing the structure directly
Arrays and Structures within Structures
A member of a structure can be either a simple variable, such as an int or double, or an
aggregate type.
In C, aggregate types are arrays and structures.
A member of a structure that is an array is treated as you might expect from the earlier examples. For
example, consider this structure:
struct x {
int a[10][10]; /* 10 x 10 array of ints */
float b;
} y;
To reference integer 3,7 in a of structure y, write:
y.a[3][7];
Nested Structures
Programming in C - 1BEIT105/205
When a structure is a member of another structure, it is called a nested structure.
For example, the structure address is nested inside emp in this example:
struct emp {
struct addr address; /* nested structure */
float wage;
} worker;
Here, structure emp has been defined as having two members.
The first is a structure of type addr, which contains an employee's address.
The other is wage, which holds the employee's wage.
The following code fragment assigns 93456 to the zip element of address:
[Link] = 93456;
Important Points
The members of each structure are referenced from outermost to innermost.
The C89 standard specifies that structures can be nested to at least 15 levels.
The C99 standard suggests that at least 63 levels of nesting be allowed.
Unions
A union is a memory location that is shared by two or more different types of variables.
A union provides a way of interpreting the same bit pattern in two or more different ways.
Declaring a union is similar to declaring a structure.
General Form
union tag {
type member_name;
type member_name;
type member_name;
...
} union_variables;
Example
union u_type {
int i;
char ch;
};
Unions (Continued)
This declaration does not create any variables.
Programming in C - 1BEIT105/205
You can declare a variable either by placing its name at the end of the declaration or by using a
separate declaration statement.
To declare a union variable called cnvt of type u_type using the definition just given, write:
union u_type cnvt;
In cnvt, both integer i and character ch share the same memory location.
Here, i occupies 2 bytes (assuming 2-byte integers), and ch uses only 1 byte. The figure shows
how i and ch share the same address.
At any point in your program, you can refer to the data stored in cnvt as either an integer or a
character.
Accessing Members of a Union
To access a member of a union, use the same syntax that you would use for structures: the dot (.) and
arrow (->) operators.
If you are operating on the union directly, use the dot operator (.)
If the union is accessed through a pointer, use the arrow operator (->)
For example, to assign the integer 10 to element i of cnvt, write:
cnvt.i = 10;
In the next example, a pointer to cnvt is passed to a function:
void func1(union u_type *un)
{
un->i = 10; /* assign 10 to cnvt through a pointer */
}
Why Use Unions?
Allows access to individual bytes of data
Helpful when altering:
o Precision
o Rounding
o Internal representation
All members share the same memory
Programming in C - 1BEIT105/205
Problem Statement
There is no standard C library function to write a short int directly to a file
fwrite() can be used, but:
o It has excessive overhead
o It is inefficient for a simple operation
We need a simpler and faster solution
Solution
Use a union to break a short int into individual bytes
Write each byte to the file one at a time
This avoids the overhead of fwrite()
This solution assumes:
o short int occupies 2 bytes
union pw {
short int i;
char ch[2];
};
i stores the complete integer
ch[2] accesses the same data byte by byte
Program Flow
Create a function putw()
Accepts a short int
Writes data to a file one byte at a time
Uses putc() internally
#include <stdio.h>
#include <stdlib.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main(void)
{
FILE *fp;
fp = fopen("[Link]", "wb+");
if(fp == NULL) {
printf("Cannot open file.\n");
Programming in C - 1BEIT105/205
exit(1);
}
putw(1025, fp); /* write the value 1025 */
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
union pw word;
word.i = num;
putc([Link][0], fp); /* write first byte */
return putc([Link][1], fp); /* write second byte */
}
Explanation
num → short integer to be written
fp → file pointer
File is opened in binary write mode (wb+)
putw() writes value 1025
File is then closed
Inside putw()
Stores num into union member i
Accesses same data as bytes using ch[]
Writes:
o First byte → [Link][0]
o Second byte → [Link][1]
Key Concept
� Union allows same memory to be accessed as:
Whole integer (i)
Individual bytes (ch[0], ch[1])
How putw() Works
word.i = num stores the integer in memory
Same memory is accessed as a character array
Each byte is written separately using putc()
Even though putw() receives a short int, it uses putc() internally
Programming in C - 1BEIT105/205
Why putc() Can Be Used
putc() writes one character (one byte) to a file
The union allows us to extract individual bytes
This makes putc() suitable for writing integers byte by byte
Advantages of This Method
Avoids overhead of fwrite()
Faster for small data types
Demonstrates low-level file handling
Shows practical use of unions
Bit-Fields
C has a built-in feature, called a bit-field, that allows you to access a single bit.
Bit-fields can be useful for a number of reasons, such as:
o If storage is limited, you can store several Boolean (true/false) variables in one byte.
o Certain devices transmit status information encoded into one or more bits within a byte.
o Certain encryption routines need to access the bits within a byte.
Although these tasks can be performed using the bitwise operators, a bit-field can add more
structure (and possibly efficiency) to your code.
A bit-field must be a member of a structure or union.
It defines how long, in bits, the field is to be.
General Form
type name : length;
Here, type is the type of the bit-field, and length is the number of bits in the field.
The type of a bit-field must be int, signed, or unsigned.
(C99 also allows a bit-field to be of type _Bool.)
Bit-fields are frequently used when analyzing input from a hardware device.
For example, the status port of a serial communications adapter might return a status byte
organized like this:
Example of Bit-Fields (Status Byte)
Programming in C - 1BEIT105/205
Bit-fields are frequently used when analyzing input from a hardware device.
For example, the status port of a serial communications adapter might return a status byte organized
like this:
Bit vs Meaning When Set
Bit Meaning When Set
0 Change in clear-to-send line
1 Change in data-set-ready
2 Trailing edge detected
3 Change in receive line
4 Clear-to-send
5 Data-set-ready
6 Telephone ringing
7 Received signal
Bit-Field Representation
You can represent the above information using a bit-field like this:
struct status_type {
unsigned delta_cts : 1;
unsigned delta_dsr : 1;
unsigned tr_edge : 1;
unsigned delta_rec : 1;
unsigned cts : 1;
unsigned dsr : 1;
unsigned ring : 1;
unsigned rec_line : 1;
} status;
✅ Key Idea
Each field uses 1 bit
Entire structure represents 1 byte (8 bits)
Easy and structured access to individual bits instead of using bitwise operators
Using Bit-Fields in Programs
You might use statements like the ones shown here to enable a program to determine when it can send
or receive data:
status = get_port_status();
if([Link])
printf("clear to send");
Programming in C - 1BEIT105/205
if([Link])
printf("data ready");
Assigning Values to Bit-Fields
To assign a value to a bit-field, simply use the same form you would use for any other structure
element.
For example, this code fragment clears the ring field:
[Link] = 0;
Partial Bit-Field Declaration
You do not have to name each bit-field. This makes it easy to reach the bit you want, bypassing unused
ones.
For example, if you only care about the cts and dsr bits, you could declare the status_type structure
like this:
struct status_type {
unsigned : 4;
unsigned cts : 1;
unsigned dsr : 1;
} status;
Important Note
The bits after dsr do not need to be specified if they are not used.
Restrictions of Bit-Fields
Bit-fields have certain restrictions.
You cannot take the address of a bit-field.
Bit-fields cannot be arrayed.
You cannot know, from machine to machine, whether the fields will run from right to left or
from left to right; this implies that any code using bit-fields may have some machine
dependencies.
Other restrictions may be imposed by various specific implementations.
Summary
Bit-fields help in memory optimization
Unnamed bit-fields skip unused bits
Can be mixed with normal structure members
Bit-fields may have machine dependencies
Programming in C - 1BEIT105/205
Quiz Time
What is the main advantage of using bit-fields in C?
A) Faster program execution
B) Reduced memory usage
C) Easier syntax
D) Automatic error checking
✅ Correct Answer:
B) Reduced memory usage
Exam Tip
Manage your time wisely, answer easy questions first, then move to longer or programming
questions.
This helps you secure quick marks and reduc