student@ubuntu:~$
advanced-c Lesson 10 9 min read

Structs & typedef

Grouping related data together — C's version of a class without methods

Reading: Hanly & Koffman: §10.1–10.2 (pp. 572–583), §10.4 (pp. 588–595)

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 typedef to 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.


Check Your Understanding
How do you access the gpa field of a Student variable named s1?
As1->gpa
Bs1.gpa
Cs1[gpa]
Dgpa(s1)
Answer: B. When you have a struct variable (not a pointer), use the dot operator to access its fields. The arrow operator (->) 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.

Next: Struct Pointers & Arrow Operator