# `const` and `var`

### `const` and `var`

Zig has two kinds of variable declarations:

```zig
const
```

and

```zig
var
```

A `const` declaration creates a name whose value cannot change.

```zig
const year = 2026;
```

A `var` declaration creates a mutable variable.

```zig
var count = 0;
```

The difference is important. Zig prefers immutability when possible.

Consider:

```zig
const std = @import("std");

pub fn main() void {
    const x = 10;
    std.debug.print("{d}\n", .{x});
}
```

This program is correct.

Now try to assign a new value:

```zig
const x = 10;
x = 20;
```

The compiler reports an error. A constant cannot be changed after initialization.

A mutable variable may be assigned another value:

```zig
const std = @import("std");

pub fn main() void {
    var n = 1;

    n = 2;
    n = 3;

    std.debug.print("{d}\n", .{n});
}
```

The output is:

```text
3
```

A declaration must always be initialized.

This is valid:

```zig
const x = 5;
var y = 10;
```

This is not:

```zig
var n; // error
```

Zig does not allow uninitialized local variables unless the programmer explicitly asks for undefined memory.

```zig
var n: i32 = undefined;
```

`undefined` means the value is not initialized. Reading it before writing a value is an error.

Usually you should initialize variables normally.

```zig
var n: i32 = 0;
```

The compiler checks whether a mutable variable is actually mutated.

```zig
var x = 10;
```

If `x` is never changed, the compiler may suggest using `const` instead.

This helps keep programs simpler and safer.

A constant does not mean the data itself is always immutable. It means the binding cannot be changed.

Consider:

```zig
var data = [_]u8{ 1, 2, 3 };

const slice = data[0..];
```

`slice` always refers to the same slice, but the underlying array may still change.

```zig
data[0] = 9;
```

Now `slice[0]` is also `9`.

The constant applies to the name, not necessarily to all reachable memory.

You may also create constant pointers and mutable pointers.

```zig
var x: i32 = 10;

const p = &x;
```

`p` always points to the same location.

But the value at that location may still change:

```zig
p.* = 20;
```

The expression:

```zig
p.*
```

means “the value pointed to by `p`”.

A mutable variable is useful when a value changes over time.

```zig
var sum: i32 = 0;

sum += 1;
sum += 2;
sum += 3;
```

A constant is useful when a value should stay fixed.

```zig
const max_users = 100;
```

Most declarations in Zig programs are constants.

This style has several advantages:

- values cannot change accidentally
- the compiler can reason more precisely
- code is easier to read
- fewer states exist in the program

A small example:

```zig
const std = @import("std");

pub fn main() void {
    const width = 80;
    const height = 25;

    const area = width * height;

    std.debug.print("{d}\n", .{area});
}
```

None of these values need mutation, so `const` is appropriate.

Now consider a loop:

```zig
const std = @import("std");

pub fn main() void {
    var i: usize = 0;

    while (i < 5) : (i += 1) {
        std.debug.print("{d}\n", .{i});
    }
}
```

Here `i` changes during execution, so it must be declared with `var`.

Use `const` by default. Use `var` only when mutation is necessary.

Exercises:

1. Declare a constant named `pi` with value `3.14`.

2. Declare a variable named `count`, increment it three times, then print it.

3. Write a program that swaps the values of two mutable variables.

4. Create a mutable array and a constant slice that refers to it. Modify the array and print the slice contents.

5. Declare a variable with `undefined`, assign a value later, then print it.

