CVariables & Declarations

Variables & Declarations

A variable in C is a named piece of memory that holds a value of a particular type. Unlike dynamically typed languages, C is statically typed: every variable must be declared with an explicit type before it can be used, and that type never changes for the lifetime of the variable. This upfront declaration is what lets the compiler know exactly how many bytes to reserve, how to interpret the bits stored there, and what operations are legal on the value.

Declaration syntax

The basic form of a variable declaration is type name;. You can also declare and initialize a variable in a single statement using type name = value;. Multiple variables of the same type can be declared in one statement by separating the names with commas.

C
#include <stdio.h>

int main(void) {
    int age;          /* declaration only, no value yet */
    age = 25;         /* assignment */

    double price = 19.99;    /* declaration with initialization */
    int x = 1, y = 2, z = 3; /* multiple variables, same type */

    printf("age=%d price=%.2f x+y+z=%d\n", age, price, x + y + z);
    return 0;
}
age=25 price=19.99 x+y+z=6
Declaration before use

C requires every variable to be declared before it is referenced. Historically (in C89/ANSI C), this rule was very strict: all variable declarations in a block had to appear at the very top of that block, before any executable statements. C99 and later standards relaxed this, allowing you to declare a variable anywhere in a block, right before it is first needed.

C89 vs modern C
If you ever work with an old C89-only compiler, remember that declarations must come first in each block. Modern compilers (GCC, Clang, MSVC) default to C99 or later, so mixing declarations and statements freely is normal and considered good style — declare a variable close to where you first use it.

C
int main(void) {
    int total = 0;      /* C99+: fine to declare here */
    for (int i = 0; i < 5; i++) {   /* fine: declare loop variable inline */
        total += i;
    }
    int average = total / 5;        /* also fine, declared where needed */
    return 0;
}
Uninitialized variables contain garbage
Local variables are NOT zero-initialized
A local (automatic) variable that is declared but not explicitly given a value does not start at zero. It contains whatever bit pattern happened to already be sitting in that memory location — often called an indeterminate value or garbage value. Reading an uninitialized variable before assigning it is undefined behavior and a very common source of bugs that appear to work by accident during testing and then fail unpredictably elsewhere.

C
#include <stdio.h>

int main(void) {
    int count;                 /* uninitialized: garbage value */
    printf("%d\n", count);    /* undefined behavior: could print anything */

    int safe_count = 0;        /* always initialize explicitly */
    printf("%d\n", safe_count);
    return 0;
}

Global variables and variables declared with the static keyword behave differently: the C standard guarantees they are automatically zero-initialized if you don't give them an explicit value. Local (automatic) variables get no such guarantee, which is exactly why this distinction matters so much in practice.

Storage

Default value if not initialized

Local (automatic) variable

Indeterminate / garbage

Global variable

Zero (guaranteed)

static local variable

Zero (guaranteed)

Heap memory from malloc

Indeterminate / garbage

Always initialize
A simple habit that eliminates an entire category of bugs: always give local variables an initial value at the point of declaration, even if it's just `0` or `NULL`, unless you have a specific performance reason not to.
  • Declare a variable with type name; before assigning it a value.

  • Combine declaration and initialization with type name = value; whenever possible.

  • Modern C (C99+) allows declarations anywhere in a block, not just at the top.

  • Uninitialized local variables hold garbage — always initialize them explicitly.