Dataslope logoDataslope

Variables and Memory

What a variable really is, where it lives, and how to think about it as a labelled box in RAM

A variable in C is a name attached to a piece of memory. Behind the friendly name is a fixed-size box of bytes at a specific address.

That mental model — variable = labelled box in memory — will guide every chapter from now on.

Declaring a variable

The minimum recipe for a variable is:

type name;            // declare, value is undefined
type name = value;    // declare and initialize

Examples:

Code Block
C 17 (201710L)

Three things happen on the line int age = 30;:

  1. Reserve memory. The compiler picks 4 bytes (on a typical system) somewhere in memory to hold the value.
  2. Bind the name. From now on, every occurrence of age in this scope refers to those 4 bytes.
  3. Initialize. The bit pattern for 30 is written into those bytes.

Picture it

After the two declarations above, memory might look like:

Address      Variable          Value (decimal)
----------   ---------------   --------------
0x7ffc...0   age               30
0x7ffc...4   year_of_birth     1995

Each box is 4 bytes. The actual addresses are not predictable across runs — they depend on the OS, the architecture, and security features like ASLR. But the shape is reliable.

Assignment versus declaration

Once a variable has been declared, you can change its value with the = operator. The type is not repeated.

Code Block
C 17 (201710L)

That last line, score = score + 5;, is a great example of sequential thinking. The right-hand side is evaluated first, producing the new value 15, which is then stored back into score. C is full of these "read, compute, write" patterns.

Read versus write

When score appears on the left of =, you are writing to it. When it appears on the right, or in an expression, you are reading from it.

score = score + 5;
  ^         ^
  |         +-- read
  +------------ write

Naming variables

Variable names in C:

  • May contain letters, digits, and underscores _.
  • Must not start with a digit.
  • Are case-sensitiveScore, score, and SCORE are three different variables.
  • Cannot collide with C keywords (int, if, return, ...).
  • Should be descriptive. n is fine for a loop counter; score is better than s for a score.
int score;            // good
int playerScore;      // also fine (camelCase)
int player_score;     // fine (snake_case — more common in C)
int 1st_score;        // ERROR: starts with a digit
int return;           // ERROR: keyword

A style note

The C ecosystem traditionally uses `snake_case` for variable and function names (`player_score`, `compute_total`). Pick a style and stay consistent within a project. Consistency matters more than the exact convention.

What "uninitialized" really means

If you declare a variable without giving it a value:

int x;
printf("%d\n", x);   // prints whatever happened to be in memory

…the compiler reserves the memory but does not zero it. The contents are whatever was left there by the previous use of those bytes. The value you read is undefined behavior — the program may print anything, including different values on different runs. Always initialize.

Try it (the exact number printed below is unpredictable and varies between runs and compilers):

Code Block
C 17 (201710L)

Modern compilers will often warn you about this. Pay attention.

Constants

Sometimes you want a name that refers to a fixed value that must never change. There are two common ways.

const marks a variable read-only after initialization:

const int SPEED_OF_LIGHT = 299792458;  // m/s

The compiler will reject any attempt to write to it later.

#define is a textual constant handled by the preprocessor:

#define MAX_PLAYERS 8

Both are useful; const is more strongly typed and easier to debug, so prefer it unless you specifically need a preprocessor macro.

Memory diagram practice

Predict the final values of a and b after this program runs, then run it to check:

Code Block
C 17 (201710L)

This is the classic swap idiom. Trace it with a table:

stepabtmp
start12
int tmp = a;121
a = b;221
b = tmp;211

A common rookie mistake is to try a = b; b = a; without a temporary — but by the time the second line runs, a already holds the new value, so you copy it back into b and lose the original. Always think what's in each box, right now?

Why memory matters even for int

A int on most systems is 4 bytes. That means it can hold values roughly between -2,147,483,648 and +2,147,483,647. Go above that and the value wraps around — a phenomenon called integer overflow.

Code Block
C 17 (201710L)

This is a small but profound lesson: in C, every variable has a finite number of bits. There are no infinite integers, no arbitrary precision. You have to choose a type that fits your data.

We'll meet more types in the next chapter.

Challenge: temperatures

Challenge
C 17 (201710L)
Convert Celsius to Fahrenheit

A variable celsius is set to 25. Compute the equivalent Fahrenheit value using the formula F = C * 9 / 5 + 32 and print exactly:

25 C = 77 F

QuestionSelect one

Which statement best describes a variable in C?

A keyword reserved by the compiler.

An object that grows and shrinks automatically based on the value assigned to it.

A name bound to a fixed-size region of memory whose contents can be read or written.

A function that always returns the most recent value passed to it.

QuestionSelect one

What is wrong with this code?

int x;
int y = x + 1;
printf("%d\n", y);

Nothing — y will always be 1.

The compiler will refuse to build it.

x is uninitialized, so reading it is undefined behavior; y could be anything.

y cannot be initialized from another variable.

On this page