Progress: 9 of 16 topics56%

Structures in C Programming

Structures are user-defined data types that allow you to group related variables of different data types under a single name. They provide a way to create complex data types that can represent real-world entities with multiple attributes, making your programs more organized and easier to manage.

Key Takeaways

  • Structures group related variables of different data types into a single unit
  • Members of a structure are accessed using the dot (.) operator
  • Structures can be nested and used in arrays
  • Structure pointers use the arrow (->) operator to access members
  • Structures help in organizing code and creating complex data models

What Are Structures?

A structure is a collection of variables (called members or fields) that are logically related and grouped together under one name. Unlike arrays that store elements of the same data type, structures can contain elements of different data types.

Think of a structure as a blueprint for creating a custom data type. For example, to represent a student, you might need to store their name, age, ID number, and GPA. Instead of creating separate variables for each piece of information, you can group them all into a single structure.

Without Structures

c
1char student_name[50];
2int student_age;
3int student_id;
4float student_gpa;
5
6char employee_name[50];
7int employee_age;
8int employee_id;
9float employee_salary;

Scattered variables, hard to manage and organize

With Structures

c
1struct Student {
2 char name[50];
3 int age;
4 int id;
5 float gpa;
6};
7
8struct Student student1, student2;

Organized, reusable, and easier to maintain

Declaring Structures

To create a structure, you use the struct keyword followed by a structure name and a list of member variables enclosed in curly braces.

Basic Syntax

c
1struct structure_name {
2 data_type member1;
3 data_type member2;
4 // ... more members
5};

Don't forget the semicolon after the closing brace when declaring a structure. This is a common source of compilation errors.

Example: Student Structure

c
1struct Student {
2 char name[50]; // Student's name
3 int age; // Student's age
4 int id; // Student ID number
5 float gpa; // Grade Point Average
6 char grade; // Letter grade
7};

Creating Structure Variables

After declaring a structure, you can create variables of that structure type:

c
1// Method 1: Declare variables after structure definition
2struct Student student1, student2, student3;
3
4// Method 2: Declare variables along with structure definition
5struct Student {
6 char name[50];
7 int age;
8 int id;
9 float gpa;
10} student1, student2;
11
12// Method 3: Using typedef (recommended)
13typedef struct {
14 char name[50];
15 int age;
16 int id;
17 float gpa;
18} Student;
19
20Student student1, student2; // No need for 'struct' keyword

Accessing Structure Members

Structure members are accessed using the dot (.) operator, also known as the member access operator. The syntax is: structure_variable.member_name

Example: Basic Member Access

c
1#include <stdio.h>
2#include <string.h>
3
4struct Student {
5 char name[50];
6 int age;
7 int id;
8 float gpa;
9};
10
11int main() {
12 struct Student student1;
13
14 // Assigning values to structure members
15 strcpy(student1.name, "Alice Johnson");
16 student1.age = 20;
17 student1.id = 12345;
18 student1.gpa = 3.85;
19
20 // Accessing and displaying structure members
21 printf("Student Information:\n");
22 printf("Name: %s\n", student1.name);
23 printf("Age: %d\n", student1.age);
24 printf("ID: %d\n", student1.id);
25 printf("GPA: %.2f\n", student1.gpa);
26
27 return 0;
28}
29
30// Output:
31// Student Information:
32// Name: Alice Johnson
33// Age: 20
34// ID: 12345
35// GPA: 3.85

Structure Initialization

Structures can be initialized in several ways when they are declared or after declaration.

Initialization at Declaration

c
1#include <stdio.h>
2
3struct Point {
4 int x;
5 int y;
6};
7
8int main() {
9 // Method 1: Initialize all members in order
10 struct Point p1 = {10, 20};
11
12 // Method 2: Designated initializers (C99 and later)
13 struct Point p2 = {.x = 30, .y = 40};
14 struct Point p3 = {.y = 50, .x = 60}; // Order doesn't matter
15
16 // Method 3: Partial initialization (remaining members set to 0)
17 struct Point p4 = {100}; // x = 100, y = 0
18
19 // Method 4: Zero initialization
20 struct Point p5 = {0}; // Both x and y are 0
21 struct Point p6 = {}; // Same as above (C++ style, some C compilers support)
22
23 printf("p1: (%d, %d)\n", p1.x, p1.y);
24 printf("p2: (%d, %d)\n", p2.x, p2.y);
25 printf("p3: (%d, %d)\n", p3.x, p3.y);
26 printf("p4: (%d, %d)\n", p4.x, p4.y);
27 printf("p5: (%d, %d)\n", p5.x, p5.y);
28
29 return 0;
30}
31
32// Output:
33// p1: (10, 20)
34// p2: (30, 40)
35// p3: (60, 50)
36// p4: (100, 0)
37// p5: (0, 0)

