Skip to main content

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.

c
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:

c
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

c
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

c
struct Student {
char name[50];
int roll_number;
float marks;
} student1, student2;

Method 3: Using Typedef

c
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 (.):

c
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

c
struct Student student1;
strcpy(student1.name, "John Doe");
student1.roll_number = 101;
student1.marks = 91.5;

Method 2: Using Initializer List

c
struct Student student1 = {"John Doe", 101, 91.5};

Method 3: Designated Initializers (C99 and later)

c
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

c
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

c
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

c
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:

c
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:

c
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:

c
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:

c
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:

c
#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

  1. Use meaningful names for structures and their members
  2. Consider using typedef to create more readable code
  3. Be aware of memory alignment and padding in performance-critical applications
  4. When passing large structures to functions, use pointers to avoid unnecessary copying
  5. Initialize structures properly to avoid undefined behavior
  6. 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! :)