C/C++ Arena

Step 2 of 7

static functions and variables

static is one of C's most overloaded keywords. It has two jobs, and both are about keeping things hidden or contained.

1. On functions and globals: private to the file

A function or global variable marked static has internal linkage: its name is only visible inside its own .c file. Other files can't call it, and two files can each have their own static int helper(void) without the linker complaining about a duplicate. Professional code marks every function that isn't part of the header's public interface as static. It keeps the public surface small and avoids name clashes across a big program.

2. On local variables: keeps its value between calls

A static local variable is created once, when the program starts, and keeps its value from one call of the function to the next. Its initializer runs only once. A normal local is created fresh on every call.

#include <stdio.h>

static int square(int x) {
    return x * x;
}

int calls(void) {
    static int count = 0;
    int fresh = 0;
    count++;
    fresh++;
    printf("count %d, fresh %d\n", count, fresh);
    return count;
}

int main(void) {
    calls();
    calls();
    calls();
    printf("%d\n", square(calls()));
    return 0;
}
count 1, fresh 1
count 2, fresh 1
count 3, fresh 1
count 4, fresh 1
16

count remembers between calls; fresh starts over every time.

Static locals are handy for counters, ID generators and caches, but use them sparingly: hidden state makes functions harder to test (calling twice gives different results) and isn't safe when several threads call the function at once.

Your task

Write int next_ticket(void) that returns 1, 2, 3, ... on successive calls, using a static local. Also write a private static helper pad3(int n) returning n % 1000, and use it so tickets wrap back to 0 after 999.

Challenge 2

Write int roll(void), a dice roll from 1 to 6 made with a simple random-number generator whose state lives in a static variable at file scope, so only this file can see it:

state starts at 1
each call: state = state * 1103515245 + 12345   (unsigned 32-bit, wrapping)
result = ((state >> 16) & 0x7FFF) % 6 + 1

The first four rolls are 3, 5, 4, 2.

Challenge 3

Write const char *next_map(void), which returns "dust2", "mirage", "inferno", then starts again, and void reset_maps(void), which makes the next call return "dust2" again. Both functions share the position, so it must be a static variable at file scope, not a static local.

Previous: Headers and include guards Next: extern and shared state