Complex Structure Initialization

c
1#include <stdio.h>
2
3struct Employee {
4 char name[30];
5 int id;
6 float salary;
7 char department[20];
8};
9
10int main() {
11 // Initialize with all values
12 struct Employee emp1 = {
13 "John Smith",
14 1001,
15 55000.50,
16 "Engineering"
17 };
18
19 // Using designated initializers
20 struct Employee emp2 = {
21 .name = "Jane Doe",
22 .id = 1002,
23 .salary = 62000.75,
24 .department = "Marketing"
25 };
26
27 printf("Employee 1: %s, ID: %d, Salary: $%.2f, Dept: %s\n",
28 emp1.name, emp1.id, emp1.salary, emp1.department);
29 printf("Employee 2: %s, ID: %d, Salary: $%.2f, Dept: %s\n",
30 emp2.name, emp2.id, emp2.salary, emp2.department);
31
32 return 0;
33}

Arrays of Structures

You can create arrays of structures to store multiple records of the same type. This is particularly useful when working with collections of similar data.

Example: Student Database

c
1#include <stdio.h>
2#include <string.h>
3
4struct Student {
5 char name[50];
6 int rollNo;
7 float marks;
8};
9
10int main() {
11 struct Student students[3];
12 int i;
13
14 // Input student data
15 for (i = 0; i < 3; i++) {
16 printf("Enter details for student %d:\n", i + 1);
17 printf("Name: ");
18 scanf("%s", students[i].name);
19 printf("Roll Number: ");
20 scanf("%d", &students[i].rollNo);
21 printf("Marks: ");
22 scanf("%f", &students[i].marks);
23 printf("\n");
24 }
25
26 // Display student data
27 printf("\n--- Student Records ---\n");
28 for (i = 0; i < 3; i++) {
29 printf("Student %d:\n", i + 1);
30 printf(" Name: %s\n", students[i].name);
31 printf(" Roll No: %d\n", students[i].rollNo);
32 printf(" Marks: %.2f\n", students[i].marks);
33 printf("\n");
34 }
35
36 // Find student with highest marks
37 int topStudent = 0;
38 for (i = 1; i < 3; i++) {
39 if (students[i].marks > students[topStudent].marks) {
40 topStudent = i;
41 }
42 }
43
44 printf("Top performer: %s with %.2f marks\n",
45 students[topStudent].name, students[topStudent].marks);
46
47 return 0;
48}

Initializing Arrays of Structures

c
1#include <stdio.h>
2
3struct Book {
4 char title[50];
5 char author[30];
6 int pages;
7 float price;
8};
9
10int main() {
11 // Initialize array of structures
12 struct Book library[3] = {
13 {"The C Programming Language", "Kernighan & Ritchie", 274, 45.99},
14 {"Data Structures in C", "Tanenbaum", 456, 39.95},
15 {"Algorithms in C", "Robert Sedgewick", 672, 54.50}
16 };
17
18 printf("Library Catalog:\n");
19 printf("%-30s %-20s %6s %8s\n", "Title", "Author", "Pages", "Price");
20 printf("%-30s %-20s %6s %8s\n", "-----", "------", "-----", "-----");
21
22 for (int i = 0; i < 3; i++) {
23 printf("%-30s %-20s %6d $%7.2f\n",
24 library[i].title, library[i].author,
25 library[i].pages, library[i].price);
26 }
27
28 return 0;
29}

Nested Structures

A structure can contain other structures as members. This is called nesting and allows you to create more complex data models that represent hierarchical relationships.

Example: Address within Person

