Chapter 18Intermediate

Structures in C

Group related data together! Create your own data types with struct. Store a student's name, age, and grade in one variable.

22 min readUpdated 2024-12-16
structstructuretypedefdot operatornested structarray of struct

What You Will Learn

  • Define structures with struct keyword
  • Access members with the dot operator (.)
  • Use typedef for cleaner syntax
  • Create arrays of structures

01What is a Structure?

A structure (struct) is a user-defined data type that allows you to group different data types together under one name. Think of it as creating your own custom data type.

🆚 Arrays vs Structures

Array
  • • All elements same type
  • • Access by index [0], [1], [2]...
  • • Example: 5 integers
main.c
C
int scores[5]; // 5 ints only
Structure
  • • Different types together
  • • Access by name .age, .name
  • • Example: Person data
main.c
C
struct Person {
int age;
char name[50];
};

Real-World Examples

  • Student: name, ID, grades, age
  • Book: title, author, price, pages
  • Point: x coordinate, y coordinate
  • Date: day, month, year

02Defining a Structure

structure_basic.c
C
1#include <stdio.h>
2
3// Define a structure (blueprint)
4struct Student {
5 int id; // Member 1: integer
6 char name[50]; // Member 2: string (char array)
7 float gpa; // Member 3: float
8 int age; // Member 4: integer
9}; // Don't forget the semicolon!
10
11int main() {
12 // Create a structure variable
13 struct Student student1;
14
15 // Assign values to members using dot (.) operator
16 student1.id = 101;
17 student1.gpa = 3.85;
18 student1.age = 20;
19 // For strings, use strcpy
20 // strcpy(student1.name, "Alice");
21
22 // Or initialize at declaration
23 struct Student student2 = {102, "Bob", 3.92, 21};
24
25 // Print values
26 printf("Student ID: %d\n", student2.id);
27 printf("Name: %s\n", student2.name);
28 printf("GPA: %.2f\n", student2.gpa);
29 printf("Age: %d\n", student2.age);
30
31 return 0;
32}

Output:

Student ID: 102
Name: Bob
GPA: 3.92
Age: 21

🔍 How This Program Works

1

struct Student {...} — Defines a blueprint (template) for Student data. No memory allocated yet.

2

struct Student student1; — Creates an actual variable using the blueprint. Memory is now allocated.

3

student1.id = 101 — The . operator accesses member "id" and assigns value 101 to it.

4

{102, "Bob", 3.92, 21} — Initialize all members at once in order they were declared.

5

student2.name — Access the name member. Since it's a char array, use %s to print.

Key Points

  • struct keyword defines the structure
  • • Members are listed inside curly braces {}
  • • Semicolon ; required after closing brace
  • • Use . (dot) operator to access members

03Structure Memory Layout

Structure members are stored in contiguous memory in the order they are declared. However, the compiler may add padding bytes for alignment.

Memory Layout: struct Point { int x; int y; }

x (int)

4 bytes

y (int)

4 bytes

Total: 8 bytes (contiguous memory)

Memory Padding & Alignment

The compiler adds padding bytes to align data on memory boundaries for faster access:

struct Example { char a; int b; char c; }

a

1B

pad

3B

b (int)

4 bytes

c

1B

pad

3B

Total: 12 bytes (not 6!) due to padding

struct_padding.c
C
1#include <stdio.h>
2
3struct WithPadding {
4 char a; // 1 byte + 3 padding
5 int b; // 4 bytes
6 char c; // 1 byte + 3 padding
7}; // Total: 12 bytes
8
9struct Optimized {
10 int b; // 4 bytes
11 char a; // 1 byte
12 char c; // 1 byte + 2 padding
13}; // Total: 8 bytes (better!)
14
15int main() {
16 printf("WithPadding size: %zu bytes\n", sizeof(struct WithPadding)); // 12
17 printf("Optimized size: %zu bytes\n", sizeof(struct Optimized)); // 8
18
19 return 0;
20}

💡 Optimization Tip

Order structure members from largest to smallest to minimize padding and save memory.

04typedef with Structures

typedef creates an alias (shorter name) for a type, so you don't have to write struct every time.

typedef_struct.c
C
1#include <stdio.h>
2
3// Without typedef - must use "struct Student" everywhere
4struct Student {
5 int id;
6 char name[50];
7};
8
9// With typedef - can use just "Person"
10typedef struct {
11 int id;
12 char name[50];
13 int age;
14} Person; // "Person" is now the type name
15
16int main() {
17 // Without typedef
18 struct Student s1 = {101, "Alice"};
19
20 // With typedef (cleaner!)
21 Person p1 = {201, "Bob", 25};
22 Person p2 = {202, "Carol", 30};
23
24 printf("Student: %s\n", s1.name);
25 printf("Person 1: %s, Age: %d\n", p1.name, p1.age);
26 printf("Person 2: %s, Age: %d\n", p2.name, p2.age);
27
28 return 0;
29}

