C Structures
Introduction to Structures
Structures (structs) in C are user-defined data types that allow you to combine data items of different kinds. Structures are used to represent a record, enabling you to group related variables under a single name.
Key benefits of structures:
- Organize related data together
- Create complex data types that mirror real-world entities
- Improve code readability and maintainability
- Enable passing grouped data to functions
Structure Definition Syntax
struct structure_name {
data_type member1;
data_type member2;
// ... more members
};
Structure Variable Declaration
There are several ways to declare structure variables. The methods below are alternatives—use one approach in a given translation unit, not all at once:
// Method 1: Declare with definition
struct Person {
char name[50];
int age;
} person1, person2;
// Method 2: Declare separately
struct Person {
char name[50];
int age;
};
struct Person person3, person4;
// Method 3: Using typedef (cleaner call sites)
typedef struct {
char name[50];
int age;
} Person;
Person p1, p2;
Accessing Structure Members
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int id;
float gpa;
};
int main(void) {
struct Student student1;
// Access members using dot operator
strcpy(student1.name, "Alice Johnson");
student1.id = 101;
student1.gpa = 3.8f;
printf("Student Name: %s\n", student1.name);
printf("Student ID: %d\n", student1.id);
printf("Student GPA: %.2f\n", student1.gpa);
return 0;
}
Student Name: Alice Johnson Student ID: 101 Student GPA: 3.80
Structure Initialization
#include <stdio.h>
struct Point {
int x;
int y;
};
int main(void) {
// Initialize at declaration
struct Point p1 = (struct Point){10, 20};
// Designated initializers (C99)
struct Point p2 = {.x = 5, .y = 15};
struct Point p3 = {.y = 25}; // x defaults to 0
printf("Point 1: (%d, %d)\n", p1.x, p1.y);
printf("Point 2: (%d, %d)\n", p2.x, p2.y);
printf("Point 3: (%d, %d)\n", p3.x, p3.y);
return 0;
}
Point 1: (10, 20) Point 2: (5, 15) Point 3: (0, 25)
Nested Structures
#include <stdio.h>
#include <string.h>
struct Address {
char street[50];
char city[30];
char zip[10];
};
struct Employee {
char name[50];
int id;
struct Address address; // Nested structure
float salary;
};
int main(void) {
struct Employee emp;
strcpy(emp.name, "John Doe");
emp.id = 1001;
strcpy(emp.address.street, "123 Main St");
strcpy(emp.address.city, "New York");
strcpy(emp.address.zip, "10001");
emp.salary = 55000.50f;
printf("Employee: %s (ID: %d)\n", emp.name, emp.id);
printf("Address: %s, %s %s\n", emp.address.street, emp.address.city, emp.address.zip);
printf("Salary: $%.2f\n", emp.salary);
return 0;
}
Employee: John Doe (ID: 1001) Address: 123 Main St, New York 10001 Salary: $55000.50
Arrays of Structures
#include <stdio.h>
struct Book {
char title[100];
char author[50];
float price;
};
int main(void) {
struct Book library[3] = {
{"The C Programming Language", "K&R", 45.99f},
{"Clean Code", "Robert Martin", 39.95f},
{"Algorithm Design", "Kleinberg", 89.50f}
};
printf("Library Catalog:\n");
for (int i = 0; i < 3; i++) {
printf("%d. %s by %s - $%.2f\n",
i + 1, library[i].title, library[i].author, library[i].price);
}
return 0;
}
Library Catalog: 1. The C Programming Language by K&R - $45.99 2. Clean Code by Robert Martin - $39.95 3. Algorithm Design by Kleinberg - $89.50
Structure Assignment and Comparison
You can assign one structure to another of the same type (member-wise copy). However, you cannot compare structs directly with ==; compare their members instead.
#include <stdio.h>
#include <string.h>
typedef struct { int x, y; } Point;
int main(void) {
Point a = {1, 2};
Point b;
b = a; // valid: member-wise copy
int equal = (a.x == b.x) && (a.y == b.y);
printf("Equal? %s\n", equal ? "yes" : "no");
// Note: memcmp on structs is not portable due to potential padding.
return 0;
}
Equal? yes
Best Practices
- Prefer the smallest reasonable member types and order members from widest to narrowest to reduce padding.
- Initialize structs at declaration when possible; use designated initializers for clarity.
- When copying strings into fixed-size char arrays, prefer snprintf/strncpy and ensure null-termination.
- Pass large structs to functions by pointer (optionally const) to avoid unnecessary copies.
- Be aware of padding and alignment when writing/reading structs to/from files or networks.