A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
Every C program is, at its core, a series of labeled boxes in memory. You name a box, you pick its size, and the compiler reserves that many bytes. Get the size wrong and you get silent corruption. Get the name wrong and you get a compile error. One of those is far more dangerous than the other.
C has a small set of built-in types. The ones you will use daily: int (typically 4 bytes, whole numbers), float (4 bytes, single-precision decimal), double (8 bytes, double-precision decimal), and char (1 byte, a single character stored as an integer). You declare a variable by stating the type, then the name, optionally followed by an initializer.
#include <stdio.h>int main(void) {int age = 30;float temperature = 98.6f;double pi = 3.141592653589793;char grade = 'A';printf("age: %d\n", age);printf("temp: %.1f\n", temperature);printf("pi: %.15f\n", pi);printf("grade: %c\n", grade);return 0;}
Compile and run that. The f suffix on 98.6f tells the compiler this literal is a float, not a double. Without it, the literal defaults to double and gets implicitly narrowed when assigned to a float variable. Most compilers will not warn you about this unless you pass -Wconversion. Add that flag to your build if you want stricter checking.
The C standard does not mandate that int is 4 bytes. It mandates that int is at least 2 bytes. On most modern desktop platforms it is 4, but on some embedded microcontrollers it is 2. If you write code that assumes a specific size and then compile for a different target, you get overflow bugs that are nightmares to trace. The sizeof operator tells you the truth for your current platform.
#include <stdio.h>int main(void) {printf("sizeof(int): %zu bytes\n", sizeof(int));printf("sizeof(float): %zu bytes\n", sizeof(float));printf("sizeof(double): %zu bytes\n", sizeof(double));printf("sizeof(char): %zu bytes\n", sizeof(char));return 0;}
Never assume type sizes in production C code. Use the fixed-width types from <stdint.h> (int32_t, uint64_t, etc.) when the exact width matters, such as when parsing binary protocols or writing to hardware registers.
Assign a value too large for the type and C does not throw an exception. It wraps around silently for unsigned types, and invokes undefined behavior for signed types. This is not a quirk. It is the language design. The compiler is allowed to assume signed overflow never happens and optimize accordingly, which means your code can behave in ways that seem impossible if you trigger it.
#include <stdio.h>#include <limits.h>int main(void) {int max = INT_MAX;printf("INT_MAX: %d\n", max);printf("INT_MAX + 1: %d\n", max + 1);return 0;}
That negative number is not a bug in the output. It is two's complement wraparound. On this platform, with this compiler, it wrapped. But the C standard calls this undefined behavior, meaning a different compiler or optimization level could produce anything, including removing the check entirely. Treat signed overflow as a program-ending error in your mental model.
Variables are the atoms of every C program you will write from here forward. Next lesson we cover printf in depth, because printing those variables correctly (and understanding format specifiers) is where most beginner bugs actually live.
Finish the lesson once you have worked through the material. This awards ★ 20 XP.