<limits.h> tells you the range of the built-in types on this platform; <stdint.h> gives you types with an exact width when you need one.
limits.h and float.h
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main(void) {
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("SCHAR = %d .. %d\n", SCHAR_MIN, SCHAR_MAX);
printf("UCHAR_MAX = %d\n", UCHAR_MAX);
printf("SHRT = %d .. %d\n", SHRT_MIN, SHRT_MAX);
printf("INT = %d .. %d\n", INT_MIN, INT_MAX);
printf("UINT_MAX = %u\n", UINT_MAX);
printf("LLONG_MAX = %lld\n", LLONG_MAX);
printf("DBL_MAX = %g, DBL_EPSILON = %g\n", DBL_MAX, DBL_EPSILON);
return 0;
}CHAR_BIT = 8
SCHAR = -128 .. 127
UCHAR_MAX = 255
SHRT = -32768 .. 32767
INT = -2147483648 .. 2147483647
UINT_MAX = 4294967295
LLONG_MAX = 9223372036854775807
DBL_MAX = 1.79769e+308, DBL_EPSILON = 2.22045e-16stdint.h — exact, least and fast types
| Type | Meaning |
|---|---|
int8_t, int16_t, int32_t, int64_t | Exactly N bits, two’s complement (optional but universally available) |
uint8_t … uint64_t | Unsigned exact-width |
int_least16_t | Smallest type with at least 16 bits |
int_fast32_t | Fastest type with at least 32 bits |
intmax_t / uintmax_t | Widest integer type |
intptr_t / uintptr_t | Integer that can hold a pointer value |
size_t (<stddef.h>) | Unsigned result of sizeof; use for sizes and indexes |
ptrdiff_t (<stddef.h>) | Signed difference of two pointers |
Printing them portably: inttypes.h
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {
int64_t big = INT64_MAX;
uint8_t small = UINT8_MAX;
uint32_t mask = 0xDEADBEEF;
printf("big = %" PRId64 "\n", big);
printf("small = %" PRIu8 "\n", small);
printf("mask = 0x%" PRIX32 "\n", mask);
printf("sizes = %zu %zu %zu\n", sizeof(int8_t), sizeof(int32_t), sizeof(uint64_t));
return 0;
}big = 9223372036854775807
small = 255
mask = 0xDEADBEEF
sizes = 1 4 8When should you use int vs int32_t?
What is size_t and why is it unsigned?