Variables & Data Types

In JavaScript you can write let x = 5; and later set x = "hello"; without complaint. In C, that second line won't compile. A C variable isn't just a name for a value — it's a reservation of a specific number of bytes, and the type you declare tells the compiler exactly how many bytes to set aside and how to interpret whatever bits end up in them.

Declaring a variable

Every variable needs a type before it can be used. You can declare it and give it a value in one line, or declare it first and assign later:

</> basics.c
#include <stdio.h>

int main(void) {
    int age = 30;
    float price = 19.99f;
    char grade = 'B';

    printf("Age: %d\n", age);
    printf("Price: %.2f\n", price);
    printf("Grade: %c\n", grade);
    return 0;
}
Output
Age: 30
Price: 19.99
Grade: B

Note the f suffix on 19.99f — without it, C treats a decimal literal as a double, which is a wider type than float. Assigning a double literal into a float variable still works (the compiler narrows it for you), but writing the f makes your intent explicit. Character literals like 'B' always use single quotes; double quotes are reserved for strings, which you'll meet properly in lesson 9.

The core types

C gives you a handful of built-in types, and you build everything else out of them:

  • int — a whole number, typically 4 bytes on modern systems.
  • float — a decimal number with roughly 6-7 significant digits of precision, 4 bytes.
  • double — a decimal number with roughly 15-16 digits of precision, 8 bytes. Use this over float unless you have a specific reason not to (like packing many values tightly in memory).
  • char — a single byte, usually holding one character, but really just a small integer (0-255 or -128 to 127 depending on signedness).

These sizes aren't guaranteed by the language itself — the C standard only promises minimums — but on essentially every desktop and laptop machine you'll compile for, they hold. You can check them yourself with the sizeof operator, which asks the compiler how many bytes a type (or variable) occupies:

</> sizes.c
#include <stdio.h>

int main(void) {
    printf("int: %zu bytes\n", sizeof(int));
    printf("float: %zu bytes\n", sizeof(float));
    printf("double: %zu bytes\n", sizeof(double));
    printf("char: %zu bytes\n", sizeof(char));
    return 0;
}
Output
int: 4 bytes
float: 4 bytes
double: 8 bytes
char: 1 bytes
Note: sizeof returns a value of type size_t, an unsigned integer type meant for sizes and counts. Its matching printf specifier is %zu, not %d — using %d happens to look right on many systems but is technically undefined behavior, since you'd be telling printf to read a type it isn't getting.

Constants

If a value shouldn't change after it's set, say so with const. This doesn't just document intent — the compiler will actually stop you from reassigning it, catching a class of bugs before the program ever runs:

</> circle.c
#include <stdio.h>

int main(void) {
    const double PI = 3.14159;
    double radius = 4.0;

    printf("Area: %.2f\n", PI * radius * radius);
    return 0;
}
Output
Area: 50.27

Try adding a line like PI = 3; after the declaration and recompiling — gcc will reject the program outright with an error about assigning to a read-only variable, rather than letting it slip through and cause a subtle bug later.