Structs & typedef
Grouping related data together — C's version of a class without methods
Quick check before you start: In Java, how do you group a name, ID, and GPA into one object? If you said “a class with fields,” you already understand the motivation. Read on to see how C does it.
Practice this topic: Structs skill drill
After this lesson, you will be able to:
- Define a struct and create instances of it
- Use
typedefto simplify struct declarations - Access fields with the dot operator
- Create arrays of structs
- Explain why
==cannot compare structs
Defining a Struct
In Java, you write a class. In C, you write a struct. A struct is a named bundle of fields — no methods, no constructors, no inheritance.
struct Student {
char name[50];
int id;
double gpa;
};
This defines a type called struct Student. To create a variable:
struct Student s1;
s1.id = 12345;
s1.gpa = 3.7;
typedef: Shortening the Name
Writing struct Student everywhere is verbose. Use typedef to create an alias:
typedef struct {
char name[50];
int id;
double gpa;
} Student;
Now you can write Student s1; instead of struct Student s1;. This is the convention we use in this course.
Initializer Syntax
You can initialize a struct at declaration time by listing field values in order:
Student s = {"Alice", 12345, 3.7};
The values must match the field order in the struct definition. In C99 and later, you can also use designated initializers to name the fields explicitly:
Student s = {.name = "Alice", .id = 12345, .gpa = 3.7};
Designated initializers are safer when the struct has many fields — you do not need to remember the order.
Nested Structs
A struct field can itself be a struct. This lets you compose complex types from simpler ones:
typedef struct {
char street[100];
char city[50];
char state[3];
int zip;
} Address;
typedef struct {
char name[50];
int id;
Address addr;
} Person;
Access nested fields by chaining the dot operator:
Person p;
strcpy(p.name, "Bob");
strcpy(p.addr.city, "Cheney");
strcpy(p.addr.state, "WA");
p.addr.zip = 99004;
This is similar to having an object field inside another object in Java.
The Dot Operator
Access fields with ., just like Java:
Student s1;
strcpy(s1.name, "Alice");
s1.id = 12345;
s1.gpa = 3.7;
printf("Name: %s, GPA: %.1f\n", s1.name, s1.gpa);
Notice that you cannot assign strings with = in C. Use strcpy for character arrays.
Arrays of Structs
An array of structs works like any other array:
Student roster[30];
roster[0].id = 10001;
roster[0].gpa = 3.5;
strcpy(roster[0].name, "Bob");
for (int i = 0; i < 30; i++) {
printf("%s: %.2f\n", roster[i].name, roster[i].gpa);
}
Each element is a full Student value on the stack.
You Cannot Compare Structs with ==
This does not work:
if (s1 == s2) { ... } // COMPILER ERROR
C does not know how to compare structs field by field. You must write your own comparison:
int students_equal(Student a, Student b) {
return (a.id == b.id) &&
(strcmp(a.name, b.name) == 0) &&
(a.gpa == b.gpa);
}
In Java, you override .equals(). In C, you write a function.
gpa field of a Student variable named s1?->) is for struct pointers, which you will learn in the next lesson.
What Comes Next
You can group data into structs. But what happens when you pass a struct to a function — does it copy the whole thing? Next, you will learn to use struct pointers and the arrow operator to avoid unnecessary copies.