Every type in c
is either an object or a function type.
Variables have a declared type that tells you the kind of object at it's
value. This is important because a collection of bits will likely have a
different value with a different type. For example, the number 1 is represented
in IEEE 754 (floating-point arithmetic standard) by the bit pattern
0x3f800000
. If you were to interpret that same bit pattern as an int, you'd
get the value 1,065,353,216 instead of 1.
Boolean
The _Bool
type was introduced in C99 and can store 1
or 0
. It starts with
an underscore because all identifiers begining with underscores are reserved.
However, it's generally better to use the bool
type in <stdbool.h>
which can
be assiged true
or false
(which expand to integer constants 0 and 1).
#include <stdbool.h>
_Bool flag1 = 0;
bool flag2 = false;
Character
The C language defines three character types: char
, signed char
and
unsigned char
. Compilers will define char
to have the same alignment, size,
range, representation, and behavior as either signed or unsigned char.
Regardless, char
is still a separate type and is incompatible with both. It's
commonly used to represent character data, but is only big enough for ascii.
There were attempts at adding "wide character" suppport to C with wchar_t
, but
most people use a proper unicode library. This one is small and efficient:
https://libs.suckless.org/libgrapheme/
Enumeration
An enum
allows you to define a type that assigns names to integer values in
cases with an enumerable set of constant values:
enum day { sun, mon, tue, wed, thu, fri, sat };
enum cardinal_points { north = 0, east = 90, south = 180, west = 270 }
enum months { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec }
The values are automatically indexed by 0 and incremented by one unless manually
defined (see months
). Duplicate values can exist and the actual value of the
enumeration constant is implementation defined. For example, Visual C++ uses a
signed int
while GCC uses an unsigned int
.
Void
The keyword void
by itself means "cannot hold any value." For example, you can
use it to indicate that a function does not return a value, or as the sole
parameter to indicate that it takes no arguments. On the other hand void *
means that the pointer can reference any object.
Integer
Signed integers can be negative, zero, or possitive; unsigned may only be zero or possitive. The range that each type of integer can represent depends on the implementation.