In C, backslashes are used for escape sequences in string literals, such as n for a newline or \ for a literal backslash. However, when using printf-style formatting, a percent sign introduces a format specifier: %d inserts an integer, %s inserts a string, and so on. To print an actual percent sign, you write %%. Why is the percent sign escaped by doubling it instead of using %?
3 Answers
Backslash escapes belong to the C language itself. For example, "anb" becomes a string containing a newline before the program runs. Percent formatting is handled by printf at runtime: %d, %s, and %.2f tell it how to consume additional arguments. Because a single % could begin one of those conversions, %% is the formatting syntax for an output percent sign.
These are two different mechanisms operating at different times. The C compiler processes backslash escapes while it is parsing the string literal. Since % has no special meaning to the compiler, a normal % is already enough to place one in the string. Later, printf processes the resulting string and treats % as the start of a format instruction, so %% tells printf to output one literal percent sign.
There is no useful meaning for % in an ordinary C string literal. The compiler would generally treat the backslash as an unnecessary escape and leave the percent sign in the string, while printf would still see the % and could interpret it as a format specifier. Using %% makes the intent clear to the code that actually needs to process it. The same general idea appears when one language produces text that another parser will process: each layer has its own special characters and escaping rules.

So even though %% looks like an escape, it is really an instruction for printf rather than for the compiler. A plain % in the source string is fine; it only needs doubling if that string will be interpreted as a printf format string.