Variables
A name bound to a value in memory. Assignment rebinds or overwrites; scope decides where the name is visible.
Level: beginner
What is it?
A variable is a name that refers to a value the program can read and change. In C the name labels a fixed slot of memory of a declared size. In Python the name is a reference bound to an object, and rebinding the name does not change the object. Scope decides where a name is visible; lifetime decides how long the value it refers to exists.
Why does it matter?
Almost every 'wrong value' bug is a question about what a name refers to at that moment. Knowing whether assignment copies a value, shares a reference, or mutates in place is the difference between reading code and guessing at it.
Mental model
A labeled box versus a sticky note. In C the label names a box of a certain size, and assigning puts a new value in the box. In Python the label is a sticky note you can move from one object to another, and two notes can point at the same object.
How it works
- Declaration introduces a name; initialization gives it a first value. Reading an uninitialized variable is undefined behavior in C and a NameError in Python.
- Scope: locals live inside a function, globals live in a module. An inner scope can shadow an outer name without changing it.
- Value semantics copy on assignment (numbers in most languages). Reference semantics share (lists and objects in Python, Java, and JavaScript).
- Mutable objects change in place. Immutable ones (numbers, strings, tuples in Python) are replaced when you 'change' them.
- A constant is a variable you promise not to rebind: const in JavaScript, final in Java, UPPER_CASE by convention in Python.
Steps
- Pick a name that says what it holds
- Bind it to a first value
- Read it in expressions
- Rebind or mutate it
- Let it go out of scope
Code example: Rebinding versus mutating
a = [1, 2]
b = a # b is another name for the same list
b.append(3) # mutate through b
print(a) # [1, 2, 3] (a sees the change)
b = [9] # rebind b to a brand-new list
print(a) # [1, 2, 3] (a is unchanged)Real-world usage
- Holding state between steps of a computation
- Naming intermediate results so code reads like the problem
- Configuration values that should be defined once and reused
Common mistakes
- Assuming b = a copies a list; it copies the reference.
- Reusing one name for unrelated values so readers lose track of what it holds.
- Using a mutable default argument in Python (def f(x=[])): the same list is shared by every call.
Interview questions
What is the difference between a shallow and a deep copy?
A shallow copy makes a new container but shares the elements inside it. A deep copy recursively copies the elements too. Mutating a shared nested object through a shallow copy is visible in the original.
What does 'pass by value' mean when the value is a reference?
The function receives a copy of the reference. It can mutate the object the reference points to, but rebinding its parameter does not change the caller's variable. Python and Java both work this way.
What is variable shadowing?
An inner scope declares a name that already exists in an outer scope. Inside the inner scope the new name wins and the outer one is untouched.