HOWTO · C

How to Sort Function in C

This article demonstrates how to use standard library sort function in C

On this page

Use the C standard library function qsort to sort an array. You provide the array, its number of elements, the size of each element, and a comparator that defines the order.

Sort an integer array with qsort

The comparator receives pointers to two elements as const void *. Cast each pointer to the element type, then compare the values. It must return a value less than zero when the first element belongs earlier, zero when the elements compare equal, or a value greater than zero when the first belongs later. Avoid returning left - right: that subtraction can overflow for widely separated int values and produce the wrong ordering. Explicit comparisons avoid that problem.

In the call, the first argument is the array, the second is its element count, the third is the size of one element in bytes, and the fourth is the comparator. sizeof values[0] keeps the element size tied to the array’s element type. qsort rearranges the supplied array in place, so printing it afterward shows the sorted order. It is not stable: equal elements are not promised to retain their original relative order.

Run this example:

#include <stdio.h>
#include <stdlib.h>

static int compare_ints(const void *a, const void *b) {
  const int left = *(const int *)a;
  const int right = *(const int *)b;
  return (left > right) - (left < right);
}

int main(void) {
  int values[] = {53, 32, 12, 52, 87, 43, 93, 23};
  const size_t count = sizeof values / sizeof values[0];

  qsort(values, count, sizeof values[0], compare_ints);
  for (size_t i = 0; i < count; ++i) {
    printf("%s%d", i == 0 ? "" : " ", values[i]);
  }
  putchar('\n');
  return EXIT_SUCCESS;
}

The expression (left > right) - (left < right) yields one of the three comparator result categories without arithmetic on the input values. The array and its count stay together in this example; if you change the array, calculate the count from that array rather than leaving a stale literal in the call.

Sort an array of strings with qsort

An array of strings is commonly an array of pointers, such as char *words[]. Each element is a pointer to characters, so the comparator receives the address of that pointer. It must dereference the element pointer before passing the two strings to strcmp. Since strcmp already returns a negative value, zero, or a positive value according to lexical order, it can provide the comparator result directly.

The element size here is sizeof words[0], which is the size of a char *, not the length of the text. qsort moves the pointers in the array; it does not copy or reorder the characters in the string literals. The order follows the byte-based comparison performed by strcmp, which is suitable for ordinary case-sensitive string ordering.

Run this example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int compare_strings(const void *a, const void *b) {
  char *const *left = (char *const *)a;
  char *const *right = (char *const *)b;
  return strcmp(*left, *right);
}

int main(void) {
  char *words[] = {"jello", "hello", "mello", "zello", "aello"};
  const size_t count = sizeof words / sizeof words[0];

  qsort(words, count, sizeof words[0], compare_strings);
  for (size_t i = 0; i < count; ++i) {
    printf("%s%s", i == 0 ? "" : " ", words[i]);
  }
  putchar('\n');
  return EXIT_SUCCESS;
}

Sort command-line strings with qsort

The same string comparator can sort the arguments given to a program. In main, argv[0] is the program name, so argv + 1 points at the first user-supplied string. argc counts the program name too; therefore argc - 1 is the number of user-supplied strings. Check the count before sorting so the example has at least two values to order. Passing this range to qsort changes the order of the argument pointers in argv; it does not change the strings themselves.

This complete program prints a usage hint and returns successfully when fewer than two strings are supplied. Otherwise, it prints the supplied strings in sorted order. Compile it as a C program and pass the words you want to sort as command-line arguments.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int compare_strings(const void *a, const void *b) {
  char *const *left = (char *const *)a;
  char *const *right = (char *const *)b;
  return strcmp(*left, *right);
}

int main(int argc, char *argv[]) {
  if (argc < 3) {
    puts("Usage: program string_1 string_2 [string ...]");
    return EXIT_SUCCESS;
  }

  char **strings = argv + 1;
  const size_t count = (size_t)(argc - 1);
  qsort(strings, count, sizeof strings[0], compare_strings);

  for (size_t i = 0; i < count; ++i) {
    printf("%s%s", i == 0 ? "" : " ", strings[i]);
  }
  putchar('\n');
  return EXIT_SUCCESS;
}