Beginner · Getting started with C · topic 4 of 60 · 30 min
Data types and their sizes
Explanation
Why sizes matter in C
In C, every type occupies a fixed number of bytes, and that number limits the values it can hold. Unlike Java, C does not fix most sizes; the standard only gives minimums, and the compiler chooses for each platform. Code that assumes long is 8 bytes works on Linux and silently breaks on Windows. sizeof tells you the size in bytes for the machine you compile on.
#include <stdio.h>
int main(void) {
printf("char %zu\n", sizeof(char)); // always 1
printf("short %zu\n", sizeof(short));
printf("int %zu\n", sizeof(int));
printf("long %zu\n", sizeof(long));
printf("long long %zu\n", sizeof(long long));
printf("float %zu\n", sizeof(float));
printf("double %zu\n", sizeof(double));
printf("pointer %zu\n", sizeof(void *));
return 0;
}| Type | 64-bit Linux/macOS (LP64) | 64-bit Windows (LLP64) | Typical range (4-byte int) |
|---|---|---|---|
| char | 1 | 1 | -128..127 or 0..255 (signedness varies!) |
| short | 2 | 2 | -32,768..32,767 |
| int | 4 | 4 | -2,147,483,648..2,147,483,647 |
| long | 8 | 4 | depends on platform |
| long long | 8 | 8 | about ±9.2 × 10^18 |
| float / double | 4 / 8 | 4 / 8 | ~7 / ~15 significant digits |
| pointer | 8 | 8 | (addresses) |
signed and unsigned
Integer types are signed by default (they hold negatives). unsigned versions hold only zero and positives, with double the positive range: unsigned int goes from 0 to 4,294,967,295 on these platforms. Whether plain char is signed or unsigned depends on the platform, so use signed char or unsigned char when it matters (for bytes, use unsigned char).
Ranges from limits.h, exact sizes from stdint.h
#include <limits.h>
#include <stdint.h>
#include <inttypes.h>
printf("%d %d\n", INT_MIN, INT_MAX); // -2147483648 2147483647 (with a 4-byte int)
int32_t balance = -500; // exactly 32 bits, signed
uint8_t pin_state = 1; // exactly 8 bits, unsigned (0..255)
uint64_t file_size = 5000000000ULL; // exactly 64 bits
printf("%" PRIu64 "\n", file_size); // portable printf format for uint64_tUse int for everyday counting, size_t for sizes and array indexes (it is what sizeof and strlen return), and fixed-width types from stdint.h for file formats, network protocols and hardware registers (module 12), where the exact number of bits matters.
Constants and literals
const double GST_RATE = 18.0; /* a read-only variable */
#define MAX_STUDENTS 60 /* a preprocessor constant (module 8) */
10 /* int */ 10U /* unsigned int */ 10L /* long */ 10LL /* long long */
3.14 /* double */ 3.14f /* float */
'A' /* a character constant, value 65 in ASCII */
0x1F /* hexadecimal 31 */ 017 /* OCTAL 15: a leading 0 means octal! */Declaring and initialising
int count; /* declared but NOT initialised: holds garbage if local */
int total = 0; /* declared and initialised */
printf("%d\n", count); /* undefined behaviour: may print any number */Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Data types and their sizes · 1/6
In this lesson you will learn C's data types and how big they are.
Prefer a video by a teacher? Find free videos on “c data types sizeof int long char signed unsigned stdint” on YouTube ↗
In real life: A sensor reading in an IoT device
A temperature sensor on a cold-storage warehouse sends readings as signed 16-bit values in tenths of a degree. The firmware stores them in int16_t, not int, because the network packet format fixes exactly 2 bytes, whatever compiler is used.
#include <stdio.h>
#include <stdint.h>
int main(void) {
int16_t raw = -185; /* -18.5 °C in tenths of a degree */
printf("Temperature: %.1f C (%zu bytes)\n", raw / 10.0, sizeof raw);
return 0;
}Practice (0/3 done)
On a typical 64-bit Linux system, what does printf("%zu", sizeof(long)) print?
What does printf("%d\n", 010 + 1); print?
C's fixed-size integers wrap around. JavaScript has typed arrays with the same behaviour, which run here: write wrapUint8(n) that returns what a C uint8_t would hold after storing n (use a Uint8Array), and wrapInt8(n) for int8_t (Int8Array).
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Input and output: printf and scanfGetting started with C · same module
- Compiling with gccGetting started with C · same module
- Variables, types and constantsC++ Programming (modern C++ and DSA) · First steps: compiling, output, variables and input
- Addresses and pointersPointers
- Type conversion and castingOperators and control flow
- Variables and primitive typesJava Programming (Core to Spring Boot) · Getting started with Java
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which size is guaranteed to be 1 on every platform?
Answer: sizeof(char)
sizeof(char) is 1 by definition.
Which printf format prints a size_t?
Answer: %zu
%zu (C99).
Which header provides int32_t and uint8_t?
Answer: <stdint.h>
stdint.h has the fixed-width types.
int x; printf("%d", x); inside main prints…
Answer: An unpredictable value (undefined behaviour)
Local variables are not initialised.
What is in an int variable declared inside main with int n; and no value?Related
Answer: Garbage: reading it is undefined behaviour
Local variables are not set to zero automatically. Always initialise them.
On a typical 64-bit system, sizeof(char *) is…Related
In char a = 100, b = 100; int c = a + b; what is c?Related
Which type should hold true or false?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Getting started with C” before its exam: Input and output: printf and scanf.
- Module 1 exam: Getting started with C · 12 questions · 20 min, without help. 5 topics of this module still to finish first.
- Then the next module, Operators and control flow. 60 topics left in the course before the final exam.