In C, 'a' is an integer character literal: a character written between single quotes. Its value is the integer code for a on the platform, and its type is int, not char. The literal '?' works the same way. The exact code for 'a' is not fixed by C. section 5.3 section 8.5
A backslash introduces a special character. For example, '\n' denotes newline, '\'' denotes a single quote, and '\\' denotes a backslash. Numeric escapes can specify a code too: '\037' uses up to three octal digits; a hexadecimal escape such as '\xFFFF' consumes every following hexadecimal digit. section 8.5
Table 8.15 Special characters in character and string literals
'\'' |
Quote |
'\"' |
Double quote |
'\?' |
Question mark |
'\\' |
Backslash |
| '\a' | Alert |
| '\b' | Backspace |
| '\f' | Form feed |
| '\n' | New line |
| '\r' | Carriage return |
'\t' |
Horizontal tab |
'\v' |
Vertical tab |
Use the special-character table to check the spellings and meanings of escapes shared by character and string literals. section 8.5
Character literals are useful when processing text without hard-coding the platform's character codes. Decimal digit codes are consecutive, so a digit can be converted with `a - '0'`. Do not extend that guarantee to lowercase letters without checking: the example below explicitly asserts that its lowercase-letter codes are contiguous. section 8.5
/* Supposes that lowercase characters are contiguous. */
static_assert('z'-'a' == 25,
"alphabetic characters not contiguous");
#include <ctype.h>
/* Converts an alphanumeric digit to an unsigned */
/* '0' ... '9' => 0 .. 9u */
/* 'A' ... 'Z' => 10 .. 35u */
/* 'a' ... 'z' => 10 .. 35u */
/* Other values => Greater */
unsigned hexatridecimal(int a) {
if (isdigit(a)) {
/* This is guaranteed to work: decimal digits
are consecutive, and isdigit is not
locale dependent. */
return a - '0';
} else {
/* Leaves a unchanged if it is not lowercase */
a = toupper(a);
/* Returns value >= 36 if not Latin uppercase */
return (isupper(a)) ? 10 + (a - 'A') : -1;
}
}
The conversion listing combines character literals with <ctype.h> classifiers and case conversion; its assertion makes an alphabetic-code assumption visible. section 8.5
Ordinary character literals should not be confused with Unicode-prefixed literals such as u8'a', u'π', and U'𝒜'. Those forms specify UTF encodings; the distinction matters when an application needs a particular encoding rather than the platform's ordinary character representation. section 14.4
