How strcmp Works in C: Lexicographical Ordering

In the C programming language, the strcmp function determines the lexicographical order of two null-terminated character strings by comparing them character by character based on their numerical ASCII values. Defined in the <string.h> header, the function traverses both buffers sequentially until it encounters a differing character or a terminating null byte (\0). It then returns an integer representing the relative relationship between the two strings: negative if the first string ranks lower, zero if both are identical, and positive if the first string ranks higher.

Function Signature and Core Behavior

The standard prototype for strcmp is:

int strcmp(const char *s1, const char *s2);

The function accepts pointers to two null-terminated byte strings, s1 and s2. To avoid undefined behavior related to signed character representations, the C standard specifies that characters must be interpreted as unsigned char during evaluation. This ensures that character values range predictably from 0 to 255, preventing negative values from skewing the comparison when working with extended ASCII or non-standard character sets.

The Character-by-Character Evaluation Process

The comparison process follows a deterministic sequence:

  1. Initialization: The function starts at index 0 of both buffers: s1[0] and s2[0].
  2. Equality Check: If the characters at the current index match and are not the null terminator (\0), the internal pointers advance to the next index.
  3. Termination Conditions: The loop terminates immediately when one of two conditions is met:
    • A mismatch occurs (s1[i] != s2[i]).
    • A null terminator (\0) is reached in both strings simultaneously.
  4. Result Calculation: Upon termination, strcmp subtracts the value of the character in s2 from the character in s1: (unsigned char)s1[i] - (unsigned char)s2[i].

Interpreting the Return Value

The resulting integer designates the lexicographical relationship:

  • Return Value < 0: The string s1 is lexicographically less than s2. The first non-matching character in s1 has a smaller numerical value than the corresponding character in s2.
  • Return Value == 0: Both strings are lexicographically equal. Every character up to and including the null terminator matches.
  • Return Value > 0: The string s1 is lexicographically greater than s2. The first non-matching character in s1 has a larger numerical value than the corresponding character in s2.

Lexicographical Rules in Practice

Because strcmp relies on raw byte values, ordering follows standard ASCII hierarchy rather than natural alphabetical order:

  • Case Sensitivity: Uppercase letters have lower numerical values than lowercase letters. For instance, 'A' (ASCII 65) is evaluated as smaller than 'a' (ASCII 97). Consequently, strcmp("Apple", "apple") yields a negative integer.
  • Prefix Length: When one string is a prefix of another, the shorter string is evaluated as smaller. The null terminator has an ASCII value of 0, which is lower than any printable character. Comparing "cat" to "caterpillar" causes strcmp to compare '\0' (0) against 'e' (101) at index 3, making "cat" lexicographically smaller.
  • Non-Alphabetical Characters: Digits and punctuation marks are evaluated based on their ASCII positions. Digits ('0' through '9') range from 48 to 57 and therefore rank lower than all alphabetical characters.