c
1#include <stdio.h>
2#include <string.h>
3
4// Define the Address structure
5struct Address {
6 char street[100];
7 char city[50];
8 char state[30];
9 int zipCode;
10};
11
12// Define the Person structure with nested Address
13struct Person {
14 char name[50];
15 int age;
16 struct Address address; // Nested structure
17 char phone[15];
18};
19
20int main() {
21 struct Person person1;
22
23 // Assign values to the person
24 strcpy(person1.name, "Robert Johnson");
25 person1.age = 35;
26 strcpy(person1.phone, "555-1234");
27
28 // Assign values to the nested address structure
29 strcpy(person1.address.street, "123 Main Street");
30 strcpy(person1.address.city, "New York");
31 strcpy(person1.address.state, "NY");
32 person1.address.zipCode = 10001;
33
34 // Display the information
35 printf("Person Information:\n");
36 printf("Name: %s\n", person1.name);
37 printf("Age: %d\n", person1.age);
38 printf("Phone: %s\n", person1.phone);
39 printf("Address:\n");
40 printf(" Street: %s\n", person1.address.street);
41 printf(" City: %s\n", person1.address.city);
42 printf(" State: %s\n", person1.address.state);
43 printf(" ZIP Code: %d\n", person1.address.zipCode);
44
45 return 0;
46}

Complex Nested Structure Example

c
1struct Date {
2 int day;
3 int month;
4 int year;
5};
6
7struct Employee {
8 char name[50];
9 int empId;
10 struct Date birthDate;
11 struct Date joiningDate;
12 struct Address workAddress;
13 float salary;
14};
15
16// Accessing nested structure members
17struct Employee emp;
18emp.birthDate.day = 15;
19emp.birthDate.month = 6;
20emp.birthDate.year = 1990;
21
22// Display nested data
23printf("Birth Date: %d/%d/%d\n",
24 emp.birthDate.day, emp.birthDate.month, emp.birthDate.year);

Structure Pointers

Like other data types, you can create pointers to structures. Structure pointers are especially useful for dynamic memory allocation and passing structures efficiently to functions.

Declaring and Using Structure Pointers

c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5struct Student {
6 char name[50];
7 int age;
8 float gpa;
9};
10
11int main() {
12 struct Student student1 = {"Alice", 20, 3.8};
13 struct Student *ptr;
14
15 // Point to the structure
16 ptr = &student1;
17
18 // Method 1: Access using (*ptr).member
19 printf("Using (*ptr).member syntax:\n");
20 printf("Name: %s\n", (*ptr).name);
21 printf("Age: %d\n", (*ptr).age);
22 printf("GPA: %.2f\n", (*ptr).gpa);
23
24 // Method 2: Access using ptr->member (arrow operator)
25 printf("\nUsing ptr->member syntax:\n");
26 printf("Name: %s\n", ptr->name);
27 printf("Age: %d\n", ptr->age);
28 printf("GPA: %.2f\n", ptr->gpa);
29
30 // Modifying values through pointer
31 ptr->age = 21;
32 ptr->gpa = 3.9;
33
34 printf("\nAfter modification:\n");
35 printf("Age: %d\n", student1.age);
36 printf("GPA: %.2f\n", student1.gpa);
37
38 return 0;
39}

Arrow Operator (->))

The arrow operator (->) is a shorthand for (*ptr).member. It makes code more readable when working with structure pointers. Use ptr-> instead of (*ptr).member.

Dynamic Memory Allocation for Structures

c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5struct Employee {
6 char name[50];
7 int id;
8 float salary;
9};
10
11int main() {
12 struct Employee *emp;
13 int n, i;
14
15 printf("Enter number of employees: ");
16 scanf("%d", &n);
17
18 // Allocate memory for n employees
19 emp = (struct Employee*)malloc(n * sizeof(struct Employee));
20
21 if (emp == NULL) {
22 printf("Memory allocation failed!\n");
23 return 1;
24 }
25
26 // Input employee data
27 for (i = 0; i < n; i++) {
28 printf("\nEmployee %d:\n", i + 1);
29 printf("Name: ");
30 scanf("%s", (emp + i)->name); // or emp[i].name
31 printf("ID: ");
32 scanf("%d", &(emp + i)->id); // or &emp[i].id
33 printf("Salary: ");
34 scanf("%f", &(emp + i)->salary); // or &emp[i].salary
35 }
36
37 // Display employee data
38 printf("\n--- Employee Records ---\n");
39 for (i = 0; i < n; i++) {
40 printf("Employee %d: %s, ID: %d, Salary: $%.2f\n",
41 i + 1, emp[i].name, emp[i].id, emp[i].salary);
42 }
43
44 // Free allocated memory
45 free(emp);
46
47 return 0;
48}

Structures and Functions

