Notifications

No notifications

/Phase 1

Variables & Data Types

Storing Data in C 📦

A variable is a named box in memory that holds a value of a specific type. In C, you must tell the compiler the type before you use the variable. This is called declaration.

int   age = 19;        // a 4-byte integer
float price = 9.99f;   // a single-precision decimal
char  grade = 'A';     // a single character (1 byte)
double pi = 3.14159;   // a higher-precision decimal (8 bytes)

The Five Core Types

TypeStoresTypical sizeRange (signed)
charone character (or small int)1 byte-128 to 127
intwhole numbers4 bytes±2.1 billion
floatdecimals (~7 digits)4 bytes±3.4 × 10³⁸
doubledecimals (~15 digits)8 bytes±1.7 × 10³⁰⁸
void"no type"used for functions that return nothing

> Sizes can vary by platform. Use sizeof(type) if you need the truth on your machine.

Type Modifiers

You can stretch or shrink the basic types:

ModifierEffectExample
unsignedonly ≥ 0, doubles the positive rangeunsigned int u = 4000000000;
shortsmaller integer (often 2 bytes)short s = 1000;
longlarger integer (often 8 bytes)long big = 10000000000L;
long longeven larger (≥ 8 bytes)long long n = 9LL;

Format Specifiers in printf / scanf

Typeprintfscanf
int%d%d
float%f%f
double%lf%lf
char%c%c
unsigned int%u%u
long%ld%ld
hex%x%x

> Trap: scanf for double is %lf (not %f). Mixing them up reads garbage.

Naming Rules

  • Letters, digits, underscore. Cannot start with a digit.
  • Case-sensitive: scoreScoreSCORE
  • Cannot be a keyword (int, return, if, …)

Constants

const float PI = 3.14159f;   // can never be changed
#define MAX_USERS 100        // preprocessor constant

On this page

Detailed Theory

Every program is just data + the operations that move data around. Variables are how you give that data a name. In C, the type system is the contract between you and the compiler — once you declare a variable's type, that type is fixed for life.

Declaration vs Definition vs Initialisation

These three words are used interchangeably in casual conversation but they mean different things:

int x;            // declaration  — "x is an int" (memory reserved, value is GARBAGE)
x = 42;           // assignment   — "put 42 into x"
int y = 42;       // definition + initialisation in one step
extern int z;     // declaration only — "z exists somewhere else, trust me"

> Critical rule: an uninitialised local variable in C does not start at zero. It contains whatever bits were sitting in that memory slot. Reading it is undefined behaviour. Always initialise.

int x;
printf("%d", x);   // ❌ might print 0, might print -873652, might crash

How Many Bytes? Use sizeof

Sizes are not fixed by the C standard — they depend on the compiler and platform. To know the truth on your machine:

printf("int   = %zu bytes\n", sizeof(int));
printf("char  = %zu bytes\n", sizeof(char));   // ALWAYS 1 by definition
printf("float = %zu bytes\n", sizeof(float));
printf("double= %zu bytes\n", sizeof(double));

%zu is the format specifier for size_t (an unsigned integer type returned by sizeof).

Signed vs Unsigned — The Bit-Level Story

A signed 8-bit number uses one bit for the sign, so it stores -128 to 127. An unsigned 8-bit number uses all 8 bits for value, so it stores 0 to 255.

unsigned char u = 200;     // fine
signed   char s = 200;     // ⚠️ overflows to -56 (depends on platform)

Why this matters: if you mix signed and unsigned in the same expression, C silently converts the signed value to unsigned — and a negative number becomes a huge positive one.

unsigned int u = 5;
int s = -3;
if (s < u) printf("yes");
else       printf("no");   // ❌ prints "no" — surprising!

s (-3) is converted to a giant unsigned number before the comparison. Lesson: don't mix signed and unsigned.

Floating-Point Is Not Real Numbers

float and double use the IEEE 754 format. They are accurate enough for most things, but not exact:

printf("%.20f\n", 0.1 + 0.2);   // 0.30000000000000004440

This is not a bug in C — it is fundamental to binary floating-point. Never use == to compare floats. Compare the difference instead:

if (fabs(a - b) < 0.0001) {
    // close enough
}

(fabs lives in — link with -lm on Linux.)

char is just a tiny integer

'A' is not a string — it's the integer 65 with the type char.

char c = 'A';
printf("%c %d\n", c, c);   // A 65

You can do arithmetic on chars:

char letter = 'a' + 3;     // 'd'

This is why ASCII tricks work — characters are numbers.

Type Casting — Telling C "Trust Me"

Sometimes you need to convert between types explicitly:

int   total = 7;
int   count = 2;
double avg  = total / count;          // ❌ 3.0 — integer division happens FIRST
double avg2 = (double)total / count;  // ✅ 3.5

The cast (double) happens before the division, so the division becomes float division.

CastEffect
(int)3.93 (truncates, doesn't round)
(double)55.0
(char)65'A'

Constants — Two Ways

const double PI = 3.14159;     // typed constant, lives in memory
#define MAX     1000           // preprocessor — pure text replacement

const#define
Has a type❌ (just text)
Visible in debugger❌ (gone before compilation)
Can be used in array sizes (C99+)❌ in old C
Scopenormal C scopingglobal, until #undef

Rule of thumb: prefer const for values, #define for purely compile-time things and macros.

Putting It Together

#include <stdio.h>

int main(void) { int age = 19; float cgpa = 8.7f; char grade = 'A'; const double PI = 3.14159;

printf("Age : %d\n", age); printf("CGPA : %.2f\n", cgpa); // %.2f → 2 decimal places printf("Grade : %c\n", grade); printf("Pi : %lf\n", PI);

age = age + 1; // variables CAN change // PI = 3.14; // ❌ compile error: assignment of read-only variable return 0; }

Master this and the rest of C reads like a sentence.