Variables & Data Types
Values in memoryA variable is a named place in memory, and its type decides how many bytes it gets
and what it can hold. In the lab below you watch variables appear in memory byte by byte,
see a number overflow, and find out why 7 / 2 is 3 in C.
- Sizeschar 1 · int 4 · double 8 bytes
- int / intgives an int: 7 / 2 = 3
- consta value that cannot change
Ready
Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode
The ideas behind the lab
Exactly what you watched happen, in plain steps.
A variable = a name + a type + a value
A variable is a named place in memory. Its type tells C how many bytes to reserve and how to read them: the same 4 bytes mean something different as an int or as a float. Declare a variable before you use it, and give it a value straight away.
type name = value; int age = 19; // whole number, 4 bytes double price = 49.99; // decimal number, 8 bytes char grade = 'A'; // one character, 1 byte const int DAYS = 7; // read-only
| Type | Size | Holds | Range / precision | printf | Example |
|---|---|---|---|---|---|
| char | 1 byte | one character (a small number) | -128 to 127 | %c | 'A' |
| unsigned char | 1 byte | small non-negative number | 0 to 255 | %d | 200 |
| short | 2 bytes | whole number | -32,768 to 32,767 | %hd | 1200 |
| int | 4 bytes | whole number | about ±2.1 billion | %d | 19 |
| long long | 8 bytes | big whole number | about ±9.2 × 10¹⁸ | %lld | 8000000000LL |
| float | 4 bytes | decimal number | about 7 significant digits | %f | 49.99f |
| double | 8 bytes | decimal number | about 15–16 significant digits | %f (%lf in scanf) | 3.14159 |
Declaring variables
- Write the type, the name, and (best) a first value: int count = 0;
- Names use letters, digits and _ and cannot start with a digit: total_2 is fine, 2total is not.
- C is case-sensitive: age and Age are two different variables.
- Keywords such as int, return or while cannot be used as names.
- A variable without a first value holds garbage — whatever was in that memory before.
Sizes, ranges and overflow
- Each type has a fixed size in bytes; sizeof(type) tells you how many.
- 1 byte = 8 bits, so it can hold 2⁸ = 256 different values.
- unsigned types hold only 0 and up; signed types split the range around 0.
- Going past the range does not stop the program: the value wraps around.
- float and double store most decimals only approximately (0.1 is not exact).
Conversions and constants
- int / int gives an int: 7 / 2 is 3. The decimals are dropped, not rounded.
- If one side is a double, the other is converted and the result is a double.
- A cast converts on purpose: (double) a / b gives 3.5.
- Storing a double in an int cuts off the decimal part: 78.9 becomes 78.
- const makes a variable read-only; #define PI 3.14159 is the older way.
Average of three marks
Every line, explained.
#include <stdio.h>
Brings in printf.
int main(void)
The program starts here.
{
const int SUBJECTS = 3;
A read-only int. Using a name instead of the number 3 makes the code clearer and easy to change.
int maths = 78, science = 85, english = 90;
Three int variables declared on one line, each with a first value.
int total = maths + science + english;
int + int + int is an int: 253.
double average = (double) total / SUBJECTS;
The cast makes total a double first, so the division keeps its decimals: 84.333… Without it the result would be 84.0.
char grade = 'A';
A char holds one character, written in single quotes. Inside it is the number 65.
printf("Total: %d\n", total);
%d prints an int: Total: 253
printf("Average: %.2f\n", average);
%.2f prints a double with 2 decimals: Average: 84.33
printf("Grade: %c\n", grade);
%c prints a char: Grade: A
return 0;
Success.
}
Spot the bug
Mistakes almost every beginner makes — and how to fix them.
Using a variable before giving it a value
int total; total = total + 5;
int total = 0; total = total + 5;
A variable without a first value contains garbage left in memory, so the result is unpredictable.
Expecting decimals from int / int
int a = 7, b = 2; double avg = a / b; // 3.0
int a = 7, b = 2; double avg = (double) a / b; // 3.5
The division happens first, with two ints, so the decimals are gone before the value reaches the double.
The wrong format specifier
double price = 49.99;
printf("%d\n", price);
double price = 49.99;
printf("%.2f\n", price);
printf trusts the specifier: %d reads the bytes of a double as an int and prints nonsense. Use %f for float and double.
Choosing a type that is too small
int population = 8000000000;
long long population = 8000000000LL;
8 billion is bigger than an int can hold (about 2.1 billion). It overflows — use long long for very big whole numbers.
Comparing decimals with ==
double x = 0.1 + 0.2; if (x == 0.3) ... // false!
double x = 0.1 + 0.2; if (fabs(x - 0.3) < 1e-9) ...
0.1 and 0.2 are stored approximately, so the sum is 0.30000000000000004. Compare decimals with a small tolerance (fabs is in math.h).
Check your understanding
Answer each question — you will see the explanation straight away.
How many bytes does a char take?
A char is always exactly 1 byte (8 bits). sizeof(char) is 1 by definition.
What is the value of x after: int x = 9 / 4;
Both numbers are int, so this is integer division: 9 / 4 = 2 and the .25 is dropped.
An unsigned char holds 255. What does it hold after adding 1?
256 needs 9 bits but an unsigned char has 8, so the value wraps around to 0. No error is reported.
Which line gives d the value 3.5?
The cast turns 7 into 7.0 before dividing, so it is a real division. In the last option 7 / 2 is already 3 before the cast.
What happens if your program tries to change a const variable?
const variables are read-only. Assigning to one is a compile-time error: "assignment of read-only variable".
Variables & Data Types quiz
Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.