Structures can be passed to functions in several ways: by value, by reference (using pointers), or by returning them from functions.

Passing Structures by Value

c
1#include <stdio.h>
2
3struct Rectangle {
4 float length;
5 float width;
6};
7
8// Function that takes structure by value
9float calculateArea(struct Rectangle rect) {
10 return rect.length * rect.width;
11}
12
13// Function that takes structure by value and returns modified structure
14struct Rectangle scaleRectangle(struct Rectangle rect, float factor) {
15 rect.length *= factor;
16 rect.width *= factor;
17 return rect;
18}
19
20int main() {
21 struct Rectangle rect1 = {10.5, 6.2};
22
23 printf("Original rectangle: %.2f x %.2f\n", rect1.length, rect1.width);
24 printf("Area: %.2f\n", calculateArea(rect1));
25
26 struct Rectangle scaledRect = scaleRectangle(rect1, 2.0);
27 printf("Scaled rectangle: %.2f x %.2f\n", scaledRect.length, scaledRect.width);
28 printf("Original after function call: %.2f x %.2f\n", rect1.length, rect1.width);
29
30 return 0;
31}
32
33// Output:
34// Original rectangle: 10.50 x 6.20
35// Area: 65.10
36// Scaled rectangle: 21.00 x 12.40
37// Original after function call: 10.50 x 6.20

Passing Structures by Reference (Pointer)

c
1#include <stdio.h>
2#include <string.h>
3
4struct Student {
5 char name[50];
6 int age;
7 float gpa;
8};
9
10// Function that modifies structure through pointer
11void updateGPA(struct Student *student, float newGPA) {
12 student->gpa = newGPA;
13 printf("Updated %s's GPA to %.2f\n", student->name, student->gpa);
14}
15
16// Function that displays student info
17void displayStudent(const struct Student *student) {
18 printf("Student: %s, Age: %d, GPA: %.2f\n",
19 student->name, student->age, student->gpa);
20}
21
22// Function that creates and returns a structure
23struct Student createStudent(char name[], int age, float gpa) {
24 struct Student newStudent;
25 strcpy(newStudent.name, name);
26 newStudent.age = age;
27 newStudent.gpa = gpa;
28 return newStudent;
29}
30
31int main() {
32 struct Student student1 = {"Bob Wilson", 19, 3.2};
33
34 printf("Before update:\n");
35 displayStudent(&student1);
36
37 updateGPA(&student1, 3.7);
38
39 printf("After update:\n");
40 displayStudent(&student1);
41
42 // Create new student using function
43 struct Student student2 = createStudent("Carol Davis", 21, 3.9);
44 displayStudent(&student2);
45
46 return 0;
47}

Performance Consideration

Passing large structures by value can be inefficient as it creates a copy of the entire structure. For large structures, consider passing by pointer to improve performance.

Using typedef with Structures

The typedef keyword can make working with structures more convenient by creating type aliases, eliminating the need to use the struct keyword repeatedly.

c
1#include <stdio.h>
2
3// Method 1: typedef with named structure
4struct Point {
5 int x;
6 int y;
7};
8typedef struct Point Point;
9
10// Method 2: typedef with anonymous structure (more common)
11typedef struct {
12 char name[50];
13 int age;
14 float salary;
15} Employee;
16
17// Method 3: typedef with structure name and alias in one declaration
18typedef struct Car {
19 char make[30];
20 char model[30];
21 int year;
22 float price;
23} Car;
24
25int main() {
26 // Using typedef makes declarations cleaner
27 Point p1 = {10, 20}; // No need for 'struct'
28 Employee emp1 = {"John Doe", 30, 50000.0};
29 Car car1 = {"Toyota", "Camry", 2023, 25000.0};
30
31 printf("Point: (%d, %d)\n", p1.x, p1.y);
32 printf("Employee: %s, Age: %d, Salary: $%.2f\n",
33 emp1.name, emp1.age, emp1.salary);
34 printf("Car: %d %s %s, Price: $%.2f\n",
35 car1.year, car1.make, car1.model, car1.price);
36
37 return 0;
38}

Memory Layout of Structures

Understanding how structures are stored in memory can help you write more efficient code and avoid potential issues with structure padding and alignment.

Structure Padding and Alignment

