C programming
array sorting
algorithms
data structures
coding tutorials

Sorting an array in C?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

In C, the usual answer to “how do I sort an array” is to use the standard library function qsort. It already handles arbitrary element types as long as you provide the array length, element size, and a correct comparison function. The real skill is not memorizing qsort. It is writing a comparator that is correct, safe, and appropriate for the data being sorted.

Use qsort for Ordinary Array Sorting

For an integer array, qsort looks like this.

c
1#include <stdio.h>
2#include <stdlib.h>
3
4static int compare_ints_asc(const void *a, const void *b) {
5    int left = *(const int *)a;
6    int right = *(const int *)b;
7
8    return (left > right) - (left < right);
9}
10
11int main(void) {
12    int values[] = {42, 7, 19, 3, 19, 1};
13    size_t count = sizeof(values) / sizeof(values[0]);
14
15    qsort(values, count, sizeof(values[0]), compare_ints_asc);
16
17    for (size_t i = 0; i < count; i++) {
18        printf("%d\n", values[i]);
19    }
20
21    return 0;
22}

This is the right default because it is portable, tested, and already part of the C standard library.

Write the Comparator Carefully

The comparator is where many bugs happen. A common beginner implementation returns left - right. That looks compact, but it can overflow if the integers are large.

The safer pattern is:

c
return (left > right) - (left < right);

It still returns negative, zero, or positive values as qsort expects, but it avoids subtraction-based overflow.

A comparator also has to be consistent. If it says a < b and b < c, it must not later imply c < a. Inconsistent comparators can make sorting behavior undefined.

Descending Order Is Just a Different Comparator

Sorting descending is not a different API. It is a different ordering rule.

c
1static int compare_ints_desc(const void *a, const void *b) {
2    int left = *(const int *)a;
3    int right = *(const int *)b;
4
5    return (right > left) - (right < left);
6}

That small change is enough to reverse the sort order.

Sorting Structs Is Where Comparator Design Matters More

Real programs often sort arrays of structs rather than raw numbers. In that case, your comparator usually expresses a primary sort key and then a tie-breaker.

c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5typedef struct {
6    char name[32];
7    int score;
8} Player;
9
10static int compare_players(const void *a, const void *b) {
11    const Player *left = (const Player *)a;
12    const Player *right = (const Player *)b;
13
14    if (left->score != right->score) {
15        return (right->score > left->score) - (right->score < left->score);
16    }
17
18    return strcmp(left->name, right->name);
19}
20
21int main(void) {
22    Player players[] = {
23        {"Avery", 90},
24        {"Blair", 95},
25        {"Casey", 90}
26    };
27    size_t count = sizeof(players) / sizeof(players[0]);
28
29    qsort(players, count, sizeof(players[0]), compare_players);
30
31    for (size_t i = 0; i < count; i++) {
32        printf("%s %d\n", players[i].name, players[i].score);
33    }
34
35    return 0;
36}

This is often the difference between a toy example and production-quality sorting logic.

Custom Sorting Algorithms Are Usually the Exception

It is possible to write your own insertion sort, merge sort, or quicksort. Sometimes that is useful for learning or for a very specialized requirement such as guaranteed stability. But for most application code, replacing qsort with hand-written sorting before measuring a real problem is unnecessary risk.

If you do need a custom sort, write it because you have a clear requirement, not because using the standard library feels too simple.

Understand What qsort Does Not Guarantee

qsort does not promise stability. If two elements compare equal, their relative order may change. If your program depends on equal elements staying in original order, you need a stable algorithm or a comparator that includes a tie-breaker field.

That is a subtle but important design point. Sorting correctness is not only about whether the final array is ordered. It is also about which ordering properties the application actually relies on.

Common Pitfalls

  • Returning left - right from the comparator and risking overflow.
  • Passing the wrong element size to qsort.
  • Writing an inconsistent comparator.
  • Assuming qsort is stable when equal elements need predictable order.
  • Replacing qsort with a custom algorithm before confirming that sorting is actually the bottleneck.

Summary

  • In C, qsort is the standard first choice for sorting arrays.
  • A safe comparator matters more than clever sorting code.
  • Use explicit comparator logic for ascending, descending, and struct-based sorting.
  • Add tie-breakers when application logic needs deterministic ordering among equal values.
  • Write a custom sort only when you have a real requirement that qsort does not satisfy.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.