CLiterals

Literals

A literal is a value written directly into your source code — 42, 3.14, 'A', "hello" are all literals. Every literal has a type, and C gives you several notations for writing the same kind of value, plus suffixes that let you override the type the compiler would otherwise infer.

Integer literals

C recognizes an integer literal's base from its prefix:

Notation

Prefix

Example

Decimal value

Decimal

(none)

42

42

Octal

0

052

42

Hexadecimal

0x or 0X

0x2A

42

Binary (GNU extension / C23)

0b or 0B

0b101010

42

C
#include <stdio.h>

int main(void) {
    int a = 42;       /* decimal */
    int b = 052;      /* octal: leading 0 means base 8 -- this is 42, not 52! */
    int c = 0x2A;     /* hexadecimal */
    int d = 0b101010; /* binary -- GCC/Clang extension, standard since C23 */

    printf("%d %d %d %d\n", a, b, c, d); /* prints: 42 42 42 42 */
    return 0;
}
A leading zero means octal, not decimal padding
Writing `052` does **not** mean "42 with a leading zero for formatting" — the leading `0` tells the compiler to interpret the rest in base 8, so `052` is octal 52, which equals decimal 42. This trips people up when zero-padding numbers for alignment; use a format specifier like `%03d` for padding instead of leading zeros in the source.
Integer literal suffixes

By default, an integer literal is typed as the smallest of int, long int, or long long int that can hold it. A suffix forces a specific type regardless of the value's size:

Suffix

Meaning

Example

Type

u or U

unsigned

100u

unsigned int

l or L

long

100l

long int

ll or LL

long long

100ll

long long int

ul, lu, ull, llu (any order/case)

unsigned long / unsigned long long

100ul

unsigned long int

C
unsigned int flags   = 0xFFu;
long file_offset     = 4294967296l;
long long big_number = 9223372036854775807ll;
unsigned long long id = 18446744073709551615ull;
Lowercase l vs the digit 1
Prefer uppercase `L` over lowercase `l` for the long suffix in your own code — in many fonts `l` (lowercase L) is nearly indistinguishable from `1` (the digit one), which makes code harder to read and review.
Floating-point literals

A floating-point literal contains a decimal point, an exponent (e/E), or both. Without a suffix, it defaults to type double:

Suffix

Type

Example

(none)

double

3.14

f or F

float

3.14f

l or L

long double

3.14L

C
double  precise   = 3.14159265358979;
float   fast      = 3.14159f;
long double huge  = 3.14159265358979323846L;

double avogadro   = 6.022e23;   /* scientific notation: 6.022 * 10^23 */
double electron   = 1.6e-19;    /* negative exponent works too */
Don't assign a raw double literal to a float without thinking
`3.14` is a `double` by default. Assigning it to a `float` variable works fine (with an implicit, safe narrowing conversion), but using the `f` suffix directly avoids the extra conversion and makes your intent explicit, which matters more in performance-sensitive or embedded code where `double` arithmetic can be noticeably slower than `float` arithmetic.
Character and string literals — a quick recap

A character literal is a single character in single quotes, like 'A', and has type int in C (unlike C++, where it's char). A string literal is a sequence of characters in double quotes, like "hello", and is stored as an array of char with an automatically appended null terminator \0. Both kinds of literals can contain escape sequences — special two-character sequences starting with a backslash, such as \n for newline or \t for tab — which get their own dedicated page next.

C
char grade = 'A';           /* character literal */
char name[] = "Ada";        /* string literal -- stored as {'A','d','a','\0'} */
char newline = '\n';        /* escape sequence inside a character literal */
char greeting[] = "Hi!\n"; /* escape sequence inside a string literal */