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 and related functions, a percent sign begins a format specifier like %d or %s. Why is %% the way to output a literal percent sign instead of using %?
4 Answers
A string such as "value: %d" contains an ordinary percent character as far as C is concerned. The printf function gives that character a special meaning: %d means to insert an integer, %s means to insert a string, and so on. To distinguish a literal percent sign from a format specifier, printf defines %% as producing a single %.
Backslash would not work here because % is not a meaningful C string escape. The compiler would generally treat it as an unrecognized escape, while printf never gets a special backslash-based instruction from it. The formatting library uses its own escape convention, so the character that needs doubling is % rather than .
These are handled at two different stages. The C compiler processes backslash escapes while creating the string. printf processes percent-based format specifiers later, at runtime. Since % has special meaning to printf, %% tells printf to output one literal percent sign. The compiler itself sees both percent signs as ordinary characters.
This can also involve multiple layers. The compiler turns C escape sequences into the characters stored in the string, and then printf interprets that resulting string. For example, \ is needed to place one backslash in the string, while %% is needed because printf interprets percent signs during formatting. Each layer has its own rules.

Even though %% looks like an escape sequence, it is really an instruction understood by printf, not by the C compiler. That is why the same string can contain both C escapes like n and printf formatting such as %%.