Difficulty: Intermediate | Prerequisites: C variables, pointers, dereference and address-of operators
Structs let you bundle different types of data into a single, named package. They are C's answer to the question "what if I need a variable that holds a name, a salary, and an ID all at once?" You will use structs constantly once you move beyond simple variables: any time you model a real-world entity (a student, a product, a node in a linked list), you reach for a struct. This topic also introduces the arrow operator (->), which is the standard way to access struct fields through a pointer. Make sure you are comfortable with pointers before starting.
A struct groups variables of different types under one name. You access fields with the dot operator (.) on a struct variable, or the arrow operator (->) on a pointer to a struct. Pointers to structs are common because they let you pass large data efficiently and allocate memory dynamically.
Struct (structure)
A user-defined composite type that groups variables of different types into a single unit. Think of it as a form with labelled fields: name here, salary here, employee ID here, all bundled together.
Field (member)
An individual variable inside a struct. In simple terms, each slot on the form.
Dot operator (.)
Accesses a field of a struct variable directly. Example: officeworker.empID = 1;
Arrow operator (->)
Accesses a field of a struct through a pointer to that struct. It is shorthand for (*pointer).field. In simple terms, it combines "go to the address" and "access the field" in a single step.
Definition:
struct employee {
char name[20];
double salary;
int empID;
};
This creates a new type called struct employee. No memory is allocated until you declare a variable of this type.
Declaring a variable:
struct employee officeworker;
Accessing fields with the dot operator:
officeworker.empID = 1;
Use the dot when you have the struct itself (not a pointer to it).
Declaration and assignment:
struct employee *temp;
temp = &officeworker;
temp now holds the address of officeworker.
Accessing fields through a pointer (long form):
(*temp).salary = 50000;
The parentheses around temp are required because the dot operator has higher precedence than the dereference operator. Without them, temp.salary would be interpreted as *(temp.salary), which is not what you want.
Accessing fields through a pointer (shorthand):
temp->salary = 50000;
This does exactly the same thing. The arrow operator is the standard, idiomatic way to access struct fields through a pointer.
Efficiency: passing a pointer (typically 4 or 8 bytes) to a function is far cheaper than copying an entire struct.
Dynamic allocation: you can allocate struct memory at runtime with malloc, which lets the struct outlive the function that created it. This is covered further in the Dynamic Memory Allocation notes.
Data structures: linked lists, trees, and graphs are all built from structs that contain pointers to other structs.
Expression | Meaning |
|---|---|
| Access field directly on a struct variable |
| Dereference the pointer, then access the field |
| Shorthand for the above (preferred) |
Structs are how C programmes model anything complex: a file system entry has a name, size, permissions, and timestamps bundled in a struct. Network packets, database records, and sensor readings in embedded systems are all represented as structs. The arrow operator appears in virtually every C codebase that uses linked lists, trees, or any heap-allocated data.
Students often forget the semicolon after the closing brace of a struct definition. Unlike function bodies, struct definitions require a trailing ;.
Students mix up . and ->. Use . on a struct variable, -> on a pointer to a struct. Using the wrong one is a compile error.
Students sometimes assume that declaring a struct definition allocates memory. It does not. Memory is allocated only when you declare a variable of that struct type.
Students forget the parentheses in (*temp).salary and write *temp.salary, which does not compile correctly because of operator precedence.
⚠️ Know the syntax for defining a struct, declaring a variable, and accessing fields with both . and ->.
⚠️ Be able to explain why (*temp).salary needs parentheses and what happens without them.
⚠️ Understand why pointers to structs are preferred over passing structs by value (efficiency, scope, dynamic allocation).
⚠️ Remember the semicolon after the struct definition's closing brace.
True or false: struct employee { ... } allocates memory for an employee.
Fill in the blank: The -> operator is shorthand for ______.
True or false: You need parentheses in (*ptr).field because . has higher precedence than *.
Fill in the blank: A struct definition must end with a ______.
True or false: temp.salary is correct when temp is a pointer to a struct.
Q: Write a struct definition for a student with fields char name[50], int id, and double gpa.
A:
struct student {
char name[50];
int id;
double gpa;
};
Q: Given struct student s; struct student *p = &s;, write two equivalent ways to set the student's GPA to 3.8.
A: s.gpa = 3.8; or p->gpa = 3.8; (equivalently, (*p).gpa = 3.8;).
Q: Why would you pass a pointer to a struct to a function rather than the struct itself?
A: Passing a pointer copies only the address (4 or 8 bytes). Passing the struct by value copies every field, which is wasteful for large structs and does not let the function modify the original.
Q: What is wrong with *temp.salary = 50000; when temp is a pointer to a struct?
A: Operator precedence. The dot binds tighter than the dereference, so this is parsed as (temp.salary), which treats temp as a struct (not a pointer). The correct form is (temp).salary = 50000; or, more commonly, temp->salary = 50000;.
Structs pair with dynamic memory allocation to create data that persists beyond a single function call: you malloc a struct, use it through a pointer, and free it when done. Linked lists, stacks, queues, and trees all combine structs with pointer fields. Enumerated types often appear as fields inside structs to represent state or category.
struct, structure, C struct, struct definition, struct declaration, dot operator, arrow operator, pointer to struct, struct member, struct field, typedef struct, pass struct by reference, CS1, Computer Science I, UCF