Without typedef

main.c
C
struct Student s1;
struct Student s2;

With typedef ✓

main.c
C
Person p1;
Person p2;

05Nested Structures

A structure can contain another structure as a member — this is called nesting.

nested_struct.c
C
1#include <stdio.h>
2
3// Define a Date structure
4typedef struct {
5 int day;
6 int month;
7 int year;
8} Date;
9
10// Define a Person structure with nested Date
11typedef struct {
12 char name[50];
13 int age;
14 Date birthdate; // Nested structure!
15} Person;
16
17int main() {
18 // Initialize with nested values
19 Person person1 = {
20 "Alice",
21 25,
22 {15, 6, 1999} // birthdate: June 15, 1999
23 };
24
25 // Access nested members with multiple dots
26 printf("Name: %s\n", person1.name);
27 printf("Age: %d\n", person1.age);
28 printf("Birthdate: %d/%d/%d\n",
29 person1.birthdate.day,
30 person1.birthdate.month,
31 person1.birthdate.year);
32
33 // Modify nested member
34 person1.birthdate.year = 1998;
35
36 return 0;
37}

Output:

Name: Alice
Age: 25
Birthdate: 15/6/1999

06Array of Structures

You can create an array where each element is a structure — perfect for storing lists of records.

array_of_struct.c
C
1#include <stdio.h>
2#include <string.h>
3
4typedef struct {
5 int id;
6 char name[30];
7 float gpa;
8} Student;
9
10int main() {
11 // Array of 3 students
12 Student students[3] = {
13 {101, "Alice", 3.85},
14 {102, "Bob", 3.92},
15 {103, "Carol", 3.78}
16 };
17
18 // Print all students
19 printf("Student Records:\n");
20 printf("%-5s %-15s %s\n", "ID", "Name", "GPA");
21 printf("----------------------------\n");
22
23 for (int i = 0; i < 3; i++) {
24 printf("%-5d %-15s %.2f\n",
25 students[i].id,
26 students[i].name,
27 students[i].gpa);
28 }
29
30 // Find highest GPA
31 float maxGpa = 0;
32 int topStudent = 0;
33 for (int i = 0; i < 3; i++) {
34 if (students[i].gpa > maxGpa) {
35 maxGpa = students[i].gpa;
36 topStudent = i;
37 }
38 }
39 printf("\nTop Student: %s with GPA %.2f\n",
40 students[topStudent].name, maxGpa);
41
42 // Memory: 3 * sizeof(Student) bytes
43 printf("\nSize of one Student: %zu bytes\n", sizeof(Student));
44 printf("Size of array: %zu bytes\n", sizeof(students));
45
46 return 0;
47}

Output:

Student Records:
ID Name GPA
----------------------------
101 Alice 3.85
102 Bob 3.92
103 Carol 3.78

Top Student: Bob with GPA 3.92

Size of one Student: 40 bytes
Size of array: 120 bytes

Array of Structures Memory Layout

id, name, gpa

students[0]

id, name, gpa

students[1]

id, name, gpa

students[2]

Each struct stored contiguously in memory

07Common Mistakes

❌ Forgetting Semicolon After struct

main.c
C
struct Point {
int x;
int y;
} // ERROR! Missing semicolon
struct Point {
int x;
int y;
}; // Correct!

❌ Assigning Strings with =

main.c
C
struct Student s;
s.name = "Alice"; // ERROR! Can't assign strings like this
// Correct way:
strcpy(s.name, "Alice"); // Use strcpy()

❌ Comparing Structures with ==

main.c
C
struct Point p1 = {1, 2};
struct Point p2 = {1, 2};
if (p1 == p2) { // ERROR! Can't compare structs with ==
}
// Must compare member by member:
if (p1.x == p2.x && p1.y == p2.y) { // Correct!
}

08Summary

What You Learned:

  • Structures: Group different data types under one name
  • Access: Use dot operator (.) to access members
  • Memory: Members stored contiguously with possible padding
  • typedef: Creates shorter type aliases (no "struct" keyword needed)
  • Nesting: Structures can contain other structures
  • Arrays: Create arrays of structures for record lists

09Next Steps

You've learned the main derived data types! Continue with: