C Structures
Structures in C are one of the most powerful features of the language that allow programmers to create custom data types by grouping variables of different data types together. They provide a way to organize related data elements, making your code more organized and readable.
What Are Structures?
A structure in C is a composite data type that defines a grouped list of variables to be placed under one name in a block of memory. These variables, known as members, can have different data types and are allocated memory in sequential order.
struct Student {
char name[50];
int roll_number;
float marks;
};
In this example, Student
is a structure containing three members: name
, roll_number
, and marks
.
Defining a Structure
The general syntax for defining a structure is:
struct tag_name {
data_type member1;
data_type member2;
...
data_type memberN;
};
Where:
tag_name
is the name of the structure (optional)member1
,member2
, etc. are the member variables- Each member can have any valid C data type (including other structures)
Declaring Structure Variables
You can declare structure variables in several ways:
Method 1: After Structure Definition
struct Student {
char name[50];
int roll_number;
float marks;
};
struct Student student1, student2; // Declaring two variables of type struct Student
Method 2: During Structure Definition
struct Student {
char name[50];
int roll_number;
float marks;
} student1, student2;
Method 3: Using Typedef
typedef struct {
char name[50];
int roll_number;
float marks;
} Student;
Student student1, student2; // No need for 'struct' keyword
Accessing Structure Members
To access the members of a structure, we use the dot operator (.
):
student1.roll_number = 101;
strcpy(student1.name, "John Doe");
student1.marks = 91.5;
printf("Student Name: %s\n", student1.name);
printf("Roll Number: %d\n", student1.roll_number);
printf("Marks: %.2f\n", student1.marks);
Structure Initialization
Structures can be initialized in different ways:
Method 1: Member-by-Member
struct Student student1;
strcpy(student1.name, "John Doe");
student1.roll_number = 101;
student1.marks = 91.5;
Method 2: Using Initializer List
struct Student student1 = {"John Doe", 101, 91.5};
Method 3: Designated Initializers (C99 and later)
struct Student student1 = {
.name = "John Doe",
.roll_number = 101,
.marks = 91.5
};
Structures and Functions
Passing Structures to Functions
You can pass structures to functions by value or by reference:
Pass by Value
void displayStudent(struct Student s) {
printf("Name: %s\n", s.name);
printf("Roll Number: %d\n", s.roll_number);
printf("Marks: %.2f\n", s.marks);
}
// Function call
displayStudent(student1);
Pass by Reference
void updateMarks(struct Student *s, float new_marks) {
s->marks = new_marks; // Using arrow operator
}
// Function call
updateMarks(&student1, 95.0);
When passing structures by reference, we use the arrow operator (->
) to access structure members.
Returning Structures from Functions
struct Student createStudent(char name[], int roll, float marks) {
struct Student temp;
strcpy(temp.name, name);
temp.roll_number = roll;
temp.marks = marks;
return temp;
}
// Function call
struct Student newStudent = createStudent("Jane Doe", 102, 89.5);
Structure Pointers
A pointer to a structure can be declared and used as follows:
struct Student *ptr_student;
ptr_student = &student1;
// Accessing members using pointer
printf("Name: %s\n", ptr_student->name);
printf("Roll Number: %d\n", ptr_student->roll_number);
The arrow operator (->
) is used to access structure members via a pointer.
Nested Structures
Structures can contain other structures as members:
struct Date {
int day;
int month;
int year;
};
struct Student {
char name[50];
int roll_number;
struct Date dob; // Nested structure
};
// Usage
struct Student student1;
student1.dob.day = 15;
student1.dob.month = 8;
student1.dob.year = 2000;
Self-Referential Structures
A structure that contains a pointer to the same structure type is called a self-referential structure:
struct Node {
int data;
struct Node *next; // Pointer to the same structure type
};
This is the foundation for linked data structures like linked lists, trees, and graphs.
Memory Padding and Structure Packing
The C compiler may add padding between structure members to ensure proper memory alignment:
struct Example {
char c; // 1 byte
// 3 bytes padding might be added here
int i; // 4 bytes
char d; // 1 byte
// 3 bytes padding might be added here
};
To control padding, you can use compiler-specific directives like #pragma pack
or use the attribute __attribute__((packed))
in GCC.
Practical Example
Let's put everything together with a practical example:
#include <stdio.h>
#include <string.h>
struct Address {
char street[50];
char city[30];
int zip;
};
struct Employee {
int id;
char name[50];
float salary;
struct Address addr;
};
void displayEmployee(struct Employee emp) {
printf("Employee ID: %d\n", emp.id);
printf("Name: %s\n", emp.name);
printf("Salary: $%.2f\n", emp.salary);
printf("Address: %s, %s - %d\n",
emp.addr.street, emp.addr.city, emp.addr.zip);
}
int main() {
struct Employee emp1 = {
.id = 1001,
.name = "John Smith",
.salary = 75000.0,
.addr = {
.street = "123 Main St",
.city = "Boston",
.zip = 02115
}
};
displayEmployee(emp1);
return 0;
}
Best Practices
- Use meaningful names for structures and their members
- Consider using typedef to create more readable code
- Be aware of memory alignment and padding in performance-critical applications
- When passing large structures to functions, use pointers to avoid unnecessary copying
- Initialize structures properly to avoid undefined behavior
- Use designated initializers (C99) for better readability
Summary
Structures in C provide a powerful way to create custom data types by grouping related data items together. They are essential for creating complex data structures and organizing your code in a meaningful way. Understanding structures is crucial for advanced C programming and is a foundation for object-oriented concepts in other languages.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)