Data Types
Why we need data types
Analogy
- Think about a job application form. The age box wants a number. The name box wants letters. "Do you have a driving licence?" gives you a yes or no tick.
- The salary box also wants a number, but this one is allowed decimals.
- You filled it in without thinking, and the form was quietly doing something clever: sorting your information into kinds.
- A computer needs the same thing, only stricter. Before it can store anything, it has to know what kind of thing it is.
What is a data type?
Definition
A data type tells the computer what kind of value it is holding.
It answers two questions. How much room does this need? And what do operations mean on it?
Underneath, memory stores nothing but 0s and 1s. The type is the note that says how to read them.
The same bits, three different answers
This is the idea that makes types click, so it is worth a picture.
Nothing about those thirty-two bits changed between the three answers. The bits do not know what they are. The type is what decides.
Once you have that sentence, almost every strange thing types do stops being strange.
Here is the same idea in a form you will actually type:
| Expression | Result | Because |
|---|---|---|
| 5 + 3 | 8 | Both are numbers, so + adds |
| "5" + "3" | "53" | Both are text, so + joins them end to end |
The five you will use constantly
| Type | Holds | Examples |
|---|---|---|
| Integer | Whole numbers | 7, 0, -25 |
| Float or double | Numbers with decimals | 3.14, -0.5, 99.0 |
| Character | A single symbol | 'A', '7', '#' |
| String | Text of any length | "hello", "A", "" |
| Boolean | Only true or false | true, false |
Almost everything you will ever build starts from these five.
One fact worth knowing early: characters are stored as numbers. 'A' is 65, 'B' is 66, 'a' is 97. That is why you can compare letters and sort words alphabetically. The computer is only ever comparing numbers.
Two traps that catch everybody
Watch out
Integers run out. In most languages an integer gets a fixed amount of room, usually 32 bits, so it can only hold values from about -2.1 billion to +2.1 billion. Go past the top and it does not error: it quietly wraps round to the most negative value, like an odometer rolling over. Python is the exception, and its integers grow as large as memory allows.
Floats are approximate. Some decimal fractions cannot be written exactly in binary, the same way one third cannot be written exactly as a decimal. So the computer stores something extremely close and moves on.
The float one is worth seeing, because it looks like a bug and is not:
0.1 + 0.2# 0.30000000000000004The practical rule that follows: never compare two floats with ==. Ask whether the gap between them is tiny instead.
if abs(a - b) < 0.000001: # close enough to call equalThe empty value
Sometimes a variable exists but holds nothing yet. That state has a name: null in Java and C, None in Python, nil in some others.
Three things that look similar and are not:
0is a number. It has a value.""is an empty string. It has a value, it just has no characters in it.Noneis the absence of any value at all.
Using a None where you expected a real value is one of the most common crashes in software. When you meet the phrase "null pointer exception", this is what happened.
Static and dynamic typing
age = 25 # Python works the type out from the valueage = "hello" # and is happy to change it int age = 25; // Java fixes it, and this next line will not compileage = "hello";Static typing (C, C++, Java) means you announce the type and it never changes. Mistakes get caught before the program runs.
Dynamic typing (Python, JavaScript) means the type comes from the value, and it can change. Faster to write.
Neither is better. They are a trade, and you will use both.
Converting between types
When nothing can be lost, most languages convert for you: 5 + 2.0 gives 7.0, and the 5 quietly became a float.
When something could be lost, you have to ask:
int(3.9) # 3, not 4int("42") # 42str(42) # "42"float("3.5") # 3.5Note
Look at the first line. int(3.9) gives 3, not 4. It chops the decimal off, it does not round. This trips up almost everyone exactly once.
And int("hello") will crash, because there is no sensible number hiding in that text.
Where this is going
The five types above are primitive: each holds one single value.
Composite types are built by combining them, and that is what the rest of this library is about. An array, a stack, a queue, a linked list, a tree: every one of them is a clever arrangement of the simple types on this page.
Mistakes to watch for
Watch out
- Expecting
7 / 2to be3.5everywhere. In C and Java, dividing two integers gives an integer, so you get3. - Comparing floats with
==. See the0.1 + 0.2problem above. - Mixing up
"5"and5. One is text and one is a number. - Assuming an integer can hold any size. It usually cannot.
- Expecting
int()to round. It truncates. - Using
==on strings in Java. It compares memory locations, not the text. Use.equals().
Quick recap
- A type says what kind of value something is
- It decides how much space to reserve and what operations mean
- Memory is only bits, and the type is the label that says how to read them
- The five to know: integer, float, character, string, boolean
- Integers overflow, floats are approximate, and neither warns you
- Every data structure you will meet is built from these
Key takeaway
A type is not the data. It is the instruction for how to read the data.