C LANGUAGE
Complete Reference Guide
From Variables to File Handling — with Code Examples
What is C? C is a powerful, low-level programming language created by Dennis Ritchie in 1972. It sits
close to hardware, giving you control over memory and performance — which is why it's used in
operating systems, embedded systems, and anywhere speed matters. This document covers every
concept from your practice files, with clear explanations and real code from your own work.
How to read this guide: Each section tells you WHAT the concept does, WHY it matters, and shows
HOW with actual code. Code blocks are dark-background snippets you can copy directly.
1. Structure of a C Program
Every C program follows the same skeleton. Understanding this skeleton means you never start from a
blank page.
Minimal C Program
#include <stdio.h> // Step 1: Include a header file
int main() { // Step 2: main() — every program starts here
// your code here // Step 3: Write your logic
return 0; // Step 4: Tell OS: all went fine
}
Part What it means
#include <stdio.h> Loads printf(), scanf() functions
int main() Entry point — OS calls this first
return 0; 0 = success, anything else = error
{ } Curly braces wrap a block of code
The compiler reads your file top-to-bottom. Declare before you use — functions,
NOTE
variables, everything.
1.1 Comments
Comments are notes for humans. The compiler ignores them completely.
[Link] → code
// This is a single-line comment
/* This is a
multi-line comment */
int age = 21; // inline comment — sits after code
TIP Keyboard shortcuts in VS Code: Ctrl+/ for single-line, Ctrl+Shift+/ for multi-line.
1.2 Preprocessor Directives
Lines starting with # are handled before compilation. The two most important are:
definepre.c
#include <stdio.h> // Pull in a header file (library)
#define PI 3.1415 // Create a constant — PI is replaced everywhere
#define circleArea(r) (PI*r*r) // Macro — like a mini function
int main(){
printf("%lf", PI); // prints 3.141500
printf("Area: %lf", circleArea(12.4)); // works like a function call
}
Directive Purpose
#include <file.h> Standard library (angle brackets)
#include "file.h" Your own header (quotes)
#define NAME value Constant replacement
#define FUNC(x) (expr) Macro — inline substitution
WARN Macros have no type checking. Prefer const int for simple constants in modern code.
2. Variables and Data Types
A variable is a named box in memory that holds a value. The data type tells C: how big the box should
be, and what kind of value fits inside.
datatype.c + variables.c
#include <stdio.h>
int main() {
int age = 25; // 4 bytes — whole numbers
double number = 12.45; // 8 bytes — precise decimals
float number1 = 10.9f; // 4 bytes — less precise decimals (note: f
suffix)
char character = 'z'; // 1 byte — single character
printf("Age: %d", age); // %d = integer
printf("%.2lf", number); // %.2lf = double, 2 decimal places
printf("%f", number1); // %f = float
printf("%c", character); // %c = character
printf("%d", character); // %d on char prints ASCII value: 122
printf("%zu", sizeof(age)); // prints 4 — bytes used
return 0;
}
Data Type Size / Format Specifier / Range
int 4 bytes | %d | -2,147,483,648 to
2,147,483,647
double 8 bytes | %lf | 15-16 decimal digits
precision
float 4 bytes | %f | 6-7 decimal digits
precision
char 1 byte | %c | ASCII 0-127 (or -128
to 127 signed)
long 8 bytes | %ld | Bigger integer range
short 2 bytes | %hd | Smaller integer
range
Format Specifiers Quick Reference
Specifier Prints what
%d int (decimal)
%lf double
%f float
%c char (character)
%s char array (string)
%p pointer address (hexadecimal)
%zu size_t (from sizeof)
%.2lf double with 2 decimal places
%.1f float with 1 decimal place
Variable Naming Rules
• No spaces — use camelCase: myAge, firstName
• Cannot start with a number: 1age is invalid, age1 is fine
• Cannot use C keywords: int, return, if, etc. as names
• Case-sensitive: Age and age are different variables
variables.c
// Changing a variable:
int age = 25;
printf("%d", age); // 25
age = 31; // overwrite
printf("%d", age); // 31
// Assign one variable to another:
int first, second = 21;
first = second; // first now holds 21
Boolean Type
C doesn't have a built-in true/false keyword by default. You need to include <stdbool.h>.
boolean.c
#include <stdbool.h>
bool value1 = true; // prints as 1
bool value2 = false; // prints as 0
printf("%d", value1); // use %d format — there's no %b in C
3. Operators
3.1 Arithmetic Operators
operators.c
int a = 12, b = 8;
double c = 12.0, d = 8.0;
printf("%d", a + b); // 20 — addition
printf("%d", a - b); // 4 — subtract
printf("%d", a * b); // 96 — multiply
printf("%d", a / b); // 1 — integer division (truncates!)
printf("%lf", c / d); // 1.5 — double division (precise)
printf("%d", a % b); // 4 — remainder (modulo)
a++; // a becomes 13 — increment by 1
a--; // a becomes 12 — decrement by 1
Integer division always truncates: 12/8 gives 1, not 1.5. To get 1.5, at least one
WARN
operand must be a double/float.
NOTE The % (modulo) operator only works with integers. printf("%f", 12%8) is invalid.
3.2 Comparison Operators
Comparison operators return true (1) or false (0). Used in conditions.
comparison.c
bool val1 = (12 > 9); // 1 (true) — greater than
bool val2 = (5 > 9); // 0 (false)
bool val3 = (5 < 9); // 1 (true) — less than
bool val4 = (9 <= 9); // 1 (true) — less than or equal
bool val5 = (9 == 9); // 1 (true) — equal (double = !)
bool val6 = (9 != 9); // 0 (false) — not equal
3.3 Logical Operators
logical.c
int age = 16; double height = 6.3;
// && (AND) — both must be true
bool result = (age == 18) && (height > 6.0); // false && true = false
// || (OR) — at least one must be true
bool r2 = (age == 16) || (height > 7.0); // true || false = true
// ! (NOT) — flips the value
bool r3 = !(age == 16); // !true = false
3.4 Ternary Operator (Shortcut if-else)
condition ? value_if_true : value_if_false
ternary.c + ternary2.c
int age = 2;
(age >= 18) ? printf("Eligible") : printf("Not Eligible");
// Reads as: if age >= 18, print Eligible, else print Not Eligible
// More complex example:
char opr = '+';
int a = 8, b = 7;
int result = (opr == '+') ? printf("%d", a+b) : printf("%d", a-b);
4. Type Conversion
C automatically converts types in some situations (implicit), or you can force it (explicit/cast).
4.1 Implicit Conversion (Automatic)
C promotes smaller types to larger ones automatically in expressions.
typeconversion.c
char a = '5'; // '5' has ASCII value 53
int b = 9;
double c = 5.67;
int result = a + b; // 53 + 9 = 62 (char promoted to int)
double result1 = b + c; // 9.0 + 5.67 = 14.67 (int promoted to double)
int result2 = b + c; // 14.67 truncated to 14 (decimal dropped!)
Hierarchy (highest wins) Note
long double Widest / most precise
double Standard decimal
float Smaller decimal
long Big integer
int Standard integer
short Small integer
char Narrowest
4.2 Explicit Conversion (Casting)
You force a conversion by writing the target type in parentheses before the value.
typeconversion2.c
int a = 9, b = 2;
double c = a / b; // 4.000000 — integer division first, then stored
double d = (double)a / b; // 4.500000 — cast a to double BEFORE dividing
double e = 3.57, f = 8.57;
double g = (int)(e + f); // 12.14 → cast to int → 12 → stored as 12.0
double h = (int)e + (int)f; // 3 + 8 = 11 → stored as 11.0
WARN Casting to int always truncates (not rounds). (int)3.99 gives 3.
char Overflow — An Interesting Case
A signed char can only hold -128 to 127. Assigning 130 causes overflow.
info_char.txt
char character = 130;
printf("%d", character); // prints -126
// 130 in binary: 10000010
// In two's complement (signed): this is -126
5. User Input
scanf() reads input from the user. The & symbol gives scanf the memory address where it should store
the value.
taking_inputs_user.c
#include <stdio.h>
int main() {
int age;
printf("Enter your age: ");
scanf("%d", &age); // & = 'address of age' — where to store the value
printf("Age: %d", age);
// Multiple inputs:
double num; char alp;
printf("Enter a number and letter: ");
scanf("%lf %c", &num, &alp); // space between means skip whitespace
return 0;
}
Why the & symbol?
scanf() needs to know WHERE in memory to write your value. &age means 'the address of the
variable age'. Without &, you're passing the value of age (which could be garbage), not where
to put the new value. This is one of the most common beginner mistakes in C.
scanf("%s", str) stops at spaces! To read a full name like 'Anumay Rai', use fgets(str,
WARN
sizeof(str), stdin) instead.
6. Conditions and Decision Making
6.1 if / else if / else
if_elseif_else.c
int age;
scanf("%d", &age);
if (age < 13) {
printf("Children");
}
else if (age >= 13 && age < 18) {
printf("Teenagers");
}
else if (age >= 18 && age < 60) {
printf("Adults");
}
else {
printf("Senior Adults");
}
6.2 switch Statement
Use switch when you're comparing one variable against many fixed values.
switch.c
int a;
scanf("%d", &a);
switch(a) {
case 1: printf("Sunday"); break;
case 2: printf("Monday"); break;
case 3: printf("Tuesday"); break;
// ... cases 4-7 ...
default: printf("Invalid");
}
Fall-through Behaviour
If you omit break, execution falls through to the next case. This is actually useful for grouping
cases together:
switch2.c — Grouping cases
switch(a) {
case 2:
case 3:
case 4:
case 5:
case 6: printf("Weekday"); break; // cases 2-6 all reach here
case 1:
case 7: printf("Weekend"); break; // cases 1 and 7 reach here
default: printf("Invalid");
}
7. Loops
Loops repeat a block of code. C has three types — each suited for different situations.
7.1 for Loop — when you know how many times
for.c / for2.c / for3.c
// for(init; condition; update)
for (int i = 0; i <= 100; i++) {
count = count + i; // sums 0 to 100
}
// Count by 2s (even numbers):
for (int i = 0; i <= 100; i += 2) { ... }
// Count odd numbers:
for (int i = 1; i <= 100; i += 2) { ... }
7.2 while Loop — when condition controls repetition
while2.c — multiplication table
int count = 1, num;
scanf("%d", &num);
while (count <= 10) { // check FIRST, then execute
printf("%d X %d = %d\n", num, count, num*count);
count++;
}
7.3 do-while Loop — runs AT LEAST once
dowhile.c
int count = 11, num;
scanf("%d", &num);
do {
printf("%d X %d = %d\n", num, count, num*count);
count++;
} while (count < 11); // condition checked AFTER — runs once even if false
// This is called an 'exit-controlled loop'
Loop type Use when
for You know exact iteration count
while Repeat as long as something is true
do-while Must execute at least once (e.g.,
menu)
7.4 break Statement
break exits a loop immediately. Useful for stopping an infinite loop on a condition.
breakst.c
while(1) { // infinite loop (condition always true)
int a;
scanf("%d", &a);
if(a > 0) { printf("Positive\n"); }
else if(a < 0) { printf("Negative\n"); }
else { printf("Zero\n"); break; } // exits loop when a==0
}
Loop Example — Multiplication Table
numbertable.c
int num = 7;
for (int count = 1; count <= 10; count++) {
printf("%d X %d = %d\n", num, count, num*count);
}
// Outputs: 7 X 1 = 7 ... 7 X 10 = 70
8. Functions
A function is a named, reusable block of code. Functions make programs modular — write once, call
many times.
function.c
// Syntax: returnType functionName(parameters) { body }
void greet() { // void means: returns nothing
printf("Good Morning");
}
int main() {
printf("Before\n");
greet(); // call the function
printf("After");
return 0;
}
8.1 Functions with Parameters
function2.c
void square_area(int a) { // a is a parameter (input)
int result = a * a;
printf("Area = %d", result);
}
int main() {
int side;
scanf("%d", &side);
square_area(side); // pass side as argument
}
8.2 Functions that Return Values
funcwithret.c
int square_area(int a) { // return type is int
int result = a * a;
return result; // send value back to caller
}
int main() {
int side = 5;
int result = square_area(side); // capture returned value
printf("Area = %d", result); // 25
}
8.3 Multiplication with Function (Two Parameters)
Multiplication.c
int mul(int a, int b) {
return a * b;
}
int main() {
int a, b;
scanf("%d,%d", &a, &b); // input format: 2,3
int result = mul(a, b);
printf("%d * %d = %d", a, b, result);
}
8.4 Local vs Global Variables
localglobal.c
int a = 20; // GLOBAL — accessible everywhere
void fun() {
printf("Function: %d\n", a); // sees global a
}
int main() {
fun(); // prints 20
a = 10; // modifying the GLOBAL a
fun(); // now prints 10
printf("Main: %d\n", a); // 10
}
Variable Type Where usable / When destroyed
Local variable Only inside the function it's
declared / When function returns
Global variable Anywhere in the file / When program
ends
When a local and global variable have the same name, the local one wins inside that
NOTE
function.
8.5 Standard Library Functions
These are pre-built functions in C. You just include the right header file.
Header / Function Does what
<stdio.h> printf() Print to screen
<stdio.h> scanf() Read user input
<math.h> sqrt(x) Square root of x
<math.h> cbrt(x) Cube root of x
<math.h> pow(a,b) a raised to power b
<ctype.h> toupper(c) Convert char to uppercase
<ctype.h> tolower(c) Convert char to lowercase
<string.h> strlen(s) Length of string s
<string.h> strcpy(d,s) Copy string s into d
<string.h> strcat(a,b) Concatenate b onto a
<string.h> strcmp(a,b) Compare a and b
<stdlib.h> malloc(n) Allocate n bytes on heap
<stdlib.h> free(ptr) Release heap memory
square_root.c + slf.c
#include <math.h>
float r = sqrt(25); // r = 5.0
printf("Answer = %lf", pow(a, sqrt(b))); // a^(sqrt(b))
9. Recursion
Recursion is when a function calls itself. Every recursive solution needs: (1) a base case to stop, and
(2) a step that moves toward the base case.
fact.c — Factorial
int fact(int n) {
if (n == 1) {
return 1; // BASE CASE — stop here
}
return fact(n-1) * n; // RECURSIVE STEP — call self with smaller n
}
int main() {
int num;
scanf("%d", &num);
printf("Factorial of %d! = %d", num, fact(num));
}
// fact(5) = fact(4)*5 = fact(3)*4*5 = fact(2)*3*4*5 = 1*2*3*4*5 = 120
How recursion works (fact(5))
fact(5) calls fact(4) fact(4) calls fact(3) fact(3) calls fact(2) fact(2) calls fact(1) → returns
1 fact(2) returns 1*2 = 2 fact(3) returns 2*3 = 6 fact(4) returns 6*4 = 24 fact(5) returns 24*5
= 120
Always have a base case. Without it, recursion runs forever and crashes with a stack
WARN
overflow.
10. Arrays
An array stores multiple values of the SAME type in consecutive memory locations. Think of it as
numbered boxes.
array.c
// Syntax: datatype arrayName[size];
int age[5] = {21, 22, 23, 24, 25}; // declare and initialize
// Access with index (0-based):
printf("age[0] = %d\n", age[0]); // 21
printf("age[2] = %d\n", age[2]); // 23
// Modify:
age[2] = 60; // now age = {21, 22, 60, 24, 25}
// Loop through:
for (int i = 0; i < 5; i++) {
printf("age[%d] = %d\n", i, age[i]);
}
Index starts at 0. An array of size 5 uses indices 0,1,2,3,4. Accessing index 5 reads
WARN
garbage memory — no crash warning, just wrong data.
10.1 User Input into Array
array2.c
int age[5];
printf("Enter 5 ages:\n");
for (int i = 0; i < 5; i++) {
scanf("%d", &age[i]); // & needed for each element
}
10.2 Multi-dimensional Arrays (2D)
A 2D array is like a table — rows and columns.
multiarray.c
// Syntax: datatype name[rows][cols];
int arr[2][3] = {{1,2,3},{4,5,6}};
// Access with two indices:
printf("%d", arr[0][1]); // 2 (row 0, col 1)
printf("%d", arr[1][2]); // 6 (row 1, col 2)
// Nested loop to print all:
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
}
}
11. Strings
A string in C is just a char array ending with a special null character \0. There's no built-in string type
like in Python or Java.
string.c + string2.c
char str[] = "Hello world!"; // automatically adds '\0' at end
printf("%s", str); // prints: Hello world!
// Access individual characters like array:
printf("%c", str[0]); // H
printf("%c", str[4]); // o
// Modify a character:
str[0] = 'J';
printf("%s", str); // Jello world!
11.1 Reading Strings with Spaces
string2.c
char str[100];
// scanf("%s", str); // STOPS at space — won't capture full name
fgets(str, sizeof(str), stdin); // reads the WHOLE LINE including spaces
printf("Your name is %s", str);
11.2 String Functions (string.h)
strfun.c
#include <string.h>
char lang[] = "C Programming";
// Length:
printf("%zu", strlen(lang)); // 13
// Copy:
char copy[20];
strcpy(copy, lang); // copy now holds "C Programming"
// Concatenate:
char a[] = "Hey,";
char b[] = "How are you?";
strcat(a, b); // a is now "Hey,How are you?"
// Compare:
int result = strcmp("apple", "banana");
// result < 0 if apple < banana alphabetically
// result > 0 if apple > banana
// result = 0 if equal
12. Pointers
A pointer is a variable that stores a MEMORY ADDRESS instead of a value. This is one of C's most
powerful (and tricky) features.
The key idea
Every variable is stored somewhere in RAM. That location has an address (like a house
address). A pointer holds that address — so you can go to the variable and change it directly.
pointer_new.c
int var = 32;
int* ptr = &var; // ptr stores the ADDRESS of var
// int* means 'pointer to int'
// &var means 'address of var'
printf("%d", var); // 32 — value
printf("%p", &var); // 0x61fe04 — address (example)
printf("%p", ptr); // same address
printf("%d", *ptr); // 32 — *ptr DEREFERENCES: 'go to that address'
Symbol Meaning
&var Address of variable var
int* ptr Declare ptr as a pointer to int
*ptr Dereference — value AT the address
in ptr
12.1 Changing a Variable via Pointer
pointer2.c
void change(int* num) { // receives the ADDRESS of a variable
*num = 39; // goes to that address and writes 39
}
int main() {
int number = 21;
change(&number); // pass the address of number
printf("%d", number); // 39 — the original was changed!
}
This is how C functions can 'return' multiple values — pass pointers and modify
NOTE
through them.
12.2 Pointer Arithmetic
pointer.c
int nums[5] = {1,3,5,7,9};
// Array name IS a pointer to first element:
printf("%p", nums); // address of nums[0]
printf("%p", nums+2); // address of nums[2] (moved 2 ints forward)
// Access elements via pointer arithmetic:
printf("%d", *(nums)); // 1 — same as nums[0]
printf("%d", *(nums+2)); // 5 — same as nums[2]
// Modify via pointer:
*nums = 89; // nums[0] = 89
*(nums+2) = 89; // nums[2] = 89
12.3 Functions Returning Pointers
ret_point.c + square_pointer.c
int* findSquare(int* number) {
int square = *number * *number;
*number = square;
return number; // returns the address back
}
int main() {
int number = 21;
int* result = findSquare(&number);
printf("Result is %d", number); // 441
}
13. Structures (struct)
A struct groups related variables of DIFFERENT types under one name. Think of it like making your
own data type.
structure.c
// Define a struct (like a template):
struct Person {
double salary;
int age;
};
int main() {
struct Person person1; // create a Person
[Link] = 21; // access with dot operator
[Link] = 4321.78;
printf("Age: %d\n", [Link]);
printf("Salary: %.2lf\n", [Link]);
}
13.1 Shortcut: Declare Variables with struct
struct2.c
struct Person {
double salary;
int age;
} person1, person2; // declare instances right after definition
// Initialise with designated initializers:
struct Person p = {.age = 21, .salary = 4321.78};
13.2 typedef — Remove the 'struct' Keyword
struct_typedef.c
typedef struct Person {
double salary;
int age;
} person; // 'person' is now a type alias
int main() {
person person1; // no need to write 'struct Person'
[Link] = 21;
[Link] = 4321.78;
}
13.3 Practical struct Example — Complex Numbers
diff_comp.c
typedef struct Complex {
double real;
double imag;
} comp;
int main() {
comp comp1 = {.real=21.09, .imag=22.09};
comp comp2 = {.real=17.21, .imag=10.34};
comp compd = {.real=0, .imag=0};
[Link] = [Link] - [Link];
[Link] = [Link] - [Link];
printf("(%.2lf+j%.2lf) - (%.2lf+j%.2lf) = (%.2lf+j%.2lf)",
[Link], [Link], [Link], [Link],
[Link], [Link]);
}
14. Enumerations (enum)
An enum creates a set of named integer constants. It makes code more readable — instead of 0, 1, 2,
you write Small, Medium, Large.
enum.c
enum Size { // defines named constants
Small, // = 0 (default starts at 0)
Medium, // = 1
Large, // = 2
ExtraLarge // = 3
};
int main() {
enum Size shoeSize;
shoeSize = Small;
printf("%d", shoeSize); // prints 0
}
14.1 Enum with Custom Values
enum2.c
enum Size {
Small = 31,
Medium = 34,
Large = 37,
ExtraLarge = 40
} shoeSize1, shoeSize2; // declare instances with definition
shoeSize1 = Small;
printf("%d\n", shoeSize1); // 31
15. Dynamic Memory Allocation
Normal variables are stored on the stack (fixed size, managed automatically). Dynamic memory is on
the heap — you control when it's allocated and freed.
Stack vs Heap
Stack: fast, automatically managed, limited size. Used for local variables. Heap: larger, you
manage it manually with malloc/free. Used when size isn't known at compile time.
15.1 malloc — Allocate Memory
memoryallocation.c
#include <stdlib.h>
int n = 4;
int* ptr;
ptr = (int*) malloc(n * sizeof(int)); // allocate space for 4 ints
// malloc returns void* — cast to int* so we can use it as int pointer
if (ptr == NULL) { // ALWAYS check — malloc can fail
printf("Memory allocation failed");
return 0;
}
for (int i = 0; i < n; i++) {
scanf("%d", ptr+i); // fill memory
}
for (int i = 0; i < n; i++) {
printf("%d\n", *(ptr+i)); // read memory
}
free(ptr); // ALWAYS free when done — prevents memory leak
Every malloc() must have a matching free(). Forgetting free() causes memory leaks
WARN
— your program uses more and more RAM until it crashes.
15.2 realloc — Resize Memory
reallocatemem.c
int n = 4;
int* ptr = (int*) malloc(n * sizeof(int));
// ... later, need more space ...
n = 6;
ptr = realloc(ptr, n * sizeof(int)); // resize to hold 6 ints
// realloc may move the memory block — ptr gets new address
free(ptr);
16. File Handling
C can read from and write to files on disk using FILE pointers.
16.1 Writing to a File
filehandlingwrite.c
#include <stdio.h>
int main() {
FILE* fptr;
fptr = fopen("[Link]", "w"); // 'w' = write (creates/overwrites)
fputs("I Love C Programming\n", fptr);
fputs("C Programming series helps learning", fptr);
fclose(fptr); // ALWAYS close the file
return 0;
}
16.2 Reading from a File
filehandling.c
#include <stdio.h>
int main() {
FILE* fptr;
fptr = fopen("[Link]", "r"); // 'r' = read
char content[1000];
if (fptr != NULL) {
while (fgets(content, 1000, fptr)) { // fgets reads one line
printf("%s", content);
}
} else {
printf("File Open Unsuccessful"); // file not found
}
fclose(fptr);
return 0;
}
Mode Meaning
"r" Read — file must exist
"w" Write — creates new / overwrites
existing
"a" Append — adds to end of existing
file
"r+" Read and write
Always check if fptr != NULL before using it. If fopen fails (file not found), fptr will be
WARN
NULL and accessing it causes a crash.
17. sizeof Operator
sizeof tells you how many bytes a data type or variable occupies in memory. This is useful when
allocating memory and when understanding data sizes.
datatype.c + sizeoffun.c
printf("Size of int: %zu bytes\n", sizeof(int)); // 4
printf("Size of double: %zu bytes\n", sizeof(double)); // 8
printf("Size of char: %zu bytes\n", sizeof(char)); // 1
printf("Size of float: %zu bytes\n", sizeof(float)); // 4
printf("Size of long: %zu bytes\n", sizeof(long)); // 8
int age = 25;
printf("Size of age: %zu bytes\n", sizeof(age)); // 4
NOTE Use %zu (not %d) for sizeof results — the return type is size_t, an unsigned type.
18. Concepts Summary — Quick Reference Card
Concept One-liner
Variable Named box in memory holding a value
Data type What kind of value + how much space
printf / scanf Print to screen / Read user input
if / else Run code based on a condition
switch Compare one value against many cases
for loop Repeat a fixed number of times
while loop Repeat while condition is true
do-while loop Run first, check condition after
break Exit a loop immediately
Function Reusable named block of code
void function Function that returns nothing
return type What data type the function gives
back
Local variable Exists only inside its function
Global variable Exists everywhere in the file
Recursion Function calling itself with base
case
Array Multiple same-type values in one
name
String char array ending with \0
Pointer Variable storing a memory address
& operator Get address of a variable
* operator Dereference — value at address
struct Group different types under one name
typedef Create a type alias for cleaner
syntax
enum Set of named integer constants
malloc / free Allocate / release heap memory
realloc Resize a heap allocation
FILE* Handle for reading/writing files
#define Preprocessor constant / macro
sizeof Bytes used by a type or variable
Type casting Force convert one type to another
19. Common Mistakes to Avoid
• Forgetting & in scanf: scanf("%d", age) → wrong | scanf("%d", &age) → correct
• = vs ==: if (age = 18) assigns, doesn't compare. Use if (age == 18)
• Array out of bounds: int a[5]; — valid indices are 0..4 only. a[5] is undefined
• Integer division: 9/2 = 4 not 4.5. Cast to (double) if you need decimals
• Missing break in switch: Falls through all remaining cases unless break stops it
• Using string without null char: Always let C manage \0 automatically with char str[] = "..."
• Not freeing malloc: Every malloc() needs free() to avoid memory leak
• Not checking NULL after fopen: File may not exist — always check if (fptr != NULL)
• scanf("%s") with spaces: Use fgets() to capture full lines with spaces
• Returning local variable address: Local variables die when function returns — don't return
their address
— End of C Language Reference Guide —