c
1#include <stdio.h>
2
3struct Example1 {
4 char a; // 1 byte
5 int b; // 4 bytes
6 char c; // 1 byte
7};
8
9struct Example2 {
10 char a; // 1 byte
11 char c; // 1 byte
12 int b; // 4 bytes
13};
14
15struct Example3 {
16 int b; // 4 bytes
17 char a; // 1 byte
18 char c; // 1 byte
19};
20
21int main() {
22 printf("Size of char: %zu bytes\n", sizeof(char));
23 printf("Size of int: %zu bytes\n", sizeof(int));
24 printf("\n");
25
26 printf("Size of Example1: %zu bytes\n", sizeof(struct Example1));
27 printf("Size of Example2: %zu bytes\n", sizeof(struct Example2));
28 printf("Size of Example3: %zu bytes\n", sizeof(struct Example3));
29
30 // Demonstrating memory addresses
31 struct Example1 ex1;
32 printf("\nMemory layout of Example1:\n");
33 printf("Address of ex1: %p\n", (void*)&ex1);
34 printf("Address of ex1.a: %p\n", (void*)&ex1.a);
35 printf("Address of ex1.b: %p\n", (void*)&ex1.b);
36 printf("Address of ex1.c: %p\n", (void*)&ex1.c);
37
38 return 0;
39}
40
41
42// Typical output (may vary by system):
43// Size of char: 1 bytes
44// Size of int: 4 bytes
45//
46// Size of Example1: 12 bytes
47// Size of Example2: 8 bytes
48// Size of Example3: 8 bytes
49
50// Demonstrating offsetof macro
51#include <stddef.h>
52
53printf("
54Offset of members in Example1:
55");
56printf("Offset of a: %zu
57", offsetof(struct Example1, a));
58printf("Offset of b: %zu
59", offsetof(struct Example1, b));
60printf("Offset of c: %zu
61", offsetof(struct Example1, c));
62
63return 0;
64}
65
66// Packed structures (compiler-specific)
67#pragma pack(1) // or __attribute__((packed)) for GCC
68struct PackedExample {
69 char a;
70 int b;
71 char c;
72};
73#pragma pack() // Reset to default alignment
74
75// Usage example with packed structure
76printf("
77Packed structure size: %zu bytes
78", sizeof(struct PackedExample));
c
1## Real-World Examples
2
3### Example 1: Library Management System
4
5
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9
10typedef struct {
11 int bookId;
12 char title[100];
13 char author[50];
14 char isbn[20];
15 int availableCopies;
16 float price;
17} Book;
18
19typedef struct {
20 int memberId;
21 char name[50];
22 char email[50];
23 int booksIssued;
24} Member;
25
26// Function to display book information
27void displayBook(const Book *book) {
28 printf("ID: %d
29", book->bookId);
30 printf("Title: %s
31", book->title);
32 printf("Author: %s
33", book->author);
34 printf("ISBN: %s
35", book->isbn);
36 printf("Available: %d copies
37", book->availableCopies);
38 printf("Price: $%.2f
39", book->price);
40 printf("------------------------
41");
42}
43
44// Function to search for a book by title
45int searchBookByTitle(Book books[], int count, const char *title) {
46 for (int i = 0; i < count; i++) {
47 if (strcmp(books[i].title, title) == 0) {
48 return i;
49 }
50 }
51 return -1;
52}
53
54int main() {
55 Book library[3] = {
56 {1, "The C Programming Language", "Kernighan & Ritchie", "978-0131103627", 5, 45.99},
57 {2, "Data Structures and Algorithms", "Cormen", "978-0262033848", 3, 89.95},
58 {3, "Operating System Concepts", "Silberschatz", "978-1118063330", 2, 79.50}
59 };
60
61 printf("=== Library Management System ===
62
63");
64
65 // Display all books
66 printf("Available Books:
67");
68 for (int i = 0; i < 3; i++) {
69 displayBook(&library[i]);
70 }
71
72 // Search for a specific book
73 char searchTitle[100];
74 printf("Enter book title to search: ");
75 fgets(searchTitle, sizeof(searchTitle), stdin);
76 searchTitle[strcspn(searchTitle, "
77")] = 0; // Remove newline
78
79 int index = searchBookByTitle(library, 3, searchTitle);
80 if (index != -1) {
81 printf("
82Book found:
83");
84 displayBook(&library[index]);
85 } else {
86 printf("
87Book not found in library.
88");
89 }
90
91 return 0;
92}
93
94### Example 2: Student Grade Management
95
96
97#include <stdio.h>
98#include <string.h>
99
100#define MAX_SUBJECTS 5
101#define MAX_STUDENTS 50
102
103typedef struct {
104 char name[30];
105 int marks;
106 char grade;
107} Subject;
108
109typedef struct {
110 int studentId;
111 char name[50];
112 Subject subjects[MAX_SUBJECTS];
113 int subjectCount;
114 float totalMarks;
115 float percentage;
116 char overallGrade;
117} Student;
118
119// Function to calculate grade based on marks
120char calculateGrade(int marks) {
121 if (marks >= 90) return 'A';
122 else if (marks >= 80) return 'B';
123 else if (marks >= 70) return 'C';
124 else if (marks >= 60) return 'D';
125 else return 'F';
126}
127
128// Function to calculate student's overall performance
129void calculateOverallPerformance(Student *student) {
130 int totalMarks = 0;
131
132 for (int i = 0; i < student->subjectCount; i++) {
133 totalMarks += student->subjects[i].marks;
134 student->subjects[i].grade = calculateGrade(student->subjects[i].marks);
135 }
136
137 student->totalMarks = totalMarks;
138 student->percentage = (float)totalMarks / (student->subjectCount * 100) * 100;
139 student->overallGrade = calculateGrade((int)student->percentage);
140}
141
142// Function to display student report
143void displayStudentReport(const Student *student) {
144 printf("
145=== Student Report Card ===
146");
147 printf("Student ID: %d
148", student->studentId);
149 printf("Name: %s
150", student->name);
151 printf("
152Subject-wise Performance:
153");
154 printf("%-20s %-10s %-10s
155", "Subject", "Marks", "Grade");
156 printf("%-20s %-10s %-10s
157", "-------", "-----", "-----");
158
159 for (int i = 0; i < student->subjectCount; i++) {
160 printf("%-20s %-10d %-10c
161",
162 student->subjects[i].name,
163 student->subjects[i].marks,
164 student->subjects[i].grade);
165 }
166
167 printf("
168Overall Performance:
169");
170 printf("Total Marks: %.0f/%d
171", student->totalMarks, student->subjectCount * 100);
172 printf("Percentage: %.2f%%
173", student->percentage);
174 printf("Overall Grade: %c
175", student->overallGrade);
176}
177
178int main() {
179 Student student1;
180
181 // Initialize student data
182 student1.studentId = 101;
183 strcpy(student1.name, "Alice Johnson");
184 student1.subjectCount = 5;
185
186 // Initialize subjects and marks
187 strcpy(student1.subjects[0].name, "Mathematics");
188 student1.subjects[0].marks = 85;
189
190 strcpy(student1.subjects[1].name, "Physics");
191 student1.subjects[1].marks = 78;
192
193 strcpy(student1.subjects[2].name, "Chemistry");
194 student1.subjects[2].marks = 92;
195
196 strcpy(student1.subjects[3].name, "English");
197 student1.subjects[3].marks = 88;
198
199 strcpy(student1.subjects[4].name, "Computer Science");
200 student1.subjects[4].marks = 95;
201
202 // Calculate overall performance
203 calculateOverallPerformance(&student1);
204
205 // Display report
206 displayStudentReport(&student1);
207
208 return 0;
209}
210
211
212## Common Pitfalls and Best Practices
213
214### Memory Management
215
216// DON'T: Return pointer to local structure
217struct Point* createPoint(int x, int y) {
218 struct Point p = {x, y}; // Local variable
219 return &p; // ERROR: Returns pointer to local variable
220}
221
222// DO: Use dynamic allocation or pass by parameter
223struct Point* createPoint(int x, int y) {
224 struct Point *p = malloc(sizeof(struct Point));
225 if (p != NULL) {
226 p->x = x;
227 p->y = y;
228 }
229 return p;
230}
231
232
233### Structure Comparison
234
235// DON'T: Compare structures directly
236struct Point p1 = {10, 20};
237struct Point p2 = {10, 20};
238
239// if (p1 == p2) { ... } // ERROR: Cannot compare structures directly
240
241// DO: Compare member by member or use memcmp
242int comparePoints(const struct Point *p1, const struct Point *p2) {
243 return (p1->x == p2->x && p1->y == p2->y);
244}
245
246// Or using memcmp (be careful with padding)
247int result = memcmp(&p1, &p2, sizeof(struct Point));