Arrays: Sorting and Searching
C stdlib provides qsort (generic sort) and bsearch (binary search) via function pointers; Java uses Arrays.sort and Collections.binarySearch.
Introduction
In this lesson, you'll learn about arrays: sorting and searching in C. Coming from Java, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Java, you're familiar with c stdlib provides qsort (generic sort) and bsearch (binary search) via function pointers; java uses arrays.sort and collections.binarysearch..
C has its own approach to c stdlib provides qsort (generic sort) and bsearch (binary search) via function pointers; java uses arrays.sort and collections.binarysearch., which we'll explore step by step.
The C Way
Let's see how C handles this concept. Here's a typical example:
#include <stdio.h>
#include <stdlib.h> /* qsort, bsearch */
#include <string.h>
/* Comparator for qsort: return negative/0/positive */
int cmp_int(const void *a, const void *b) {
return (*(int*)a - *(int*)b); /* ascending */
}
typedef struct { char name[32]; int age; } Person;
int cmp_age(const void *a, const void *b) {
const Person *pa = (const Person *)a;
const Person *pb = (const Person *)b;
return pa->age - pb->age;
}
int main(void) {
int nums[] = {5, 3, 8, 1, 9, 2};
int n = sizeof(nums) / sizeof(nums[0]); /* element count */
qsort(nums, n, sizeof(int), cmp_int);
for (int i = 0; i < n; i++) printf("%d ", nums[i]);
printf("\n"); /* 1 2 3 5 8 9 */
/* bsearch: array MUST be sorted first */
int key = 5;
int *found = bsearch(&key, nums, n, sizeof(int), cmp_int);
if (found) printf("Found %d at index %td\n", *found, found - nums);
Person people[] = {
{"Charlie", 30}, {"Alice", 25}, {"Bob", 35}
};
int np = sizeof(people) / sizeof(people[0]);
qsort(people, np, sizeof(Person), cmp_age);
for (int i = 0; i < np; i++) printf("%s: %d\n", people[i].name, people[i].age);
return 0;
}Comparing to Java
Here's how you might have written similar code in Java:
import java.util.Arrays;
import java.util.Comparator;
public class Sorting {
record Person(String name, int age) {}
public static void main(String[] args) {
int[] nums = {5, 3, 8, 1, 9, 2};
Arrays.sort(nums); // in-place, O(n log n)
System.out.println(Arrays.toString(nums)); // [1, 2, 3, 5, 8, 9]
int idx = Arrays.binarySearch(nums, 5); // 3
System.out.println("Found at: " + idx);
Person[] people = {
new Person("Charlie", 30),
new Person("Alice", 25),
new Person("Bob", 35),
};
Arrays.sort(people, Comparator.comparing(Person::age));
for (Person p : people) System.out.println(p);
}
}You may be used to different syntax or behavior.
qsort takes a comparator function pointer — it must return <0, 0, or >0 like Java Comparator.compare
You may be used to different syntax or behavior.
Element count = sizeof(array) / sizeof(array[0]) — Java uses .length field
You may be used to different syntax or behavior.
bsearch requires a sorted array; returns a void* pointer (or NULL) to the found element, not an index
You may be used to different syntax or behavior.
Generic qsort/bsearch work on any type by taking element size (sizeof(T)) — Java generics do this at compile time
You may be used to different syntax or behavior.
Pointer subtraction (found - nums) gives the index; %td is the format specifier for ptrdiff_t
Step-by-Step Breakdown
1. qsort — The Generic Sort
qsort(base, n, size, compare) sorts n elements of size bytes starting at base. The compare function receives void* pointers — cast them to the actual type.
Arrays.sort(nums);int cmp(const void *a, const void *b) {
return *(int*)a - *(int*)b; /* ascending */
}
qsort(nums, n, sizeof(int), cmp);2. Element Count Idiom
sizeof gives bytes, not count. Divide by the element size to get the element count. This only works on a stack-allocated array, not a pointer.
int n = nums.length;int n = sizeof(nums) / sizeof(nums[0]);
/* or: sizeof(nums) / sizeof(*nums) */
/* WARNING: doesn't work for int *ptr = nums */3. bsearch — Binary Search
bsearch returns a void* pointer to the found element, or NULL if not found. The array must already be sorted with the same comparator.
int idx = Arrays.binarySearch(nums, key);int key = 5;
int *p = bsearch(&key, nums, n, sizeof(int), cmp);
if (p) {
printf("found at index %zu\n", (size_t)(p - nums));
} else {
printf("not found\n");
}4. Sorting Structs
Pass a struct comparator to sort arrays of structures. Cast the void* parameters to the struct pointer type inside the comparator.
Arrays.sort(people, Comparator.comparing(p -> p.age));int cmp_age(const void *a, const void *b) {
const Person *pa = a;
const Person *pb = b;
return pa->age - pb->age;
}
qsort(people, n, sizeof(Person), cmp_age);Common Mistakes
When coming from Java, developers often make these mistakes:
- qsort takes a comparator function pointer — it must return <0, 0, or >0 like Java Comparator.compare
- Element count = sizeof(array) / sizeof(array[0]) — Java uses .length field
- bsearch requires a sorted array; returns a void* pointer (or NULL) to the found element, not an index
Key Takeaways
- qsort(array, n, sizeof(T), cmp) — generic sort; comparator gets void* pointers, cast to T*
- Element count = sizeof(array)/sizeof(array[0]) — works for stack arrays only, not pointers
- bsearch returns void* to found element or NULL — array must be sorted; convert pointer to index with (p - arr)
- Struct comparators cast void* to the struct pointer; use -> to access fields