qsort with structs in C: solved exercise
qsort with structs in C: solved exercise
If you searched for a solved qsort with structs in C, here is how to pass a custom comparator to qsort to sort an array of structs by different fields. qsort from <stdlib.h> accepts void * pointers in the comparator, so an explicit cast to the concrete type is required.
The comparator signature must be int cmp(const void *a, const void *b) and return negative, zero, or positive according to the relative order of a and b.
Problem statement
Define a Student struct with fields name (32-character array), grade (double), and age (int). Create an array of 5 students and sort it three ways:
- By grade descending (highest grade first).
- By name ascending (alphabetical order).
- By age ascending and, in case of a tie, by grade descending.
C solution
Expected output
Common mistakes
- Comparing doubles with
a->grade - b->gradeand returning the result directly: the difference may be a tiny double that gets truncated to 0 on cast toint, producing incorrect ties. Use explicit comparisons (>,<). - Not using
const Student *in the comparator: casting fromconst void *to a non-const pointer is valid but generates compiler warnings; usingconstis correct. - Forgetting the third argument to
qsort(sizeof(Student)): passingsizeof(Student *)(pointer size) causesqsortto misinterpret the data. - Not using
strncmpwith theMAX_Nlimit to compare strings in a struct:strcmpmay read past the field if it is not null-terminated.
Practical use
qsort with custom comparators is the standard C tool for sorting any array of records: in-memory database tables, query results, user rankings, sorting files by name/size/date, and any scenario where the sort criterion depends on multiple fields.
Recommended next exercise
- List of structs in C: solved exercise
- Struct with pointers in C: solved exercise
- Direct insertion in C: solved exercise
- All C exercises
Guided practice and full book
If you want a complete path with progressive difficulty:
FAQ
Is qsort stable? Does it preserve the order of equal elements?
Stability is not guaranteed. Most platform implementations use introsort (quicksort + heapsort hybrid), which is not stable. If you need stability, add the original index to the comparator as the final tiebreaker.
What is the difference between qsort and bsearch?
qsort sorts an array in place; bsearch finds an element in an already-sorted array, with O(n log n) and O(log n) complexity respectively. They are used together: first qsort, then bsearch.
Can qsort be used with an array of pointers to structs?
Yes, and it is common when elements are large. The comparator receives const void *a which is really const Student **, so the cast is *(const Student **)a. Sorting pointers instead of full structs avoids copying data during sorting.