C typedef and Nested Structures
Writing struct Student everywhere becomes long. typedef gives a type a new, shorter name. It also helps when structures contain other structures.
typedef
#include <stdio.h>
typedef struct {
int x;
int y;
} Point;
typedef unsigned long long BigNumber;
int main(void) {
Point p = {2, 5};
BigNumber stars = 100000000000ULL;
printf("Point (%d, %d)\n", p.x, p.y);
printf("Stars: %llu\n", stars);
return 0;
}Point (2, 5) Stars: 100000000000
Now Point is a type like int; there is no need to write struct before it. typedef does not create a new kind of data: BigNumber is just another name for unsigned long long.
Nested structures
A member of a structure can itself be a structure. Reach the inner members with two dots:
#include <stdio.h>
typedef struct {
int day, month, year;
} Date;
typedef struct {
char title[30];
Date published;
double price;
} Book;
int main(void) {
Book b = {"Learning C", {15, 8, 2024}, 299.0};
printf("%s, published %02d/%02d/%d, price %.2f\n",
b.title, b.published.day, b.published.month, b.published.year, b.price);
return 0;
}Learning C, published 15/08/2024, price 299.00
Sorting structures
Structures are often sorted by one member. Here a simple bubble sort compares neighbours and swaps them when they are in the wrong order; whole structures are swapped with =:
#include <stdio.h>
typedef struct {
char name[20];
int marks;
} Student;
int main(void) {
Student s[4] = {{"Ravi", 72}, {"Asha", 91}, {"Kiran", 65}, {"Meera", 84}};
int n = 4;
for (int pass = 0; pass < n - 1; pass++) {
for (int i = 0; i < n - 1 - pass; i++) {
if (s[i].marks < s[i + 1].marks) {
Student t = s[i];
s[i] = s[i + 1];
s[i + 1] = t;
}
}
}
for (int i = 0; i < n; i++) {
printf("%d. %-6s %d\n", i + 1, s[i].name, s[i].marks);
}
return 0;
}1. Asha 91 2. Meera 84 3. Ravi 72 4. Kiran 65
The C library also has qsort in stdlib.h, which sorts any array with a comparison function you write; it is faster for large arrays.
Self-referencing structures
A structure can contain a pointer to its own type, which is how linked lists and trees are built. Then it needs a name after struct: typedef struct Node { int value; struct Node *next; } Node;. The Dynamic Memory topics use this.
When to use typedef
typedef is most useful for structures, where it saves writing struct everywhere, and for types whose meaning matters more than their details, such as typedef double Money;. Some programmers prefer to keep struct visible so readers always know they are looking at a structure; both styles are common, so follow the style of the project you work in. Avoid hiding pointers behind a typedef (such as typedef int *IntPtr;), because readers can no longer see that a value is a pointer.
Practice exercises
- Make
typedef struct { char name[20]; Date birthday; } Person;and print a person's birthday. - Sort an array of points by their distance from (0, 0).
- Rewrite the sort with
qsortand a comparison function.