C Programming Tutorial for Beginners: Complete 50-Hour Guide from Scratch

Total Duration: 50 Hours | 17 Chapters | 2-3 Hours Per Chapter

c-programming-tutorial-beginners-complete-guide

This C programming tutorial for beginners is your complete roadmap to mastering the C language from absolute scratch. Designed as a comprehensive 50-hour course with 17 structured chapters, this beginner-friendly C programming guide covers everything from basic syntax to advanced topics like pointers, structures, and file I/O. Whether you're starting your programming journey, preparing for technical interviews, or strengthening your coding fundamentals, this step-by-step C tutorial provides hands-on examples, practice exercises, and detailed explanations to transform you into a confident C programmer.

Learning Objectives

Chapter 1 - Introduction to C Programming

Chapter 2 - Your First C Program - Hello World

Chapter 3 - Variables and Constants

Chapter 4 - Operators

Chapter 5 - Input and Output

Chapter 6 - Conditional Statements - if, else

Chapter 7 - Switch Statement

Chapter 8 - Loops - for Loop

Chapter 9 - while and do-while Loops

Chapter 10 - Functions

Chapter 11 - Recursion

Chapter 12 - Arrays - 1D Arrays

Chapter 13 - 2D Arrays

Chapter 14 - Strings

Chapter 15 - Pointers

Chapter 16 - Structures & Unions

Chapter 17 - File I/O Basics

Chapter 1: Introduction to C Programming

What is C Programming?

C is a general-purpose programming language created by Dennis Ritchie at Bell Labs in 1972. It’s called the “mother of all programming languages” because many modern languages are based on C.

Why Learn C?

  • Foundation language: Understanding C makes learning other languages easier.
  • Fast execution: C programs run very quickly.
  • System programming: Used for operating systems, embedded systems.
  • Portable: C programs can run on different computers with minimal changes.

Key Features of C

Feature Description
Simple Easy to learn and understand
Fast Compiled language, executes quickly
Portable Code works on different systems
Low-level access Can work directly with memory
Rich library Many built-in functions available

Setting Up C Programming Environment:

Step 1: Install a C Compiler

For Windows Users

Option A: Code::Blocks (Recommended for Beginners)

  1. Go to codeblocks.org.
  2. Download "codeblocks-20.03mingw-setup.exe" (includes compiler).
  3. Run the installer and follow the setup wizard.
  4. Choose default installation settings.
  5. Launch Code::Blocks to verify installation.

Option B: Dev-C++

  1. Visit sourceforge.net/projects/orwelldevcpp.
  2. Download the latest version.
  3. Install with default settings.
  4. Open Dev-C++ to confirm it works.

Option C: Visual Studio (Advanced)

  1. Download Visual Studio Community (free).
  2. During installation, select "Desktop development with C++".
  3. This includes the MSVC compiler.

For Mac Users

Option A: Xcode (Complete IDE)

  1. Open App Store.
  2. Search for "Xcode".
  3. Click Install (it's free but large ~10GB).
  4. Once installed, open Terminal and type: xcode-select --install.
  5. This installs command-line tools including gcc.

Option B: Terminal with Homebrew (Lightweight)

  1. Open Terminal (Applications → Utilities → Terminal).
  2. Install Homebrew by pasting:
  3. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
  4. Install gcc: brew install gcc.
  5. Verify: gcc --version.

For Linux Users

Most Linux distributions come with gcc pre-installed

Check if gcc is installed:

gcc --version

If not installed:

  • Ubuntu/Debian: sudo apt update && sudo apt install build-essential
  • CentOS/RHEL: sudo yum install gcc
  • Fedora: sudo dnf install gcc
  • Arch Linux: sudo pacman -S gcc

Basic Structure of a C Program

#include <stdio.h>
int main() {
    // Your code goes here  
    return 0;
}

Breakdown

  1. main: The Entry Point of the Program
  2. Every C program must have a main function. It is the designated starting block where the program's execution begins and, typically, where it ends.

  3. int: The Return Type
  4. The int before main specifies the return type of the function. It's a promise that the main function will return an integer value to the operating system when it has finished executing

Line-by-Line Explanation:

Line Purpose
#include <stdio.h> Includes standard input/output functions
int main() Main function where program execution begins
{ Opening brace - starts the function
return 0; Returns 0 to indicate successful program completion
} Closing brace - ends the function

Practice Exercises

Exercise 1: Identify the parts of a C program structure.

Exercise 2: What does #include <stdio.h> do?

Answers:

Answer 1: C program has: header files (#include), main function (int main()), opening/closing braces {}, and return statement.

Answer 2: #include <stdio.h> includes the standard input/output library that contains functions like printf()and scanf().

Chapter 2: Your First C Program - Hello World

What is “Hello World”?

“Hello World” is traditionally the first program every programmer writes. It simply displays the text “Hello World” on the screen.

Code Example 1: Basic Hello World

#include <stdio.h>

int main() {
    printf("Hello World!");
    return 0;
}

Output

Hello World!

Line-by-Line Explanation:

Line Purpose
#include <stdio.h> Includes standard I/O library
int main() { Main function where program execution begins
printf("Hello World!"); Prints text to screen
return 0; Program ends successfully
} End of main function

Code Example 2: Hello World with New Line

#include <stdio.h>

int main() {
    printf("Hello World!\n");
    printf("Welcome to C Programming!");
    return 0;
}

Output

Hello World!

Welcome to C Programming!

Understanding \n:

  • \n is called an escape sequence
  • It creates a new line (like pressing Enter)
  • Always put it inside the quotes

Code Example 3: Multiple Lines at Once

#include <stdio.h>

int main() {
    printf("Hello World!\nWelcome to C Programming!\nLet's start learning!");
    return 0;
}

Output

Hello World!

Welcome to C Programming!

Let's start learning!

Common Escape Sequences

Escape Sequence Purpose Example
\n New line printf("Line 1\nLine 2");
\t Tab space printf("Name:\tJohn");
\" Double quote printf("He said \"Hello\"");
\\ Backslash printf("C:\\Users\\");

Practice Exercises

Exercise 1: Write a program that prints your name and age on separate lines.

Exercise 2: Create a program that displays a simple menu:

=== MAIN MENU ===

1. Start Game

2. Settings

3. Exit

Answers:

Answer 1:

#include <stdio.h>

int main() {
    printf("My name is John\n");
    printf("I am 20 years old");
    return 0;
}

Output

My name is John

I am 20 years old

Answer 2:

#include <stdio.h>

int main() {
    printf("=== MAIN MENU ===\n");
    printf("1. Start Game\n");
    printf("2. Settings\n");
    printf("3. Exit");
    return 0;
}

Output

=== MAIN MENU ===

1. Start Game

2. Settings

3. Exit

Chapter 3: Variables and Constants

What are Variables?

A variable is like a container that stores data. Think of it as a labeled box where you can put different values.

Variable Declaration

data_type variable_name;

Basic Data Types in C

Data Type Description Size Example
int Whole numbers 4 bytes 42, -15, 0
float Decimal numbers 4 bytes 3.14, -2.5
char Single character 1 bytes 'A', '7', '@'
double Large decimal numbers 8 bytes 3.141592653

Code Example 1: Declaring and Using Variables

#include <stdio.h>

int main() {
    int age;           // Declare an integer variable
    float height;      // Declare a float variable
    char grade;        // Declare a character variable
    
    age = 20;          // Assign value to age
    height = 5.8;      // Assign value to height
    grade = 'A';       // Assign value to grade
    
    printf("Age: %d\n", age);
    printf("Height: %.1f feet\n", height);
    printf("Grade: %c\n", grade);
    
    return 0;
}

Output

Age: 20

Height: 5.8 feet

Grade: A

Format Specifiers Explanation:

In C programming, format specifiers are essential placeholders used in input and output functions (like printf()and scanf()) to define the type of data being printed or read. They act as a bridge between the raw binary data stored in variables and the human-readable text displayed on the screen.

Format Specifier Data Type Purpose
%d int Display integer
%f float Display floating-point number
%.1f float Display float with 1 decimal place
%c char Display single character
%s string Display string (text)

Why Format Specifiers are Necessary

  • Computers store data in binary format (1s and 0s).
  • The printf()and scanf() functions need to know how to interpret this binary data and convert it into a meaningful format for display or storage.

Declare a variable

int age = 25;

The integer 25 is stored in memory as 00011001. Without instructions, the computer doesn't know if this binary sequence represents:

  • The decimal number 25.
  • The ASCII character for the "End of Medium" symbol.
  • A part of a floating-point number.
  • A memory address.

Format specifiers solve this problem by telling the compiler exactly how to treat the data.

Code Example 2: Variable Initialization

#include <stdio.h>

int main() {
    // Declare and initialize in one line
    int students = 30;
    float price = 99.99;
    char initial = 'J';
    
    printf("Number of students: %d\n", students);
    printf("Price: Rs.%.2f\n", price);
    printf("First initial: %c\n", initial);
    
    return 0;
}

Output

Number of students: 30

Price: Rs.99.99

First initial: J

Constants in C

Constants are values that cannot be changed during program execution.

Method 1: Using const keyword

#include <stdio.h>

int main() {
    const float PI = 3.14159;
    const int DAYS_IN_WEEK = 7;
    
    printf("Value of PI: %.5f\n", PI);
    printf("Days in a week: %d\n", DAYS_IN_WEEK);
    
    // PI = 3.14;  // This would cause an error!
    
    return 0;
}

Output

Value of PI: 3.14159

Days in a week: 7

Method 2: Using #define

In C, the #define directive is a simple instruction used to create a macro, which tells the preprocessor to replace a specific name with a given value or piece of code before the program is compiled.

Think of it as setting up an automatic "find and replace" rule for your code.

#include <stdio.h>
#define MAX_STUDENTS 50
#define SCHOOL_NAME "ABC High School"

int main() {
    printf("School: %s\n", SCHOOL_NAME);
    printf("Maximum students allowed: %d\n", MAX_STUDENTS);
    
    return 0;
}

Output

School: ABC High School

Maximum students allowed: 50

Variable Naming Rules

In C programming, format specifiers are essential placeholders used in input and output functions (like printf()and scanf()) to define the type of data being printed or read. They act as a bridge between the raw binary data stored in variables and the human-readable text displayed on the screen.

Rule Valid Example Invalid Example
Start with letter or underscore age, _count 2age, #count
Use letters, digits, underscore only student_1, total_marks student-1, total marks
Case sensitive Age ≠ age -
No keywords number, value int, return

Practice Exercises

Exercise 1: Create a program that stores information about a book (title initial, number of pages, price) and displays it.

Exercise 2: Write a program to calculate and display the area of a rectangle using variables for length and width.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    char title_initial = 'H';
    int pages = 350;
    float price = 29.99;
    
    printf("Book title starts with: %c\n", title_initial);
    printf("Number of pages: %d\n", pages);
    printf("Price: $%.2f\n", price);
    
    return 0;
}

Output

Book title starts with: H

Number of pages: 350

Price: $29.99

Answer 2:

#include <stdio.h>

int main() {
    float length = 10.5;
    float width = 6.2;
    float area;
    
    area = length * width;
    
    printf("Length: %.1f meters\n", length);
    printf("Width: %.1f meters\n", width);
    printf("Area: %.2f square meters\n", area);
    
    return 0;
}

Output

Length: 10.5 meters

Width: 6.2 meters

Area: 65.10 square meters

Chapter 4: Operators

What are Operators?

Operators are symbols that perform operations on variables and values. Think of them as mathematical symbols like +, -, x, ÷.

Types of Operators

1. Arithmetic Operators

Arithmetic operators are used to perform common mathematical operations.

Operator Name Example Result
+ Addition 5 + 3 8
- Subtraction 5 - 3 2
* Multiplication 5 * 3 15
/ Division 6 / 3 2
% Modulus (remainder) 7 % 3 1
++ Increment x++ Increases x by 1
-- Decrement x-- Decreases x by 1

Code Example 1: Basic Arithmetic Operations

#include <stdio.h>

int main() {
    int a = 15;
    int b = 4;
    
    printf("a = %d, b = %d\n", a, b);
    printf("a + b = %d\n", a + b);
    printf("a - b = %d\n", a - b);
    printf("a * b = %d\n", a * b);
    printf("a / b = %d\n", a / b);        // Integer division
    printf("a %% b = %d\n", a % b);       // Remainder
    
    return 0;
}

Output

a = 15, b = 4

a + b = 19

a - b = 11

a * b = 60

a / b = 3

a % b = 3

Important Note about Division:

  • Integer division (15 \ 4 = 3) drops the decimal part
  • For decimal results, use float or double.

Code Example 2: Float Division and Increment/Decrement

#include <stdio.h>

int main() {
    float x = 15.0;
    float y = 4.0;
    int count = 5;
    
    printf("Float division: %.2f / %.2f = %.2f\n", x, y, x/y);
    
    printf("Original count: %d\n", count);
    count++;  // Increment by 1
    printf("After increment: %d\n", count);
    count--;  // Decrement by 1
    printf("After decrement: %d\n", count);

    return 0;
}

Output

Float division: 15.00 / 4.00 = 3.75

Original count: 5

After increment: 6

After decrement: 5

2. Relational (Comparison) Operators

Comparison operators are used to compare two values (or variables). This is important in programming, because it helps us to find answers and make decisions.

Operator Name Example Returns
== Equal to 5 == 3 0 (False)
!= Not equal 5 != 3 1 (True)
> Greater than 5 > 3 1 (True)
< Less than 5 < 3 0 (False)
>= Greater than or equal 5 >= 5 1 (True)
<= Less than or equal 3 <= 5 1 (True)

Code Example 3: Relational Operators

#include <stdio.h>

int main() {
    int x = 10;
    int y = 20;
    
    printf("x = %d, y = %d\n", x, y);
    printf("x == y: %d\n", x == y);    // False = 0
    printf("x != y: %d\n", x != y);    // True = 1
    printf("x > y: %d\n", x > y);      // False = 0
    printf("x < y: %d\n", x < y);      // True = 1
    printf("x >= y: %d\n", x >= y);    // False = 0
    printf("x <= y: %d\n", x <= y);    // True = 1
    
    return 0;
}

Output

x = 10, y = 20

x == y: 0

x != y: 1

x > y: 0

x < y: 1

x >= y: 0

x <= y: 1

3. Logical Operators

Logical operators are used to determine the logic between variables or values, by combining multiple conditions.

Operator Name Example Description
&& AND (5 > 3) && (2 < 4) True if both conditions are true
|| OR (5 > 3) || (2 > 4) True if at least one condition is true
! NOT !(5 > 3) Reverses the result

Code Example 4: Logical Operator

#include <stdio.h>

int main() {
    int age = 25;
    int income = 30000;
    
    printf("Age: %d, Income: %d\n", age, income);
    
    // AND operator
    printf("Eligible for loan (age >= 18 AND income >= 25000): %d\n", 
           (age >= 18) && (income >= 25000));
    
    // OR operator
    printf("Special discount (age < 18 OR age > 60): %d\n", 
           (age < 18) || (age > 60));
    
    // NOT operator
    printf("Not a senior citizen (age < 65): %d\n", !(age >= 65));
    
    return 0;
}

Output

Age: 25, Income: 30000

Eligible for loan (age >= 18 AND income >= 25000): 1

Special discount (age < 18 OR age> 60): 0

Not a senior citizen (age < 65): 1

4. Assignment Operators

Assignment operators are used to assign values to variables.

Operator Example Equivalent To
= x = 5 Assign 5 to x
+= x += 3 x = x + 3
-= x -= 2 x = x - 2
*= x *= 4 x = x * 4
/= x /= 2 x = x / 2
%= x %= 3 x = x % 3

Code Example 5: Assignment Operators

#include <stdio.h>

int main() {
    int num = 10;
    
    printf("Initial value: %d\n", num);
    
    num += 5;    // num = num + 5
    printf("After += 5: %d\n", num);
    
    num -= 3;    // num = num - 3
    printf("After -= 3: %d\n", num);
    
    num *= 2;    // num = num * 2
    printf("After *= 2: %d\n", num);
    
    num /= 4;    // num = num / 4
    printf("After /= 4: %d\n", num);
    
    num %= 3;    // num = num % 3
    printf("After %= 3: %d\n", num);
    
    return 0;
}

Output

Initial value: 10

After += 5: 15

After -= 3: 12

After *= 2: 24

After /= 4: 6

After %= 3: 0

Operator Precedence

When multiple operators are used, C follows a specific order:

Priority Operators Example
1 (Highest) () (a + b) * c
2 ++, --, ! ++x, !flag
3 *, /, % a * b / c
4 +, - a + b - c
5 <, <=, >, >= a < b
6 ==, != a == b
7 && a && b
8 || a || b
9 (Lowest) =, +=, -=, etc. a = b + c

Practice Exercises

Exercise 1: Write a program that calculates the average of three numbers using variables and arithmetic operators.

Exercise 2: Create a program that checks if a number is even or odd using the modulus operator.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    float num1 = 85.5;
    float num2 = 92.0;
    float num3 = 78.5;
    float average;
    
    average = (num1 + num2 + num3) / 3;
    
    printf("Number 1: %.1f\n", num1);
    printf("Number 2: %.1f\n", num2);
    printf("Number 3: %.1f\n", num3);
    printf("Average: %.2f\n", average);
    
    return 0;
}

Output

Number 1: 85.5

Number 2: 92.0

Number 3: 78.5

Average: 85.33

Answer 2:

#include <stdio.h>

int main() {
    int number = 17;
    int remainder;
    
    remainder = number % 2;
    
    printf("Number: %d\n", number);
    printf("Remainder when divided by 2: %d\n", remainder);
    
    if (remainder == 0) {
        printf("The number is EVEN\n");
    } else {
        printf("The number is ODD\n");
    }
    
    return 0;
}

Output

Number: 17

Remainder when divided by 2: 1

Number 3: 78.5

The number is ODD

Chapter 5: Input and Output

Input and Output (I/O) in C programming are fundamental operations that allow programs to communicate with the outside world. Input refers to receiving data into a program, while output refers to sending data from a program to external destinations.

What is Input and Output?

  • Input: The process of feeding data or information into a program from external sources (keyboard, files, network, etc.)
  • Output: The process of displaying or sending data from a program to external destinations (screen, files, printer, etc.)

In C, I/O operations are handled through functions provided in the stdio.h (Standard Input/Output) header file.

Output with printf()

We've already used printf() to display text. Let's explore it in detail.

printf("format string", variables);

Code Example 1: Different Format Specifiers

#include <stdio.h>

int main() {
    int age = 25;
    float height = 5.9;
    char grade = 'A';
    
    printf("Age: %d years\n", age);
    printf("Height: %.1f feet\n", height);
    printf("Grade: %c\n", grade);
    printf("Height with 3 decimals: %.3f\n", height);
    
    return 0;
}

Output

Age: 25 years

Height: 5.9 feet

Grade: A

Height with 3 decimals: 5.900

Format Specifiers Reference:

Specifier Data Type Description Example
%d int Integer %d → 123
%f float/double Floating point %f → 3.140000
%.2f float/double 2 decimal places %.2f → 3.14
%c char Single character %c → A
%s char[] String %s → Hello
%x int Hexadecimal %x → 1a
%o int Octal %o → 17

Input with scanf()

scanf() is used to get input from the user.

scanf("format", &variables);

Code Example 2: Getting User Input

#include <stdio.h>

int main() {
    int age;
    float salary;
    char grade;
    
    printf("Enter your age: ");
    scanf("%d", &age);
    
    printf("Enter your salary: ");
    scanf("%f", &salary);
    
    printf("Enter your grade: ");
    scanf(" %c", &grade);  // Note the space before %c
    
    printf("\n--- Your Information ---\n");
    printf("Age: %d years\n", age);
    printf("Salary: $%.2f\n", salary);
    printf("Grade: %c\n", grade);
    
    return 0;

}

Output

Enter your age: 28

Enter your salary: 45000.50

Enter your grade: B


--- Your Information ---

Age: 28 years

Salary: $45000.50

Grade: B

Line-by-Line Explanation:

Line Explanation
scanf("%d",&age); Read integer and store in age
&age & gets the memory address of age
scanf("%c",&grade); Space before %c clears any leftover characters
printf("\n--- Your Information ---\n"); \n creates new lines

Code Example 3: Multiple Inputs at Once

#include <stdio.h>

int main() {
    int day, month, year;
    
    printf("Enter date (DD MM YYYY): ");
    scanf("%d %d %d", &day, &month, &year);
    
    printf("You entered: %02d/%02d/%d\n", day, month, year);
    // %02d means: 2 digits, fill with 0 if needed
    
    return 0;
}

Output

Enter date (DD MM YYYY): 5 3 2024

You entered: 05/03/2024

Getting String Input

For strings, we use %s and don't need &:

#include <stdio.h>

int main() {
    char name[50];  // Array to store string
    int age;
    
    printf("Enter your name: ");
    scanf("%s", name);  // No & needed for strings
    
    printf("Enter your age: ");
    scanf("%d", &age);
    
    printf("Hello %s, you are %d years old!\n", name, age);
    
    return 0;
}

Output

Enter your name: John

Enter your age: 25

Hello John, you are 25 years old!

Code Example 4: Interactive Calculator

#include <stdio.h>

int main() {
    float num1, num2, result;
    char operator;
    
    printf("=== Simple Calculator ===\n");
    printf("Enter first number: ");
    scanf("%f", &num1);
    
    printf("Enter operator (+, -, *, /): ");
    scanf(" %c", &operator);
    
    printf("Enter second number: ");
    scanf("%f", &num2);
    
    // Perform calculation based on operator
    if (operator == '+') {
        result = num1 + num2;
    } else if (operator == '-') {
        result = num1 - num2;
    } else if (operator == '*') {
        result = num1 * num2;
    } else if (operator == '/') {
        result = num1 / num2;
    }
    
    printf("%.2f %c %.2f = %.2f\n", num1, operator, num2, result);
    
    return 0;
}

Output

=== Simple Calculator ===

Enter first number: 15.5

Enter operator (+, -, *, /): *

Enter second number: 2.5

15.50 * 2.50 = 38.75

Common Input/Output Mistakes and Solutions

Problem 1: Reading Characters After Numbers

// Wrong way
scanf("%d", &num);
scanf("%c", &ch);  // This might not work correctly

// Correct way
scanf("%d", &num);
scanf(" %c", &ch);  // Note the space before %c

Problem 2: String Input with Spaces

// scanf() stops at spaces
scanf("%s", name);  // Input: "John Smith" → Only gets "John"

// Solution: Use gets() or fgets()
gets(name);  // Gets entire line including spaces

Practice Exercises

Exercise 1: Write a program that asks for the user's name, age, and favorite number, then displays them in a formatted way.

Exercise 2: Create a program that calculates the area and perimeter of a rectangle by getting length and width from the user.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    char name[50];
    int age;
    int fav_number;
    
    printf("Enter your name: ");
    scanf("%s", name);
    
    printf("Enter your age: ");
    scanf("%d", &age);
    
    printf("Enter your favorite number: ");
    scanf("%d", &fav_number);
    
    printf("\n=== Your Profile ===\n");
    printf("Name: %s\n", name);
    printf("Age: %d years old\n", age);
    printf("Favorite Number: %d\n", fav_number);
    
    return 0;
}

Output

Enter your name: John

Enter your age: 24

Enter your favorite number: 3


=== Your Profile ===

Name: John

Age: 24 years old

Favorite Number: 3

Answer 2:

#include <stdio.h>

int main() {
    float length, width, area, perimeter;
    
    printf("Enter rectangle length: ");
    scanf("%f", &length);
    
    printf("Enter rectangle width: ");
    scanf("%f", &width);
    
    area = length * width;
    perimeter = 2 * (length + width);
    
    printf("\n=== Rectangle Information ===\n");
    printf("Length: %.2f units\n", length);
    printf("Width: %.2f units\n", width);
    printf("Area: %.2f square units\n", area);
    printf("Perimeter: %.2f units\n", perimeter);
    
    return 0;
}

Output

Enter rectangle length: 12

Enter rectangle width: 4


=== Rectangle Information ===

Length: 12.00 units

Width: 4.00 units

Area: 48.00 square units

Perimeter: 32.00 units

Chapter 6: Conditional Statements - if, else

What are Conditional Statements?

Conditional statements allow programs to make decisions. They execute different code blocks based on whether conditions are true or false.

Think of it like: “IF it's raining, THEN take an umbrella, ELSE wear sunglasses.”

Basic if Statement

Syntax:

if (condition) {    
		// Code to execute if condition is true
}

Code Example 1: Simple if Statement

#include <stdio.h>

int main() {
    int age;
    
    printf("Enter your age: ");
    scanf("%d", &age);
    
    if (age >= 18) {
        printf("You are eligible to vote!\n");
    }
    
    printf("Program ended.\n");
    
    return 0;
}

Output

Enter your age: 20

You are eligible to vote!

Program ended.

If age was 16:

Output

Enter your age: 16

Program ended.

How it Works:

Condition Result Action
age >= 18 is TRUE Condition met Execute the code inside {}
age >= 18 is FALSE Condition not met Skip the code inside {}

if-else Statement

Syntax:

if (condition) {    
		// Code to execute if condition is true
}

Code Example 2: if-else Statement

#include <stdio.h>

int main() {
    int number;
    
    printf("Enter a number: ");
    scanf("%d", &number);
    
    if (number % 2 == 0) {
        printf("%d is an EVEN number.\n", number);
    } else {
        printf("%d is an ODD number.\n", number);
    }
    
    return 0;

}

Output

Enter a number: 8

8 is an EVEN number.

Output

Enter a number: 7

7 is an ODD number.

Flow Chart Explanation:

Step Check Action
1 Is number % 2 == 0? If YES → “EVEN number”
2 If NO from step 1 Execute else → “ODD number”

if-else if-else Statement

For multiple conditions, use else if:

Syntax:

if (condition1) {
    // Code for condition1
} else if (condition2) {
    // Code for condition2
} else if (condition3) {
    // Code for condition3
} else {
    // Code if none of the above conditions are true
}

Code Example 3: Grade Calculator

#include <stdio.h>

int main() {
    int marks;
    
    printf("Enter your marks (0-100): ");
    scanf("%d", &marks);
    
    if (marks >= 90) {
        printf("Grade: A+ (Excellent!)\n");
    } else if (marks >= 80) {
        printf("Grade: A (Very Good!)\n");
    } else if (marks >= 70) {
        printf("Grade: B (Good!)\n");
    } else if (marks >= 60) {
        printf("Grade: C (Average)\n");
    } else if (marks >= 50) {
        printf("Grade: D (Pass)\n");
    } else {
        printf("Grade: F (Fail)\n");
    }
    
    return 0;
}

Output

Enter your marks (0-100): 85

Grade: A (Very Good!)

Grade System Table:

Marks Range Grade Message
90-100 A+ Excellent!
80-89 A Very Good!
70-79 B Good!
60-69 C Average
50-59 D Pass
0-49 F Fail

Nested if Statements

You can put if statements inside other if statements:

Code Example 4: Nested if - Login System

#include <stdio.h>

int main() {
    int user_id;
    int password;
    int age;
    
    printf("Enter User ID: ");
    scanf("%d", &user_id);
    
    if (user_id == 1234) {
        printf("Enter Password: ");
        scanf("%d", &password);
        
        if (password == 9999) {
            printf("Enter your age: ");
            scanf("%d", &age);
            
            if (age >= 18) {
                printf("Access GRANTED! Welcome!\n");
            } else {
                printf("Access DENIED! Must be 18 or older.\n");
            }
        } else {
            printf("Wrong password!\n");
        }
    } else {
        printf("Invalid User ID!\n");
    }
    
    return 0;
}

Output(Success)

Enter User ID: 1234

Enter Password: 9999

Enter your age: 25

Access GRANTED! Welcome!

Output(Wrong Password)

Enter User ID: 1234

Enter Password: 1111

Wrong password!

Logical Operators in Conditions

AND Operator (&&)

Both conditions must be true:

#include <stdio.h>

int main() {
    int age;
    int income;
    
    printf("Enter age: ");
    scanf("%d", &age);
    printf("Enter monthly income: ");
    scanf("%d", &income);
    
    if (age >= 21 && income >= 30000) {
        printf("You qualify for a premium credit card!\n");
    } else {
        printf("You don't qualify for premium credit card.\n");
    }
    
    return 0;
}

OR Operator (||)

At least one condition must be true:

#include <stdio.h>

int main() {
    int age;
    
    printf("Enter your age: ");
    scanf("%d", &age);
    
    if (age < 13 || age > 65) {
        printf("You get a special discount!\n");
    } else {
        printf("Regular price applies.\n");
    }
    
    return 0;
}

Code Example 5: Complex Conditions - ATM System

#include <stdio.h>

int main() {
    int pin = 1234;           // Correct PIN
    int balance = 5000;       // Account balance
    int entered_pin;
    int withdraw_amount;
    
    printf("=== ATM System ===\n");
    printf("Enter your PIN: ");
    scanf("%d", &entered_pin);
    
    if (entered_pin == pin) {
        printf("PIN Correct!\n");
        printf("Current balance: $%d\n", balance);
        printf("Enter withdrawal amount: ");
        scanf("%d", &withdraw_amount);
        
        if (withdraw_amount > 0 && withdraw_amount <= balance) {
            balance = balance - withdraw_amount;
            printf("Transaction successful!\n");
            printf("Withdrawn: $%d\n", withdraw_amount);
            printf("Remaining balance: $%d\n", balance);
        } else if (withdraw_amount > balance) {
            printf("Insufficient funds!\n");
        } else {
            printf("Invalid amount!\n");
        }
    } else {
        printf("Wrong PIN! Access denied.\n");
    }
    
    return 0;
}

Code Structure Overview

#include <stdio.h>

int main() {
    // Code goes here
    return 0;
}

This is a basic C program structure that every C program needs.

Step-by-Step Code Explanation

  1. Header File and Program Start
  2. #include <stdio.h>
    
    int main() {
    }
    
    • #include <stdio.h>: This tells the computer to include functions for input (reading) and output (displaying) operations.
    • int main(): This is where your program starts executing - like the main entrance to your program.
  3. Variable Declarations
  4. int pin = 1234;           // Correct PIN
    int balance = 5000;       // Account balance
    int entered_pin;
    int withdraw_amount;
    
    • pin = 1234: Stores the correct PIN number (like your ATM card's secret code).
    • balance = 5000: Stores how much money is in the account (starts with $5000).
    • entered_pin: Will store whatever PIN the user types in.
    • withdraw_amount: Will store how much money the user wants to withdraw.
  5. Getting User Input (PIN Entry)
  6. printf("=== ATM System ===\n");
    printf("Enter your PIN: ");
    scanf("%d", &entered_pin);
    
    • printf(): Displays text on the screen.
    • scanf("%d", &entered_pin): Waits for user to type a number and stores it in entered_pin.
    • The & symbol means "store the input IN this variable".
  7. PIN Verification (First Decision)
  8. if (entered_pin == pin) {
        // PIN is correct - do banking operations
    } else {
        printf("Wrong PIN! Access denied.\n");
    }
    
    • == means "is equal to" (comparison).
    • If the PIN matches: user gets access to their account.
    • If the PIN is wrong: user is denied access.
  9. Banking Operations (Inside Correct PIN Block)
  10. printf("PIN Correct!\n");
    printf("Current balance: $%d\n", balance);
    printf("Enter withdrawal amount: ");
    scanf("%d", &withdraw_amount);
    
    • Shows "PIN Correct!" message.
    • Displays current balance ($5000).
    • Asks user how much money they want to withdraw.
  11. Withdrawal Logic (Nested Decisions)
  12. if (withdraw_amount > 0 && withdraw_amount <= balance) {
        balance = balance - withdraw_amount;
        printf("Transaction successful!\n");
        printf("Withdrawn: $%d\n", withdraw_amount);
        printf("Remaining balance: $%d\n", balance);
    } else if (withdraw_amount > balance) {
        printf("Insufficient funds!\n");
    } else {
        printf("Invalid amount!\n");
    }
    

    Three possible scenarios:

    1. Valid Withdrawal (withdraw_amount > 0 && withdraw_amount <= balance):
      • Amount is positive AND less than or equal to balance.
      • Subtracts money from balance: balance = balance - withdraw_amount.
      • Shows success message and new balance
    2. Insufficient Funds (withdraw_amount > balance):
      • User wants more money than they have.
      • Shows "Insufficient funds!" message.
    3. Invalid Amount (anything else):
      • User entered 0 or negative number.
      • Shows "Invalid amount!" message.

Example Program Flow

Let's see how this works with examples:

Scenario 1: Successful Transaction

Output

=== ATM System ===

Enter your PIN: 1234

PIN Correct!

Current balance: $5000

Enter withdrawal amount: 1000

Transaction successful!

Withdrawn: $1000

Remaining balance: $4000

Scenario 2: Wrong PIN

Output

=== ATM System ===

Enter your PIN: 1111

Wrong PIN! Access denied.

Scenario 3: Insufficient Funds

Output

=== ATM System ===

Enter your PIN: 1234

PIN Correct!

Current balance: $5000

Enter withdrawal amount: 6000

Insufficient funds!

Scenario 4: Invalid Amount

Output

=== ATM System ===

Enter your PIN: 1234

PIN Correct!

Current balance: $5000

Enter withdrawal amount: -500

Invalid amount!

Common Mistakes and Best Practices

Mistake 1: Using = instead of ==

// Wrong
if (x = 5) {  // This assigns 5 to x, doesn't compare!
    
// Correct
if (x == 5) {  // This compares x with 5

Mistake 2: Missing Braces

// Risky (only first line is in if block)
if (age >= 18)
    printf("You can vote\n");
    printf("You are an adult\n");  // This always executes!

// Better (use braces)
if (age >= 18) {
    printf("You can vote\n");
    printf("You are an adult\n");
}

Practice Exercises

Exercise 1: Write a program that takes three numbers from the user and finds the largest one.

Exercise 2: Create a simple calculator that takes two numbers and an operator (+, -, *, /) and performs the calculation. Handle division by zero.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    float num1, num2, num3;
    
    printf("Enter three numbers: ");
    scanf("%f %f %f", &num1, &num2, &num3);
    
    if (num1 >= num2 && num1 >= num3) {
        printf("%.2f is the largest number.\n", num1);
    } else if (num2 >= num1 && num2 >= num3) {
        printf("%.2f is the largest number.\n", num2);
    } else {
        printf("%.2f is the largest number.\n", num3);
    }
    
    return 0;
}

Output

Enter three numbers: 3 6 8

8.00 is the largest number.

Answer 2:

#include <stdio.h>

int main() {
    float num1, num2, result;
    char operator;
    
    printf("Enter first number: ");
    scanf("%f", &num1);
    
    printf("Enter operator (+, -, *, /): ");
    scanf(" %c", &operator);
    
    printf("Enter second number: ");
    scanf("%f", &num2);
    
    if (operator == '+') {
        result = num1 + num2;
        printf("%.2f + %.2f = %.2f\n", num1, num2, result);
    } else if (operator == '-') {
        result = num1 - num2;
        printf("%.2f - %.2f = %.2f\n", num1, num2, result);
    } else if (operator == '*') {
        result = num1 * num2;
        printf("%.2f * %.2f = %.2f\n", num1, num2, result);
    } else if (operator == '/') {
        if (num2 != 0) {
            result = num1 / num2;
            printf("%.2f / %.2f = %.2f\n", num1, num2, result);
        } else {
            printf("Error: Division by zero is not allowed!\n");
        }
    } else {
        printf("Error: Invalid operator!\n");
    }
    
    return 0;
}

Output

Enter first number: 15

Enter operator (+, -, *, /): *

Enter second number: 5

15.00 * 5.00 = 75.00

Chapter 7: Switch Statement

What is a Switch Statement?

The switch statement is used when you need to compare a variable against many different values. It's a cleaner alternative to multiple if-else if statements.

Think of it like a menu selector - you choose one option from many available options.

When to Use Switch vs if-else:

  • Switch: When comparing ONE variable against multiple exact values.
  • if-else: When using complex conditions with ranges or multiple variables.

Basic Switch Syntax

switch (variable) {
    case value1:
        // Code for value1
        break;
    case value2:
        // Code for value2
        break;
    case value3:
        // Code for value3
        break;
    default:
        // Code if no cases match
}

Key Components:

Component Purpose
switch(variable) Variable to compare
case value: Specific value to match
break; Exit the switch (prevents fall-through)
default: Executes if no case matches (optional)

Code Example 1: Simple Menu System

#include <stdio.h>

int main() {
    int choice;
    
    printf("=== Main Menu ===\n");
    printf("1. Play Game\n");
    printf("2. View Settings\n");
    printf("3. View Help\n");
    printf("4. Exit\n");
    printf("Enter your choice (1-4): ");
    scanf("%d", &choice);
    
    switch (choice) {
        case 1:
            printf("Starting the game...\n");
            break;
        case 2:
            printf("Opening settings menu...\n");
            break;
        case 3:
            printf("Displaying help information...\n");
            break;
        case 4:
            printf("Thank you for playing! Goodbye!\n");
            break;
        default:
            printf("Invalid choice! Please enter 1-4.\n");
    }
    
    return 0;
}

Output

=== Main Menu ===

1. Play Game

2. View Settings

3. View Help

4. Exit

Enter your choice (1-4): 2

Opening settings menu...

If invalid input:

Output

Enter your choice (1-4): 7

Invalid choice! Please enter 1-4.

Code Example 2: Calculator Using Switch

#include <stdio.h>

int main() {
    float num1, num2, result;
    char operator;
    
    printf("=== Calculator ===\n");
    printf("Enter first number: ");
    scanf("%f", &num1);
    
    printf("Enter operator (+, -, *, /): ");
    scanf(" %c", &operator);
    
    printf("Enter second number: ");
    scanf("%f", &num2);
    
    switch (operator) {
        case '+':
            result = num1 + num2;
            printf("%.2f + %.2f = %.2f\n", num1, num2, result);
            break;
            
        case '-':
            result = num1 - num2;
            printf("%.2f - %.2f = %.2f\n", num1, num2, result);
            break;
            
        case '*':
            result = num1 * num2;
            printf("%.2f * %.2f = %.2f\n", num1, num2, result);
            break;
            
        case '/':
            if (num2 != 0) {
                result = num1 / num2;
                printf("%.2f / %.2f = %.2f\n", num1, num2, result);
            } else {
                printf("Error: Division by zero!\n");
            }
            break;
            
        default:
            printf("Error: Invalid operator!\n");
            printf("Please use +, -, *, or /\n");
    }
    
    return 0;
}

Output

=== Calculator ===

Enter first number: 15.5

Enter operator (+, -, *, /): *

15.50 * 3.00 = 46.50

Switch with Character Cases

Code Example 2: Calculator Using Switch

#include <stdio.h>

int main() {
    char grade;
    
    printf("Enter your grade (A, B, C, D, F): ");
    scanf(" %c", &grade);
    
    switch (grade) {
        case 'A':
        case 'a':  // Handle both uppercase and lowercase
            printf("Excellent! You scored 90-100%%\n");
            printf("Keep up the great work!\n");
            break;
            
        case 'B':
        case 'b':
            printf("Very Good! You scored 80-89%%\n");
            printf("You're doing well!\n");
            break;
            
        case 'C':
        case 'c':
            printf("Good! You scored 70-79%%\n");
            printf("There's room for improvement.\n");
            break;
            
        case 'D':
        case 'd':
            printf("Satisfactory. You scored 60-69%%\n");
            printf("You need to study harder.\n");
            break;
            
        case 'F':
        case 'f':
            printf("Fail. You scored below 60%%\n");
            printf("Don't give up! Try again.\n");
            break;
            
        default:
            printf("Invalid grade! Please enter A, B, C, D, or F.\n");
    }
    
    return 0;
}

Output

Enter your grade (A, B, C, D, F): b

Very Good! You scored 80-89%

You're doing well!

What Happens Without break?

Fall-through behavior: If you forget break, the program continues to execute the next cases.

#include <stdio.h>

int main() {
    int day = 2;
    
    printf("Day %d: ", day);
    
    switch (day) {
        case 1:
            printf("Monday ");
        case 2:
            printf("Tuesday ");
        case 3:
            printf("Wednesday ");
        case 4:
            printf("Thursday ");
        case 5:
            printf("Friday ");
        default:
            printf("(Workday)\n");
    }
    
    return 0;
}

Output

Day 2: Tuesday Wednesday Thursday Friday (Workday)

With proper breaks:

switch (day) {
    case 1:
        printf("Monday\n");
        break;
    case 2:
        printf("Tuesday\n");
        break;
    case 3:
        printf("Wednesday\n");
        break;
    // ... and so on
}

Useful Fall-through Example

Sometimes fall-through is intentionally used:

#include <stdio.h>

int main() {
    int month;
    
    printf("Enter month number (1-12): ");
    scanf("%d", &month);
    
    switch (month) {
        case 12:
        case 1:
        case 2:
            printf("Winter season\n");
            break;
            
        case 3:
        case 4:
        case 5:
            printf("Spring season\n");
            break;
            
        case 6:
        case 7:
        case 8:
            printf("Summer season\n");
            break;
            
        case 9:
        case 10:
        case 11:
            printf("Autumn season\n");
            break;
            
        default:
            printf("Invalid month! Enter 1-12.\n");
    }
    
    return 0;
}

Code Example 5: ATM Machine Menu

#include <stdio.h>

int main() {
    int choice;
    float balance = 1500.00;  // Starting balance
    float amount;
    
    printf("=== ATM Machine ===\n");
    printf("Current Balance: $%.2f\n\n", balance);
    printf("1. Check Balance\n");
    printf("2. Deposit Money\n");
    printf("3. Withdraw Money\n");
    printf("4. Exit\n");
    printf("Select an option: ");
    scanf("%d", &choice);
    
    switch (choice) {
        case 1:
            printf("\nYour current balance is: $%.2f\n", balance);
            break;
            
        case 2:
            printf("Enter deposit amount: $");
            scanf("%f", &amount);
            if (amount > 0) {
                balance += amount;
                printf("$%.2f deposited successfully!\n", amount);
                printf("New balance: $%.2f\n", balance);
            } else {
                printf("Invalid amount!\n");
            }
            break;
            
        case 3:
            printf("Enter withdrawal amount: $");
            scanf("%f", &amount);
            if (amount > 0 && amount <= balance) {
                balance -= amount;
                printf("$%.2f withdrawn successfully!\n", amount);
                printf("Remaining balance: $%.2f\n", balance);
            } else if (amount > balance) {
                printf("Insufficient funds!\n");
            } else {
                printf("Invalid amount!\n");
            }
            break;
            
        case 4:
            printf("Thank you for using our ATM. Goodbye!\n");
            break;
            
        default:
            printf("Invalid option! Please select 1-4.\n");
    }
    
    return 0;
}

Output

=== ATM Machine ===

Current Balance: $1500.00


1. Check Balance

2. Deposit Money

3. Withdraw Money

4. Exit

Select an option: 3

Enter withdrawal amount: $200

$200.00 withdrawn successfully!

Remaining balance: $1300.00

Switch vs if-else Comparison

Aspect Switch Statement if-else Statement
Use Case Multiple exact values Complex conditions, ranges
Performance Faster for many cases Slower for many conditions
Readability Cleaner for menus Better for complex logic
Data Types int, char, enum only Any data type
Conditions Only equality (==) All operators (>, <, >=, etc.)

Practice Exercises

Exercise 1: Create a program that converts numerical day (1-7) to day name (1=Monday, 2=Tuesday, etc.).

Exercise 2: Build a simple restaurant ordering system with at least 5 menu items, prices, and order confirmation.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    int day;
    
    printf("Enter day number (1-7): ");
    scanf("%d", &day);
    
    switch (day) {
        case 1:
            printf("Monday\n");
            break;
        case 2:
            printf("Tuesday\n");
            break;
        case 3:
            printf("Wednesday\n");
            break;
        case 4:
            printf("Thursday\n");
            break;
        case 5:
            printf("Friday\n");
            break;
        case 6:
            printf("Saturday\n");
            break;
        case 7:
            printf("Sunday\n");
            break;
        default:
            printf("Invalid day! Please enter 1-7.\n");
    }
    
    return 0;
}

Output

Enter day number (1-7): 3

Wednesday

Answer 2:

#include <stdio.h>

int main() {
    int choice;
    float total = 0;
    
    printf("=== Restaurant Menu ===\n");
    printf("1. Burger - $8.99\n");
    printf("2. Pizza - $12.50\n");
    printf("3. Pasta - $9.75\n");
    printf("4. Salad - $6.25\n");
    printf("5. Drinks - $2.50\n");
    printf("6. Exit\n");
    printf("Enter your choice: ");
    scanf("%d", &choice);
    
    switch (choice) {
        case 1:
            total += 8.99;
            printf("Burger added to order!\n");
            printf("Total: $%.2f\n", total);
            break;
            
        case 2:
            total += 12.50;
            printf("Pizza added to order!\n");
            printf("Total: $%.2f\n", total);
            break;
            
        case 3:
            total += 9.75;
            printf("Pasta added to order!\n");
            printf("Total: $%.2f\n", total);
            break;
            
        case 4:
            total += 6.25;
            printf("Salad added to order!\n");
            printf("Total: $%.2f\n", total);
            break;
            
        case 5:
            total += 2.50;
            printf("Drinks added to order!\n");
            printf("Total: $%.2f\n", total);
            break;
            
        case 6:
            printf("Thank you for visiting!\n");
            break;
            
        default:
            printf("Invalid choice! Please select 1-6.\n");
    }
    return 0;
}

Output

=== Restaurant Menu ===

1. Burger - $8.99

2. Pizza - $12.50

3. Pasta - $9.75

4. Salad - $6.25

5. Drinks - $2.50

6. Exit

Enter your choice: 3

Pasta added to order!

Total: $9.75

Chapter 8: Loops - for Loop

What are Loops?

Loops allow you to execute the same block of code multiple times without writing it repeatedly. Think of it like asking someone to"count from 1 to 10" - they repeat the counting process.

Types of Loops

  1. for loop - When you know how many times to repeat.
  2. while loop - When you repeat based on a condition.
  3. do-while loop - Similar to while, but executes at least once

for Loop Basics

Syntax:

for (initialization; condition; increment/decrement) {
    // Code to repeat
}

Components:

Component Purpose Example
Initialization Starting point i = 1
Condition When to continue i <= 10
Increment/Decrement How to change i++ or i--

Code Example 5: ATM Machine Menu

#include <stdio.h>

int main() {
    int i;
    
    printf("Counting from 1 to 5:\n");
    
    for (i = 1; i <= 5; i++) {
        printf("%d ", i);
    }
    
    printf("\nLoop finished!\n");
    
    return 0;
}

Output

Counting from 1 to 5:

1 2 3 4 5

Loop finished!

How it Works Step by Step:

Iteration i value Condition (i <= 5) Action Print
1 1 TRUE Execute loop 1
2 2 TRUE Execute loop 2
3 3 TRUE Execute loop 3
4 4 TRUE Execute loop 4
5 5 TRUE Execute loop 5
6 6 FALSE Exit loop -

Code Example 2: Counting Backwards

#include <stdio.h>

int main() {
    int i;
    
    printf("Countdown: ");
    
    for (i = 10; i >= 1; i--) {
        printf("%d ", i);
    }
    
    printf("Blast off! 🚀\n");
    
    return 0;
}

Output

Countdown: 10 9 8 7 6 5 4 3 2 1 Blast off! 🚀

Code Example 3: Multiplication Table

#include <stdio.h>

int main() {
    int number, i;
    
    printf("Enter a number: ");
    scanf("%d", &number);
    
    printf("\nMultiplication table for %d:\n", number);
    printf("========================\n");
    
    for (i = 1; i <= 10; i++) {
        printf("%d x %d = %d\n", number, i, number * i);
    }
    
    return 0;
}

Output

Enter a number: 7


Multiplication table for 7:

========================

7 x 1 = 7

7 x 2 = 14

7 x 3 = 21

7 x 4 = 28

7 x 5 = 35

7 x 6 = 42

7 x 7 = 49

7 x 8 = 56

7 x 9 = 63

7 x 10 = 70

Different Increment/Decrement Styles

Increment by Different Values:

#include <stdio.h>

int main() {
    int i;
    
    // Count by 2s
    printf("Even numbers (2, 4, 6...): ");
    for (i = 2; i <= 20; i += 2) {
        printf("%d ", i);
    }
    
    printf("\n");
    
    // Count by 5s
    printf("Multiples of 5: ");
    for (i = 5; i <= 50; i += 5) {
        printf("%d ", i);
    }
    
    printf("\n");
    
    return 0;
}

Output

Even numbers (2, 4, 6...): 2 4 6 8 10 12 14 16 18 20

Multiples of 5: 5 10 15 20 25 30 35 40 45 50

Nested for Loops

Nested loops are loops inside other loops:

Code Example 4: Creating Patterns

#include <stdio.h>

int main() {
    int i, j;
    
    printf("Right triangle pattern:\n");
    
    for (i = 1; i <= 5; i++) {        // Outer loop for rows
        for (j = 1; j <= i; j++) {    // Inner loop for stars in each row
            printf("* ");
        }
        printf("\n");                  // New line after each row
    }
    
    return 0;
}

Output

Right triangle pattern:

*

* *

* * *

* * * *

* * * * *

How Nested Loops Work:

Outer Loop (i) Inner Loop (j) Stars Printed Output
1 1 1 star *
2 1, 2 2 stars * *
3 1, 2, 3 3 stars * * *
4 1, 2, 3, 4 4 stars * * * *
5 1, 2, 3, 4, 5 5 stars * * * * *

Code Example 5: Number Square Pattern

#include <stdio.h>

int main() {
    int i, j;
    int size;
    
    printf("Enter size of square: ");
    scanf("%d", &size);
    
    printf("\nNumber square pattern:\n");
    
    for (i = 1; i <= size; i++) {
        for (j = 1; j <= size; j++) {
            printf("%d ", j);
        }
        printf("\n");
    }
    
    return 0;
}

Output

Enter size of square: 4


Number square pattern:

1 2 3 4

1 2 3 4

1 2 3 4

1 2 3 4

Practical Applications

Code Example 6: Sum of Numbers

#include <stdio.h>

int main() {
    int n, i;
    int sum = 0;
    
    printf("Enter a positive number: ");
    scanf("%d", &n);
    
    for (i = 1; i <= n; i++) {
        sum = sum + i;  // Add each number to sum
    }
    
    printf("Sum of numbers from 1 to %d = %d\n", n, sum);
    
    // Mathematical formula: sum = n * (n + 1) / 2
    printf("Verification using formula: %d\n", n * (n + 1) / 2);
    
    return 0;
}

Output

Enter a positive number: 10

Sum of numbers from 1 to 10 = 55

Verification using formula: 55

Code Example 7: Factorial Calculation

#include <stdio.h>

int main() {
    int n, i;
    long long factorial = 1;  // Use long long for large numbers
    
    printf("Enter a number: ");
    scanf("%d", &n);
    
    if (n < 0) {
        printf("Factorial is not defined for negative numbers.\n");
    } else {
        for (i = 1; i <= n; i++) {
            factorial = factorial * i;
        }
        
        printf("Factorial of %d = %lld\n", n, factorial);
        
        // Show the calculation
        printf("Calculation: ");
        for (i = 1; i <= n; i++) {
            printf("%d", i);
            if (i < n) printf(" x ");
        }
        printf(" = %lld\n", factorial);
    }
    
    return 0;
}

What is a Factorial?

A factorial is the product of all positive integers from 1 up to a given number.

  • 5! (5 factorial) = 5 × 4 × 3 × 2 × 1 = 120
  • 4! (4 factorial) = 4 × 3 × 2 × 1 = 24
  • 0! = 1 (by definition)

Step-by-Step Code Breakdown

  1. Program Setup
  2. #include <stdio.h>
    int main() {
    
    • #include <stdio.h>: Include the standard input/output library for printf() and scanf().
    • int main(): The main function where program execution begins.
  3. Variable Declarations
  4. int n, i;
    long long factorial = 1;  // Use long long for large numbers
    
    • n: Stores the number entered by the user.
    • i: Loop counter variable (will go from 1 to n).
    • factorial = 1: Stores the factorial result.
  5. Getting User Input
  6. printf("Enter a number: ");
    scanf("%d", &n);
    
    • Asks the user to enter a number.
    • scanf("%d", &n) reads the integer and stores it in variable n.
  7. Input Validation
  8. if (n < 0) {
        printf("Factorial is not defined for negative numbers.\n");
    } else {
        // Calculate factorial
    }
    

    Why this check? Factorials are only defined for non-negative numbers. This prevents errors and educates users about mathematical rules.

  9. Factorial Calculation (The Heart of the Program)
  10. for (i = 1; i <= n; i++) {
        factorial = factorial * i;
    }
    
    • Initialization: i = 1 (start from 1).
    • Condition: i <= n (continue until we reach the input number).
    • Update: ++ (increment i by 1 each time).
    • Action: factorial = factorial * i (multiply current factorial by i)

    Example with n = 5:

    • i = 1: factorial = 1 × 1 = 1
    • i = 2: factorial = 1 × 2 = 2
    • i = 3: factorial = 2 × 3 = 6
    • i = 4: factorial = 6 × 4 = 24
    • i = 5: factorial = 24 × 5 = 120
  11. Displaying Results
  12. printf("Factorial of %d = %lld\n", n, factorial);
    
    • %d: Format specifier for integer (n).
    • %lld: Format specifier for long long integer (factorial).
  13. Showing the Calculation Process
  14. printf("Calculation: ");
    for (i = 1; i <= n; i++) {
        printf("%d", i);
        if (i < n) printf(" x ");
    }
    printf(" = %lld\n", factorial);
    
    • Creates a visual representation like "1 x 2 x 3 x 4 x 5 = 120".
    • Uses another loop to print each number.
    • Adds " x " between numbers (but not after the last number).

Output

Enter a number: 5

Factorial of 5 = 120

Calculation: 1 x 2 x 3 x 4 x 5 = 120

Advanced for Loop Features

#include <stdio.h>

int main() {
    int i, j;
    
    // Multiple variables
    for (i = 1, j = 10; i <= 5; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    
    return 0;
}

Output

i = 1, j = 10

i = 2, j = 9

i = 3, j = 8

i = 4, j = 7

i = 5, j = 6

  1. The condition i <= 5 controls the ENTIRE loop - not just i, but also j.
  2. Both i++ and j-- happen together in the update section, but only if the condition i <= 5 is true.
  3. When i becomes 6, the condition i <= 5 becomes false, and the loop stops completely.
  4. At that point, neither i++ nor j-- executes anymore.

So i stops decrementing because the loop condition is based on i. Even though j has its own decrement operation (j--), it's tied to the same loop condition as i.

Empty Parts in for Loop:

int i = 1;              // Initialize outside
for ( ; i <= 5; ) {     // Empty initialization and increment
    printf("%d ", i);
    i++;                // Increment inside loop
}

Practice Exercises

Exercise 1: Write a program that prints all odd numbers between 1 and 20 using a for loop.

Exercise 2: Create a program that calculates and displays the first 10 terms of the Fibonacci sequence (0, 1, 1, 2, 3, 5, 8, 13, 21, 34).

Answers:

Answer 1:

#include <stdio.h>

int main() {
    int i;
    
    printf("Odd numbers between 1 and 20:\n");
    
    for (i = 1; i <= 20; i++) {
        if (i % 2 == 1) {  // Check if odd
            printf("%d ", i);
        }
    }
    
    printf("\n");
    
    // Alternative method
    printf("Alternative method:\n");
    for (i = 1; i <= 20; i += 2) {  // Start at 1, increment by 2
        printf("%d ", i);
    }
    
    printf("\n");
    
    return 0;
}

Output

Odd numbers between 1 and 20:

1 3 5 7 9 11 13 15 17 19

Alternative method:

1 3 5 7 9 11 13 15 17 19

Answer 2:

#include <stdio.h>

int main() {
    int i;
    int first = 0, second = 1, next;
    
    printf("First 10 terms of Fibonacci sequence:\n");
    
    // First two terms
    printf("%d %d ", first, second);
    
    // Calculate and print remaining 8 terms
    for (i = 3; i <= 10; i++) {
        next = first + second;
        printf("%d ", next);
        
        // Update for next iteration
        first = second;
        second = next;
    }
    
    printf("\n");
    
    return 0;
}

Output

First 10 terms of Fibonacci sequence:

0 1 1 2 3 5 8 13 21 34

Chapter 9: while and do-while Loops

What are while and do-while Loops?

Unlike for loops which are best when you know how many times to repeat, while and do-while loops are used when you want to repeat based on a condition.

while Loop

The while loop checks the condition before executing the code block.

while (condition) {
    // Code to repeat
    // Don't forget to update the condition!
}
  • If condition is false initially, the loop never executes.
  • You must manually update variables to avoid infinite loops.
  • Best for situations where you might not need to execute the loop at all.

Code Example 1: Basic while Loop

#include <stdio.h>

int main() {
    int i = 1;
    
    printf("Counting with while loop:\n");
    
    while (i <= 5) {
        printf("Count: %d\n", i);
        i++;  // IMPORTANT: increment i to avoid infinite loop
    }
    
    printf("Loop ended!\n");
    
    return 0;
}

Output

Counting with while loop:

Count: 1

Count: 2

Count: 3

Count: 4

Count: 5

Loop ended!

Step-by-Step Execution:

Step i value Condition (i <= 5) Action
1 1 TRUE Print “Count: 1”, i becomes 2
2 2 TRUE Print “Count: 2”, i becomes 3
3 3 TRUE Print “Count: 3”, i becomes 4
4 4 TRUE Print “Count: 4”, i becomes 5
5 5 TRUE Print “Count: 5”, i becomes 6
6 6 FALSE Exit loop

Code Example 2: Number Guessing Game

#include <stdio.h>

int main() {
    int secret_number = 7;
    int guess;
    int attempts = 0;
    
    printf("=== Number Guessing Game ===\n");
    printf("I'm thinking of a number between 1 and 10.\n");
    
    while (guess != secret_number) {
        printf("Enter your guess: ");
        scanf("%d", &guess);
        attempts++;
        
        if (guess < secret_number) {
            printf("Too low! Try again.\n");
        } else if (guess > secret_number) {
            printf("Too high! Try again.\n");
        } else {
            printf("🎉 Congratulations! You guessed it!\n");
            printf("The number was %d.\n", secret_number);
            printf("You took %d attempts.\n", attempts);
        }
    }
    
    return 0;
}

Output

=== Number Guessing Game ===

I'm thinking of a number between 1 and 10.

Enter your guess: 5

Too low! Try again.

Enter your guess: 8

Too high! Try again.

Enter your guess: 7

🎉 Congratulations! You guessed it!

The number was 7.

You took 3 attempts.

Code Example 3: Sum Until User Enters 0

#include <stdio.h>

int main() {
    int number;
    int sum = 0;
    int count = 0;
    
    printf("Enter numbers to add (enter 0 to stop):\n");
    
    while (1) {  // Infinite loop - we'll break out when needed
        printf("Enter number: ");
        scanf("%d", &number);
        
        if (number == 0) {
            break;  // Exit the loop
        }
        
        sum += number;
        count++;
        printf("Running total: %d\n", sum);
    }
    
    if (count > 0) {
        printf("\nFinal Results:\n");
        printf("Total sum: %d\n", sum);
        printf("Numbers entered: %d\n", count);
        printf("Average: %.2f\n", (float)sum / count);
    } else {
        printf("No numbers were entered.\n");
    }
    
    return 0;
}

Output

Enter numbers to add (enter 0 to stop):

Enter number: 10

Running total: 10

Enter number: 25

Running total: 35

Enter number: 15

Running total: 50

Enter number: 0


Final Results:

Total sum: 50

Numbers entered: 3

Average: 16.67

do-while Loop

The do-while loop executes the code block first, then checks the condition.

Syntax

do {
    // Code to repeat
    // This executes at least once
} while (condition);

Key Difference:

  • while: Check condition first, then execute (may not execute at all)
  • do-while: Execute first, then check condition (executes at least once)

Code Example 4: Menu System with do-while

#include <stdio.h>

int main() {
    int choice;
    
    do {
        printf("\n=== Student Management System ===\n");
        printf("1. Add Student\n");
        printf("2. View Students\n");
        printf("3. Delete Student\n");
        printf("4. Exit\n");
        printf("Enter your choice (1-4): ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("Adding new student...\n");
                break;
            case 2:
                printf("Displaying all students...\n");
                break;
            case 3:
                printf("Deleting student...\n");
                break;
            case 4:
                printf("Thank you for using our system!\n");
                break;
            default:
                printf("Invalid choice! Please try again.\n");
        }
        
    } while (choice != 4);  // Continue until user chooses to exit
    
    return 0;
}

Output

=== Student Management System ===

1. Add Student

2. View Students

3. Delete Student

4. Exit

Enter your choice (1-4): 1

Adding new student...


=== Student Management System ===

1. Add Student

2. View Students

3. Delete Student

4. Exit

Enter your choice (1-4): 4

Thank you for using our system!

Code Example 5: Input Validation

#include <stdio.h>

int main() {
    int age;
    
    // Keep asking until valid age is entered
    do {
        printf("Enter your age (1-100): ");
        scanf("%d", &age);
        
        if (age < 1 || age > 100) {
            printf("Invalid age! Please enter between 1 and 100.\n");
        }
        
    } while (age < 1 || age > 100);
    
    printf("Thank you! Your age %d has been recorded.\n", age);
    
    // Determine category
    if (age < 13) {
        printf("Category: Child\n");
    } else if (age < 20) {
        printf("Category: Teenager\n");
    } else if (age < 60) {
        printf("Category: Adult\n");
    } else {
        printf("Category: Senior\n");
    }
    
    return 0;
}

Output

Enter your age (1-100): -5

Invalid age! Please enter between 1 and 100.

Enter your age (1-100): 150

Invalid age! Please enter between 1 and 100.

4. Exit

Enter your age (1-100): 25

Thank you! Your age 25 has been recorded.

Category: Adult

while vs do-while Comparison

Aspect While Loop do-while Loop
When condition is checked Before execution After execution
Minimum executions 0 times 1 time
Use when Condition might be false initially Must execute at least once
Common use cases Reading files, input validation Menus, “try again” scenarios

Loop Control Statements

break Statement

Exits the loop immediately:

#include <stdio.h>

int main() {
    int i = 1;
    
    while (i <= 10) {
        if (i == 6) {
            printf("Breaking at %d\n", i);
            break;  // Exit loop when i is 6
        }
        printf("%d ", i);
        i++;
    }
    
    return 0;
}

Output

1 2 3 4 5 Breaking at 6

continue Statement

Skips the rest of current iteration:

#include <stdio.h>

int main() {
    int i = 0;
    
    while (i < 10) {
        i++;
        if (i % 2 == 0) {
            continue;  // Skip even numbers
        }
        printf("%d ", i);  // Only prints odd numbers
    }
    
    return 0;
}

Output

1 3 5 7 9

Common Mistakes and Solutions

Mistake 1: Infinite Loop

// WRONG - infinite loop
int i = 1;
while (i <= 5) {
    printf("%d ", i);
    // Forgot to increment i!
}

// CORRECT
int i = 1;
while (i <= 5) {
    printf("%d ", i);
    i++;  // Don't forget this!
}

Mistake 2: Off-by-One Error

// Be careful with conditions
int i = 1;
while (i < 5) {    // This runs 4 times (1,2,3,4)
    printf("%d ", i);
    i++;
}

while (i <= 5) {   // This runs 5 times (1,2,3,4,5)
    printf("%d ", i);
    i++;
}

Practice Exercises

Exercise 1: Write a program using a while loop that finds and displays all factors of a given number.

Exercise 2: Create a simple ATM program using do-while loop that keeps showing the menu until the user chooses to exit. Include options for checking balance, deposit, and withdrawal.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    int number, i;
    
    printf("Enter a positive number: ");
    scanf("%d", &number);
    
    printf("Factors of %d are: ", number);
    
    i = 1;
    while (i <= number) {
        if (number % i == 0) {
            printf("%d ", i);
        }
        i++;
    }
    
    printf("\n");
    
    return 0;
}

Output

Enter a positive number: 5

Factors of 5 are: 15

Answer 2:

#include <stdio.h>

int main() {
    int choice;
    float balance = 1000.00;
    float amount;
    
    do {
        printf("\n=== ATM Machine ===\n");
        printf("1. Check Balance\n");
        printf("2. Deposit Money\n");
        printf("3. Withdraw Money\n");
        printf("4. Exit\n");
        printf("Choose an option: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("Your current balance: $%.2f\n", balance);
                break;
                
            case 2:
                printf("Enter deposit amount: $");
                scanf("%f", &amount);
                if (amount > 0) {
                    balance += amount;
                    printf("$%.2f deposited successfully!\n", amount);
                    printf("New balance: $%.2f\n", balance);
                } else {
                    printf("Invalid amount!\n");
                }
                break;
                
            case 3:
                printf("Enter withdrawal amount: $");
                scanf("%f", &amount);
                if (amount > 0 && amount <= balance) {
                    balance -= amount;
                    printf("$%.2f withdrawn successfully!\n", amount);
                    printf("Remaining balance: $%.2f\n", balance);
                } else if (amount > balance) {
                    printf("Insufficient funds!\n");
                } else {
                    printf("Invalid amount!\n");
                }
                break;
                
            case 4:
                printf("Thank you for using our ATM!\n");
                break;
                
            default:
                printf("Invalid choice! Please try again.\n");
        }
        
    } while (choice != 4);
    
    return 0;
}

Output

=== ATM Machine ===

1. Check Balance

2. Deposit Money

3. Withdraw Money

4. Exit

Choose an option: 2

Enter deposit amount: $2000

$2000.00 deposited successfully!

New balance: $3000.00


=== ATM Machine ===

1. Check Balance

2. Deposit Money

3. Withdraw Money

4. Exit

Choose an option: 1

Your current balance: $3000.00


=== ATM Machine ===

1. Check Balance

2. Deposit Money

3. Withdraw Money

4. Exit

Choose an option: 4

Thank you for using our ATM!

Chapter 10: Functions - Declaration and Definition

What are Functions?

A function is a block of code that performs a specific task. Think of it as a mini-program within your main program. Functions help organize code, avoid repetition, and make programs easier to understand and maintain.

Real-world analogy:

  • Calculator: Has separate functions for add, subtract, multiply, divide.
  • TV Remote: Each button performs a specific function.
  • Kitchen: You have separate tools for different tasks (microwave, blender, etc.).

Why Use Functions?

Benefit Description Example
Code Reusability Write once, use many times A function to calculate area can be used throughout the program
Organization Break large problems into smaller parts Split calculator into separate functions for each operation
Easier Debugging Find and fix errors in specific functions If multiplication is wrong, only check that function
Teamwork Different people can work on different functions One person writes math functions, another handles input

Basic Function Structure

Function Declaration (Prototype):

return_type function_name(parameter_list);

Function Definition:

return_type function_name(parameter_list) {
    // Function body
    return value;  // if return_type is not void
}

Function Call:

function_name(arguments);

Code Example 1: Simple Function Without Parameters

In C programming, the keywor void literally means "nothing" or "empty". It's a special data type that represents the absence of any data or value.

Think of void as telling the compiler: "There's nothing here" or "I don't need any value in this spot."

#include <stdio.h>

// Function declaration
void greet();

int main() {
    printf("Before calling function\n");
    greet();  // Function call
    printf("After calling function\n");
    
    return 0;
}

// Function definition
void greet() {
    printf("Hello! Welcome to C Programming!\n");
    printf("Have a great day!\n");
}

Output

Before calling function

Hello! Welcome to C Programming!

Have a great day!

After calling function

Components Explained:

Component Explanation
void greet(); Function declaration - tells compiler about the function
void Return type - function doesn't return any value
greet() Function name with empty parameter list
greet(); Function call in main()

Code Example 2: Function with Parameters

#include <stdio.h>

// Function declaration
void printInfo(char name[], int age);

int main() {
    // Function calls with different arguments
    printInfo("Alice", 25);
    printInfo("Bob", 30);
    printInfo("Carol", 22);
    
    return 0;
}

// Function definition
void printInfo(char name[], int age) {
    printf("Name: %s\n", name);
    printf("Age: %d years old\n", age);
    printf("Category: ");
    
    if (age < 18) {
        printf("Minor\n");
    } else if (age < 65) {
        printf("Adult\n");
    } else {
        printf("Senior\n");
    }
    
    printf("-------------------\n");
}

Output

Name: Alice

Age: 25 years old

Category: Adult

-------------------

Name: Bob

Age: 30 years old

Category: Adult

-------------------

Name: Carol

Age: 22 years old

Category: Adult

-------------------

Function Return Types

Code Example 3: Functions with Return Values

#include <stdio.h>

// Function declarations
int add(int a, int b);
float calculateArea(float length, float width);
int findMax(int x, int y, int z);

int main() {
    int sum;
    float area;
    int maximum;
    
    // Call functions and store return values
    sum = add(15, 25);
    area = calculateArea(5.5, 3.2);
    maximum = findMax(10, 25, 18);
    
    printf("Sum: %d\n", sum);
    printf("Area: %.2f\n", area);
    printf("Maximum: %d\n", maximum);
    
    return 0;
}

// Function to add two numbers
int add(int a, int b) {
    int result = a + b;
    return result;  // Return the sum
}

// Function to calculate rectangle area
float calculateArea(float length, float width) {
    return length * width;  // Direct return
}

// Function to find maximum of three numbers
int findMax(int x, int y, int z) {
    if (x >= y && x >= z) {
        return x;
    } else if (y >= x && y >= z) {
        return y;
    } else {
        return z;
    }
}

Output

Sum: 40

Area: 17.60

Maximum: 25

Return Types Reference:

Return Type Description Example
void Returns nothing void printMenu()
int Returns integer int add(int a, int b)
float Returns floating-point float calculateAverage()
char Returns character char getGrade(int marks)
double Returns double precision double getPi()

Code Example 4: Calculator with Functions

#include <stdio.h>

// Function declarations
float add(float a, float b);
float subtract(float a, float b);
float multiply(float a, float b);
float divide(float a, float b);
void displayMenu();

int main() {
    float num1, num2, result;
    int choice;
    
    do {
        displayMenu();
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        if (choice >= 1 && choice <= 4) {
            printf("Enter first number: ");
            scanf("%f", &num1);
            printf("Enter second number: ");
            scanf("%f", &num2);
        }
        
        switch (choice) {
            case 1:
                result = add(num1, num2);
                printf("%.2f + %.2f = %.2f\n", num1, num2, result);
                break;
            case 2:
                result = subtract(num1, num2);
                printf("%.2f - %.2f = %.2f\n", num1, num2, result);
                break;
            case 3:
                result = multiply(num1, num2);
                printf("%.2f * %.2f = %.2f\n", num1, num2, result);
                break;
            case 4:
                result = divide(num1, num2);
                if (num2 != 0) {
                    printf("%.2f / %.2f = %.2f\n", num1, num2, result);
                }
                break;
            case 5:
                printf("Thank you for using the calculator!\n");
                break;
            default:
                printf("Invalid choice! Please try again.\n");
        }
        printf("\n");
        
    } while (choice != 5);
    
    return 0;
}

void displayMenu() {
    printf("=== Calculator Menu ===\n");
    printf("1. Addition\n");
    printf("2. Subtraction\n");
    printf("3. Multiplication\n");
    printf("4. Division\n");
    printf("5. Exit\n");
}

float add(float a, float b) {
    return a + b;
}

float subtract(float a, float b) {
    return a - b;
}

float multiply(float a, float b) {
    return a * b;
}

float divide(float a, float b) {
    if (b != 0) {
        return a / b;
    } else {
        printf("Error: Division by zero!\n");
        return 0;
    }
}

Output

=== Calculator Menu ===

1. Addition

2. Subtraction

3. Multiplication

4. Division

5. Exit

Enter your choice: 1

Enter first number: 5

Enter second number: 3

5.00 + 3.00 = 8.00

Function Parameters vs Arguments

Understanding the Terminology:

Term Definition Example
Parameters Variables in function definition int add(int a, int b) - a and b are parameters
Arguments Actual values passed to function add(5, 3) - 5 and 3 are arguments

Code Example 5: Grade Management System

#include <stdio.h>

// Function declarations
float calculateAverage(float marks[], int size);
char assignGrade(float average);
void displayResult(char name[], float average, char grade);
int countPassing(float marks[], int size);

int main() {
    char studentName[50];
    float marks[5];
    float average;
    char finalGrade;
    int passingCount;
    int i;
    
    printf("Enter student name: ");
    scanf("%s", studentName);
    
    printf("Enter marks for 5 subjects:\n");
    for (i = 0; i < 5; i++) {
        printf("Subject %d: ", i + 1);
        scanf("%f", &marks[i]);
    }
    
    // Call functions
    average = calculateAverage(marks, 5);
    finalGrade = assignGrade(average);
    passingCount = countPassing(marks, 5);
    
    // Display results
    displayResult(studentName, average, finalGrade);
    printf("Subjects passed: %d out of 5\n", passingCount);
    
    return 0;
}

float calculateAverage(float marks[], int size) {
    float sum = 0;
    int i;
    
    for (i = 0; i < size; i++) {
        sum += marks[i];
    }
    
    return sum / size;
}

char assignGrade(float average) {
    if (average >= 90) return 'A';
    else if (average >= 80) return 'B';
    else if (average >= 70) return 'C';
    else if (average >= 60) return 'D';
    else return 'F';
}

void displayResult(char name[], float average, char grade) {
    printf("\n=== Student Report ===\n");
    printf("Name: %s\n", name);
    printf("Average: %.2f%%\n", average);
    printf("Grade: %c\n", grade);
    
    if (grade != 'F') {
        printf("Status: PASS\n");
    } else {
        printf("Status: FAIL\n");
    }
}

int countPassing(float marks[], int size) {
    int count = 0;
    int i;
    
    for (i = 0; i < size; i++) {
        if (marks[i] >= 50) {  // Assuming 50 is passing marks
            count++;
        }
    }
    
    return count;
}

Output

Enter student name: John

Enter marks for 5 subjects:

Subject 1: 85

Subject 2: 92

Subject 3: 78

Subject 4: 88

Subject 5: 90


=== Student Report ===

Name: John

Average: 86.60%

Grade: B

Status: PASS

Subjects passed: 5 out of 5

Practice Exercises

Exercise 1: Create a function that checks if a number is prime and returns 1 for prime, 0 for not prime.

Exercise 2: Write a program with functions to convert temperature between Celsius, Fahrenheit, and Kelvin.

Answers:

Answer 1:

#include <stdio.h>

// Function declaration
int isPrime(int num);

int main() {
    int number;
    
    printf("Enter a number: ");
    scanf("%d", &number);
    
    if (isPrime(number)) {
        printf("%d is a prime number.\n", number);
    } else {
        printf("%d is not a prime number.\n", number);
    }
    
    return 0;
}

// Function to check if number is prime
int isPrime(int num) {
    int i;
    
    if (num <= 1) {
        return 0;  // Not prime
    }
    
    for (i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            return 0;  // Not prime
        }
    }
    
    return 1;  // Prime
}

Output

Enter a number: 13

13 is a prime number.

Answer 2:

#include <stdio.h>

// Function declarations
float celsiusToFahrenheit(float celsius);
float fahrenheitToCelsius(float fahrenheit);
float celsiusToKelvin(float celsius);
float kelvinToCelsius(float kelvin);
void displayMenu();

int main() {
    int choice;
    float temperature, result;
    
    do {
        displayMenu();
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        if (choice >= 1 && choice <= 4) {
            printf("Enter temperature: ");
            scanf("%f", &temperature);
        }
        
        switch (choice) {
            case 1:
                result = celsiusToFahrenheit(temperature);
                printf("%.2f°C = %.2f°F\n", temperature, result);
                break;
            case 2:
                result = fahrenheitToCelsius(temperature);
                printf("%.2f°F = %.2f°C\n", temperature, result);
                break;
            case 3:
                result = celsiusToKelvin(temperature);
                printf("%.2f°C = %.2f K\n", temperature, result);
                break;
            case 4:
                result = kelvinToCelsius(temperature);
                printf("%.2f K = %.2f°C\n", temperature, result);
                break;
            case 5:
                printf("Goodbye!\n");
                break;
            default:
                printf("Invalid choice!\n");
        }
        
    } while (choice != 5);
    
    return 0;
}

void displayMenu() {
    printf("\n=== Temperature Converter ===\n");
    printf("1. Celsius to Fahrenheit\n");
    printf("2. Fahrenheit to Celsius\n");
    printf("3. Celsius to Kelvin\n");
    printf("4. Kelvin to Celsius\n");
    printf("5. Exit\n");
}

float celsiusToFahrenheit(float celsius) {
    return (celsius * 9.0 / 5.0) + 32;
}

float fahrenheitToCelsius(float fahrenheit) {
    return (fahrenheit - 32) * 5.0 / 9.0;
}

float celsiusToKelvin(float celsius) {
    return celsius + 273.15;
}

float kelvinToCelsius(float kelvin) {
    return kelvin - 273.15;
}

Output

=== Temperature Converter ===

1. Celsius to Fahrenheit

2. Fahrenheit to Celsius

3. Celsius to Kelvin

4. Kelvin to Celsius

5. Exit

Enter your choice: 1

Enter temperature: 37

37.00°C = 98.60°F

Chapter 11: Recursion

What is Recursion?

Recursion is when a function calls itself to solve a smaller version of the same problem. Think of it like Russian nesting dolls - each doll contains a smaller version of itself.

Real-world Examples:

  • Mirrors facing each other: Creates infinite reflections
  • Fractals in nature: Tree branches, snowflakes
  • Searching in folders: Opening folder → subfolder → sub-subfolder

Basic Structure of Recursion

Every recursive function needs two parts:

Component Purpose Example
Base Case Stopping condition if (n == 0) return 1;
Recursive Case Function calls itself with smaller input return n * factorial(n-1);

Code Example 1: Factorial Using Recursion

#include <stdio.h>

// Function declaration
long factorial(int n);

int main() {
    int number;
    
    printf("Enter a number: ");
    scanf("%d", &number);
    
    if (number < 0) {
        printf("Factorial is not defined for negative numbers.\n");
    } else {
        printf("Factorial of %d = %ld\n", number, factorial(number));
    }
    
    return 0;
}

// Recursive function to calculate factorial
long factorial(int n) {
    // Base case
    if (n == 0 || n == 1) {
        return 1;
    }
    
    // Recursive case
    return n * factorial(n - 1);
}

Output

Enter a number: 5

Factorial of 5 = 120

How Recursion Works (Factorial of 5):

Step Function Call Action Value Returned
1 factorial(5) 5 * factorial(4) Waits for factorial(4)
2 factorial(4) 4 * factorial(3) Waits for factorial(3)
3 factorial(3) 3 * factorial(2) Waits for factorial(2)
4 factorial(2) 2 * factorial(1) Waits for factorial(1)
5 factorial(1) Base case reached Returns 1
6 Back to factorial(2) 2 * 1 Returns 2
7 Back to factorial(3) 3 * 2 Returns 6
8 Back to factorial(4) 4 * 6 Returns 24
9 Back to factorial(5) 5 * 24 Returns 120

What is the Fibonacci Sequence?

The Fibonacci sequence starts with 0 and 1, and each subsequent number is the sum of the previous two numbers:

Sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

Mathematical Formula:

  • F(0) = 0
  • F(1) = 1
  • F(n) = F(n-1) + F(n-2) for n > 1

Code Example 2: Fibonacci Sequence

#include <stdio.h>

// Function declaration
int fibonacci(int n);

int main() {
    int n, i;
    
    printf("Enter number of terms: ");
    scanf("%d", &n);
    
    printf("Fibonacci sequence: ");
    for (i = 0; i < n; i++) {
        printf("%d ", fibonacci(i));
    }
    printf("\n");
    
    return 0;
}

// Recursive function for Fibonacci
int fibonacci(int n) {
    // Base cases
    if (n == 0) {
        return 0;
    }
    if (n == 1) {
        return 1;
    }
    
    // Recursive case
    return fibonacci(n - 1) + fibonacci(n - 2);
}

Output

Enter number of terms: 8

Fibonacci sequence: 0 1 1 2 3 5 8 13

Fibonacci Call Tree for fibonacci(4):

                fibonacci(4)
               /          \
      fibonacci(3)       fibonacci(2)
      /          \         /          \
fibonacci(2) fibonacci(1) fibonacci(1) fibonacci(0)
   /      \
fibonacci(1) fibonacci(0)
    

Code Example 3: Sum of Natural Numbers

#include <stdio.h>

// Function declaration
int sumNatural(int n);

int main() {
    int number;
    
    printf("Enter a positive number: ");
    scanf("%d", &number);
    
    if (number < 1) {
        printf("Please enter a positive number.\n");
    } else {
        printf("Sum of first %d natural numbers = %d\n", 
               number, sumNatural(number));
    }
    
    return 0;
}

// Recursive function to find sum of natural numbers
int sumNatural(int n) {
    // Base case
    if (n == 1) {
        return 1;
    }
    
    // Recursive case
    return n + sumNatural(n - 1);
}

Output

Enter a positive number: 5

Sum of first 5 natural numbers = 15

Code Example 4: Power Calculation

#include <stdio.h>

// Function declaration
double power(double base, int exponent);

int main() {
    double base;
    int exp;
    
    printf("Enter base: ");
    scanf("%lf", &base);
    printf("Enter exponent: ");
    scanf("%d", &exp);
    
    printf("%.2f raised to power %d = %.2f\n", 
           base, exp, power(base, exp));
    
    return 0;
}

// Recursive function to calculate power
double power(double base, int exponent) {
    // Base case
    if (exponent == 0) {
        return 1;
    }
    
    // Handle negative exponents
    if (exponent < 0) {
        return 1 / power(base, -exponent);
    }
    
    // Recursive case
    return base * power(base, exponent - 1);
}

How Recursion Works Here

Case 1: Base Case (Stopping Condition)

if (exponent == 0) {
    return 1;
}
  • Mathematical fact: Any number⁰ = 1.
  • This is the base case that stops the recursion.
  • Without this, the function would call itself forever!.

Case 2: Negative Exponents

if (exponent < 0) {
    return 1 / power(base, -exponent);
}
  • Mathematical fact: x⁻ⁿ = 1/xⁿ.
  • Example: 2⁻³ = 1/2³ = 1/8 = 0.125.
  • Converts negative exponent to positive and takes reciprocal.

Case 3: Positive Exponents (Recursive Case)

 base * power(base, exponent - 1);
  • Mathematical fact:xⁿ = x × x^(n-1).
  • Example: 2³ = 2 × 2² = 2 × 2 × 2¹ = 2 × 2 × 2 × 2⁰ = 2 × 2 × 2 × 1 = 8.

Step-by-Step Execution Example

Let's trace through power(3, 4) (calculating 3⁴):

Step Function Call Condition Action Returns
1st power(3, 4) 4 ≠ 0, 4 > 0 3 * power(3, 3) Waits for result
2nd power(3, 3) 3 ≠ 0, 3 > 0 3 * power(3, 2) Waits for result
3rd power(3, 2) 2 ≠ 0, 2 > 0 3 * power(3, 1) Waits for result
4th power(3, 1) 1 ≠ 0, 1 > 0 3 * power(3, 0) Waits for result
5th power(3, 0) 0 == 0 Base case Returns 1

Now the recursion "unwinds":

  • 4th call: 3 * 1 = 3 ← Returns 3
  • 3rd call: 3 * 3 = 9 ← Returns 9
  • 2nd call: 3 * 9 = 27 ← Returns 27
  • 1st call: 3 * 27 = 81 ← Final result: 81

Output

Enter base: 2.5

Enter exponent: 3

2.50 raised to power 3 = 15.63

Code Example 5: Binary Search (Recursive)

Binary Search is like looking up a word in a dictionary. You don't start from page 1 - you open to the middle, see if your word comes before or after, then eliminate half the dictionary and repeat.

#include <stdio.h>

// Function declarations
int binarySearch(int arr[], int left, int right, int target);
void displayArray(int arr[], int size);

int main() {
    int arr[] = {2, 5, 8, 12, 16, 23, 38, 45, 56, 67, 78};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target, result;
    
    printf("Array: ");
    displayArray(arr, size);
    
    printf("Enter number to search: ");
    scanf("%d", &target);
    
    result = binarySearch(arr, 0, size - 1, target);
    
    if (result != -1) {
        printf("Number %d found at index %d\n", target, result);
    } else {
        printf("Number %d not found in array\n", target);
    }
    
    return 0;
}

// Recursive binary search
int binarySearch(int arr[], int left, int right, int target) {
    // Base case: element not found
    if (left > right) {
        return -1;
    }
    
    int mid = left + (right - left) / 2;
    
    // Base case: element found
    if (arr[mid] == target) {
        return mid;
    }
    
    // Recursive cases
    if (target < arr[mid]) {
        return binarySearch(arr, left, mid - 1, target);  // Search left half
    } else {
        return binarySearch(arr, mid + 1, right, target);  // Search right half
    }
}

void displayArray(int arr[], int size) {
    int i;
    for (i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

The Binary Search Algorithm

This is the heart of the program:

int binarySearch(int arr[], int left, int right, int target) {
    // Base case: element not found
    if (left > right) {
        return -1;
    }
    
    int mid = left + (right - left) / 2;
    
    // Base case: element found
    if (arr[mid] == target) {
        return mid;
    }
    
    // Recursive cases
    if (target < arr[mid]) {
        return binarySearch(arr, left, mid - 1, target);  // Search left half
    } else {
        return binarySearch(arr, mid + 1, right, target);  // Search right half
    }
}

How It Works - Step by Step

Parameters:

  • arr[] = the sorted array.
  • left = leftmost index to search.
  • right = rightmost index to search.
  • target = number we're looking for.

The Algorithm:

  1. Check if search space is empty:
  2. if (left > right) {
        return -1;  // Not found
    }
    
  3. Find the middle element:
  4. int mid = left + (right - left) / 2;
    
    • This finds the middle index between left and right.
  5. Check if we found it:
  6. if (arr[mid] == target) {
        return mid;  // Found! Return the index
    }
    
  7. Decide which half to search:
  8. if (target < arr[mid]) {
        return binarySearch(arr, left, mid - 1, target);  // Search left half
    } else {
        return binarySearch(arr, mid + 1, right, target);  // Search right half
    }
    

Example Walkthrough

Let's trace through searching for 23 in the array {2, 5, 8, 12, 16, 23, 38, 45, 56, 67, 78}:

Step left right mid arr[mid] target Action
1 0 10 5 23 23 FOUND! Return 5

Lucky! We found it on the first try because 23 happened to be in the middle.

Let's try searching for 12:

Step left right mid arr[mid] target Comparison Action
1 0 10 5 23 12 12 < 23 Search left half
2 0 4 2 8 12 12 > 8 Search right half
3 3 4 3 12 12 12 == 12 FOUND! Return 3

Visual Example

textArray: [2, 5, 8, 12, 16, 23, 38, 45, 56, 67, 78]

Index: 0 1 2 3 4 5 6 7 8 9 10

Searching for 12:


Step 1: Check middle (index 5, value 23)

        12 < 23, so search LEFT half

        [2, 5, 8, 12, 16] ⟵ New search area


Step 2: Check middle of left half (index 2, value 8)

        12 > 8, so search RIGHT half of this section

        [12, 16] ⟵ New search area


Step 3: Check middle (index 3, value 12)

        12 == 12 ⟶ FOUND at index 3!

Output

Array: 2 5 8 12 16 23 38 45 56 67 78

Enter number to search: 23

Number 23 found at index 5

Recursion vs Iteration Comparison

Aspect Recursion Iteration
Memory Usage Higher (function calls stored in stack) Lower
Speed Usually slower Usually faster
Code Complexity Often simpler and cleaner Can be more complex
Stack Overflow Risk Yes (for deep recursion) No
Best for Tree traversal, mathematical problems Simple loops, large datasets

Example - Factorial Both Ways:

Recursive:

long factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

Iterative:

long factorial(int n) {
    long result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

Types of Recursion

  1. Direct Recursion

  2. Function calls itself directly:

    int factorial(int n) {
        if (n <= 1) return 1;
        return n * factorial(n - 1);  // Direct call to itself
    }
    
  3. Indirect Recursion

  4. Functions call each other in a cycle:

    void functionA(int n) {
        if (n > 0) {
            printf("A: %d ", n);
            functionB(n - 1);  // Calls functionB
        }
    }
    
    void functionB(int n) {
        if (n > 0) {
            printf("B: %d ", n);
            functionA(n - 1);  // Calls functionA
        }
    }
    

Common Recursion Problems and Solutions

Problem 1: Stack Overflow

// BAD - No base case
int badFunction(int n) {
    return badFunction(n - 1);  // Infinite recursion!
}

// GOOD - Has base case
int goodFunction(int n) {
    if (n <= 0) return 0;  // Base case
    return goodFunction(n - 1);
}

Problem 2: Inefficient Fibonacci

The recursive Fibonacci is very slow for large numbers because it recalculates the same values multiple times.

Better approach - Memoization:

#include 

int memo[100] = {-1}; // Initialize with -1

int fibonacciMemo(int n) {
    if (n <= 1) return n;
    
    if (memo[n] != -1) {
        return memo[n];  // Return cached result
    }
    
    memo[n] = fibonacciMemo(n-1) + fibonacciMemo(n-2);
    return memo[n];
}

Practice Exercises

Exercise 1: Write a recursive function to find the Greatest Common Divisor (GCD) of two numbers using Euclidean algorithm.

Exercise 2: Create a recursive function to reverse a string.

Answers:

Answer 1:

#include <stdio.h>

// Function declaration
int gcd(int a, int b);

int main() {
    int num1, num2;
    
    printf("Enter two numbers: ");
    scanf("%d %d", &num1, &num2);
    
    printf("GCD of %d and %d = %d\n", num1, num2, gcd(num1, num2));
    
    return 0;
}

// Recursive function to find GCD using Euclidean algorithm
int gcd(int a, int b) {
    // Base case
    if (b == 0) {
        return a;
    }
    
    // Recursive case
    return gcd(b, a % b);
}

Line-by-Line Breakdown

The Magic: Recursive GCD Function

int gcd(int a, int b) {
    // Base case
    if (b == 0) {
        return a;
    }
    
    // Recursive case
    return gcd(b, a % b);
}

This function implements the famous Euclidean Algorithm - one of the oldest and most efficient algorithms in mathematics!

Step-by-Step Execution Example

Let's trace through gcd(48, 18):

Call Function Call a b b == 0? a % b Action Returns
1st gcd(48, 18) 48 18 No 48 % 18 = 12 Call gcd(18, 12) Waits...
2nd gcd(18, 12) 18 12 No 18 % 12 = 6 Call gcd(12, 6) Waits...
3rd gcd(12, 6) 12 6 No 12 % 6 = 0 Call gcd(6, 0) Waits...
4th gcd(6, 0) 6 0 Yes! - Base case reached - Returns 6 6

Now the recursion "unwinds":

  • 3rd call returns: 6
  • 2nd call returns: 6
  • 1st call returns: 6
  • Final result: GCD(48, 18) = 6

Visual Representation

GCD(48, 18)

    ↓

GCD(18, 12)  [because 48 % 18 = 12]

    ↓

GCD(12, 6)    [because 18 % 12 = 6]

    ↓

GCD(6, 0)    [because 12 % 6 = 0]

    ↓

Return 6     [BASE CASE: when b = 0, return a]

Output

Enter two numbers: 48 18

GCD of 48 and 18 = 6

How it calculated:

  1. gcd(48, 18)gcd(18, 12) [48 % 18 = 12]
  2. gcd(18, 12)gcd(12, 6) [18 % 12 = 6]
  3. gcd(12, 6)gcd(6, 0) [12 % 6 = 0]
  4. gcd(6, 0)return 6 [base case]

Answer 2:

#include <stdio.h>
#include <string.h>

// Function declarations
void reverseString(char str[], int start, int end);
void printString(char str[]);

int main() {
    char str[100];
    
    printf("Enter a string: ");
    gets(str);  // Read string with spaces
    
    printf("Original string: ");
    printString(str);
    
    reverseString(str, 0, strlen(str) - 1);
    
    printf("Reversed string: ");
    printString(str);
    
    return 0;
}

// Recursive function to reverse string
void reverseString(char str[], int start, int end) {
    // Base case
    if (start >= end) {
        return;
    }
    
    // Swap characters
    char temp = str[start];
    str[start] = str[end];
    str[end] = temp;
    
    // Recursive call
    reverseString(str, start + 1, end - 1);
}

void printString(char str[]) {
    printf("%s\n", str);
}

The Magic: Recursive String Reversal Function

// Recursive function to reverse string
void reverseString(char str[], int start, int end) {
    // Base case
    if (start >= end) {
        return;
    }
    
    // Swap characters
    char temp = str[start];
    str[start] = str[end];
    str[end] = temp;
    
    // Recursive call
    reverseString(str, start + 1, end - 1);
}

Understanding the Algorithm

The Strategy:

The algorithm uses a "meet in the middle"" approach:

  1. Swap the first and last characters.
  2. Move inward: start goes right, end goes left.
  3. Repeat until they meet in the middle.

Visual Example:

Let's reverse the string "HELLO"":

Original:    H  E  L  L  O

Index:         0  1  2  3  4

                     ↑                ↑

                 start          end

Step-by-Step Execution Trace

Call Function Call Parameters (start, end) Condition Check Swap Performed String State Recursive Next Call
1 reverseString("HELLO", 0, 4) start=0, end=4 0 >= 4? → No 'H' ↔ 'O' "OELLH" reverseString("OELLH", 1, 3)
2 reverseString("OELLH", 1, 3) start=1, end=3 1 >= 3? → No 'E' ↔ 'L' "OLLEH" reverseString("OLLEH", 2, 2)
3 reverseString("OLLEH", 2, 2) start=2, end=2 2 >= 2? → Yes (Base) (no swap) "OLLEH" (returns, unwinds call stack)

Visual Step-by-Step Process

Step 0: H E L L O  (Original)

            ↑           ↑     (start=0, end=4)


Step 1: O E L L H  (After swap H ↔ O)

                ↑    ↑        (start=1, end=3)


Step 2: O L L E H  (After swap E ↔ L)

                   ↑          (start=2, end=2)


Step 3: O L L E H  (Base case: start >= end)

(DONE!)

Output

Enter a string: HELLO

Enter a string: HELLO

Reversed string: OLLEH

Chapter 12: Arrays - 1D Arrays

What are Arrays?

An array is a collection of elements of the same data type stored in consecutive memory locations. Think of it as a row of boxes, each labeled with a number (index), where you can store similar items.

Real-world Examples:

  • Classroom seats: Row of chairs numbered 1, 2, 3…
  • Apartment building: Units numbered 101, 102, 103…
  • Parking lot: Spaces numbered 1, 2, 3…

Why Use Arrays?

Method Code Example Description
Declaration only int numbers[5]; Creates array, values are garbage
With initialization int numbers[5] = {10, 20, 30, 40, 50}; All values specified
Partial initialization int numbers[5] = {10, 20}; First 2 values set, rest are 0
Size auto-calculated int numbers[] = {10, 20, 30}; Size becomes 3 automatically

Code Example 1: Basic Array Operations

#include <stdio.h>

int main() {
    // Array declaration and initialization
    int marks[5] = {85, 92, 78, 90, 88};
    int i;
    
    // Display array elements
    printf("Student marks:\n");
    for (i = 0; i < 5; i++) {
        printf("Student %d: %d\n", i + 1, marks[i]);
    }
    
    // Calculate and display sum and average
    int sum = 0;
    for (i = 0; i < 5; i++) {
        sum += marks[i];
    }
    
    float average = (float)sum / 5;
    
    printf("\nTotal marks: %d\n", sum);
    printf("Average marks: %.2f\n", average);
    
    return 0;
}

Output

Student marks:

Student 1: 85

Student 2: 92

Student 3: 78

Student 4: 90

Student 5: 88


Total marks: 433

Average marks: 86.60

The program lists each student's mark, then prints the total and the average with two decimal places.

Code Example 2: Input and Output with Arrays

#include <stdio.h>

int main() {
    int size;
    int i;
    
    printf("Enter number of elements: ");
    scanf("%d", &size);
    
    int numbers[size];  // Variable-length array (C99 feature)
    
    // Input array elements
    printf("Enter %d numbers:\n", size);
    for (i = 0; i < size; i++) {
        printf("Element %d: ", i + 1);
        scanf("%d", &numbers[i]);
    }
    
    // Display array elements
    printf("\nYou entered:\n");
    for (i = 0; i < size; i++) {
        printf("numbers[%d] = %d\n", i, numbers[i]);
    }
    
    return 0;
}

Output

Enter number of elements: 4

Enter 4 numbers:

Element 1: 15

Element 2: 25

Element 3: 35

Element 4: 45


You entered:

numbers[0] = 15

numbers[1] = 25

numbers[2] = 35

numbers[3] = 45

Code Example 3: Finding Maximum and Minimum

#include <stdio.h>

int main() {
    int numbers[] = {45, 23, 67, 12, 89, 34, 78};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    int i;
    
    // Initialize max and min with first element
    int max = numbers[0];
    int min = numbers[0];
    int maxIndex = 0;
    int minIndex = 0;
    
    // Find maximum and minimum
    for (i = 1; i < size; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
            maxIndex = i;
        }
        if (numbers[i] < min) {
            min = numbers[i];
            minIndex = i;
        }
    }
    
    // Display array
    printf("Array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    
    printf("\nMaximum value: %d (at index %d)\n", max, maxIndex);
    printf("Minimum value: %d (at index %d)\n", min, minIndex);
    
    return 0;
}

Output

Array: 45 23 67 12 89 34 78

Maximum value: 89 (at index 4)

Minimum value: 12 (at index 3)

Code Example 4: Searching in Arrays

#include <stdio.h>

int main() {
    int numbers[] = {10, 25, 30, 45, 50, 65, 70};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    int search, found = 0, position = -1;
    int i;
    
    // Display array
    printf("Array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    
    printf("\nEnter number to search: ");
    scanf("%d", &search);
    
    // Linear search
    for (i = 0; i < size; i++) {
        if (numbers[i] == search) {
            found = 1;
            position = i;
            break;  // Exit loop once found
        }
    }
    
    // Display result
    if (found) {
        printf("Number %d found at index %d (position %d)\n", 
               search, position, position + 1);
    } else {
        printf("Number %d not found in the array\n", search);
    }
    
    return 0;
}

Output

Array: 10 25 30 45 50 65 70

Enter number to search: 45

Number 45 found at index 3 (position 4)

Code Example 5: Array Sorting (Bubble Sort)

#include <stdio.h>

int main() {
    int numbers[] = {64, 34, 25, 12, 22, 11, 90};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    int i, j, temp;
    
    printf("Original array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    
    // Bubble sort algorithm
    for (i = 0; i < size - 1; i++) {
        for (j = 0; j < size - i - 1; j++) {
            if (numbers[j] > numbers[j + 1]) {
                // Swap elements
                temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
            }
        }
    }
    
    printf("\nSorted array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    return 0;
}

The Bubble Sort Algorithm Explained

The Main Logic: Nested Loops

for (i = 0; i < size - 1; i++) {           // Outer loop
    for (j = 0; j < size - i - 1; j++) {   // Inner loop
        if (numbers[j] > numbers[j + 1]) {
            // Swap elements
            temp = numbers[j];
            numbers[j] = numbers[j + 1];
            numbers[j + 1] = temp;
        }
    }
}

The Swapping Process

if (numbers[j] > numbers[j + 1]) {
    temp = numbers[j];              // Store first element
    numbers[j] = numbers[j + 1];    // Move second to first position  
    numbers[j + 1] = temp;          // Move first to second position
}

Example swap: If we have [64, 34] and 64 > 34:

  1. temp = 64 (save 64)
  2. numbers = 34 (move 34 to first position)
  3. numbers = 64 (move 64 to second position)
  4. numbers = 64 (move 64 to second position)

Visual Step-by-Step Execution

Let's trace through the first few steps:

Initial Array:

[64] [34] [25] [12] [22] [11] [90]

Pass 1 (i = 0):

Compare 64 & 34: 64 > 34 → SWAP → [34] [64] [25] [12] [22] [11] [90]

Compare 64 & 25: 64 > 25 → SWAP → [34] [25] [64] [12] [22] [11] [90]

Compare 64 & 12: 64 > 12 → SWAP → [34] [25] [12] [64] [22] [11] [90]

Compare 64 & 22: 64 > 22 → SWAP → [34] [25] [12] [22] [64] [11] [90]

Compare 64 & 11: 64 > 11 → SWAP → [34] [25] [12] [22] [11] [64] [90]

Compare 64 & 90: 64 < 90 → NO SWAP → [34] [25] [12] [22] [11] [64] [90]

Result after Pass 1: [34, 25, 12, 2, 11, 64, 90]

Pass 2 (i = 1):

Compare 34 & 25: 34 > 25 → SWAP → [25] [34] [12] [22] [11] [64] [90]

Compare 34 & 12: 34 > 12 → SWAP → [25] [12] [34] [22] [11] [64] [90]

Compare 34 & 22: 34 > 22 → SWAP → [25] [12] [22] [34] [11] [64] [90]

Compare 34 & 11: 34 > 11 → SWAP → [25] [12] [22] [11] [34] [64] [90]

Compare 34 & 64: 34 < 64 → NO SWAP → [25] [12] [22] [11] [34] [64] [90]

Result after Pass 2: [25, 12, 22, 11, 34, 64, 90] and so on.

Complete Execution Trace

Here's what happens in each pass:

Original: [64, 34, 25, 12, 22, 11, 90]

Pass 1: [34, 25, 12, 22, 11, 64, 90] ← 90 in place

Pass 2: [25, 12, 22, 11, 34, 64, 90] ← 64 in place

Pass 3: [12, 22, 11, 25, 34, 64, 90] ← 34 in place

Pass 4: [12, 11, 22, 25, 34, 64, 90] ← 25 in place

Pass 5: [11, 12, 22, 25, 34, 64, 90] ← 22 in place

Pass 6: [11, 12, 22, 25, 34, 64, 90] ← 12 in place (11 automatically correct)

Final: [11, 12, 22, 25, 34, 64, 90] ← Fully sorted!

Common Array Operations

1. Copying Arrays

#include <stdio.h>

int main() {
    int source[] = {1, 2, 3, 4, 5};
    int destination[5];
    int size = 5;
    int i;
    
    // Copy array elements
    for (i = 0; i < size; i++) {
        destination[i] = source[i];
    }
    
    // Display both arrays
    printf("Source: ");
    for (i = 0; i < size; i++) {
        printf("%d ", source[i]);
    }
    
    printf("\nDestination: ");
    for (i = 0; i < size; i++) {
        printf("%d ", destination[i]);
    }
    printf("\n");
    
    return 0;
}

2. Reversing an Array

#include <stdio.h>

int main() {
    int numbers[] = {1, 2, 3, 4, 5, 6};
    int size = sizeof(numbers) / sizeof(numbers[^0]);
    int i, temp;
    
    printf("Original: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    
    // Reverse array
    for (i = 0; i < size / 2; i++) {
        temp = numbers[i];
        numbers[i] = numbers[size - 1 - i];
        numbers[size - 1 - i] = temp;
    }
    
    printf("\nReversed: ");
    for (i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    return 0;
}

Visual Step-by-Step Execution

Initial State:

Index:  [0] [1] [2] [3] [4] [5]

Values:  1  2  3  4  5  6

             ↑                  ↑

            i=0           size-1-i=5

Iteration 1 (i = 0):

temp = numbers[0];           // temp = 1
numbers[0] = numbers[5];     // numbers[0] = 6  
numbers[5] = temp;           // numbers[5] = 1

Result:

Index:   [0] [1] [2] [3] [4] [5]

Values:   6   2   3   4   5   1

Iteration 2 (i = 1):

temp = numbers[1];           // temp = 2
numbers[1] = numbers[4];     // numbers[1] = 5
numbers[4] = temp;           // numbers[4] = 2

Result:

Index:  [0] [1] [2] [3] [4] [5]

Values:  6  5  3  4  2  1

Iteration 3 (i = 2):

temp = numbers[2];           // temp = 3
numbers[2] = numbers[3];     // numbers[2] = 4
numbers[3] = temp;           // numbers[3] = 3

Final Result:

Index:  [0] [1] [2] [3] [4] [5]

Values:  6  5  4  3  2  1

Complete Execution Summary

Original:     [1, 2, 3, 4, 5, 6]

 

Iteration 1:  [6, 2, 3, 4, 5, 1]  ← Swapped positions 0↔5

Iteration 2:  [6, 5, 3, 4, 2, 1]  ← Swapped positions 1↔4

Iteration 3:  [6, 5, 4, 3, 2, 1]  ← Swapped positions 2↔3

 

Final Result: [6, 5, 4, 3, 2, 1]  ← Fully reversed!

Output

Original: 1 2 3 4 5 6

Reversed: 6 5 4 3 2 1

Array with Functions

Code Example 6: Array Functions

#include <stdio.h>

// Function declarations
void displayArray(int arr[], int size);
int findSum(int arr[], int size);
float findAverage(int arr[], int size);
int findMax(int arr[], int size);

int main() {
    int marks[] = {85, 92, 78, 96, 88, 79, 91};
    int size = sizeof(marks) / sizeof(marks[0]);
    
    printf("Student Marks Analysis\n");
    printf("=====================\n");
    
    displayArray(marks, size);
    
    printf("Total marks: %d\n", findSum(marks, size));
    printf("Average: %.2f\n", findAverage(marks, size));
    printf("Highest mark: %d\n", findMax(marks, size));
    
    return 0;
}

void displayArray(int arr[], int size) {
    int i;
    printf("Marks: ");
    for (i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int findSum(int arr[], int size) {
    int sum = 0;
    int i;
    for (i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum;
}

float findAverage(int arr[], int size) {
    return (float)findSum(arr, size) / size;
}

int findMax(int arr[], int size) {
    int max = arr[0];
    int i;
    for (i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

Output

Student Marks Analysis

=====================

Marks: 85 92 78 96 88 79 91

Total marks: 609

Average: 87.00

Highest mark: 96

Common Mistakes with Arrays

  1. Array Bounds Error
  2. int arr[5] = {1, 2, 3, 4, 5};
    printf("%d", arr[5]);  // ERROR! Index 5 is out of bounds
    printf("%d", arr[4]);  // CORRECT! Last valid index is 4
    
  3. Not Initializing Arrays
  4. int arr[5];
    // arr contains garbage values
    // Always initialize: int arr[5] = {0}; for all zeros
    
  5. Confusion with Size
  6. int arr[10];
    int size = sizeof(arr) / sizeof(arr[0]);  // Correct way to get size
    // Don't assume size, always calculate or track it
    

Practice Exercises

Exercise 1: Write a program that reads 10 integers into an array and counts how many are positive, negative, and zero.

Exercise 2: Create a program that removes duplicate elements from an array and displays the unique elements

Answers:

Answer 1:

#include <stdio.h>

int main() {
    int numbers[10];
    int i;
    int positive = 0, negative = 0, zero = 0;
    
    printf("Enter 10 integers:\n");
    for (i = 0; i < 10; i++) {
        printf("Number %d: ", i + 1);
        scanf("%d", &numbers[i]);
        
        if (numbers[i] > 0) {
            positive++;
        } else if (numbers[i] < 0) {
            negative++;
        } else {
            zero++;
        }
    }
    
    printf("\nArray: ");
    for (i = 0; i < 10; i++) {
        printf("%d ", numbers[i]);
    }
    
    printf("\n\nResults:\n");
    printf("Positive numbers: %d\n", positive);
    printf("Negative numbers: %d\n", negative);
    printf("Zero count: %d\n", zero);
    
    return 0;
}

Output

Enter 10 integers:

Number 1: 7

Number 2: -3

Number 3: 0

Number 4: 12

Number 5: -8

Number 6: 0

Number 7: 5

Number 8: 0

Number 9: -2

Number 10: 4


Array: 7 -3 0 12 -8 0 5 0 -2 4


Results:

Positive numbers: 4

Negative numbers: 3

Zero count: 3

Answer 2:

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 2, 3, 4, 4, 5, 1, 6, 5};
    int size = sizeof(arr) / sizeof(arr[0]);
    int unique[size];
    int uniqueCount = 0;
    int i, j, isDuplicate;
    
    printf("Original array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    
    // Find unique elements
    for (i = 0; i < size; i++) {
        isDuplicate = 0;
        
        // Check if element already exists in unique array
        for (j = 0; j < uniqueCount; j++) {
            if (arr[i] == unique[j]) {
                isDuplicate = 1;
                break;
            }
        }
        
        // If not duplicate, add to unique array
        if (!isDuplicate) {
            unique[uniqueCount] = arr[i];
            uniqueCount++;
        }
    }
    
    printf("\nUnique elements: ");
    for (i = 0; i < uniqueCount; i++) {
        printf("%d ", unique[i]);
    }
    
    printf("\nTotal unique elements: %d\n", uniqueCount);
    
    return 0;
}

Output

Original array: 1 2 2 3 4 4 5 1 6 5

Unique elements: 1 2 3 4 5 6

Total unique elements: 6

Step-by-Step Run Through (Visualized)

Starting arrays:

arr[ ] = 1, 2, 2, 3, 4, 4, 5, 1, 6, 5

unique[ ] = (empty)

Step arr[i] Is In unique[]? Action unique[] After Step uniqueCount
0 1 No (empty) Add 1 1 1
1 2 No Add 2 1, 2 2
2 2 Yes (at index 1) Skip 1, 2 2
3 3 No Add 3 1, 2, 3 3
4 4 No Add 4 1, 2, 3, 4 4
5 4 Yes (at index 3) Skip 1, 2, 3, 4 4
6 5 No Add 5 1, 2, 3, 4, 5 5
7 1 Yes (at index 0) Skip 1, 2, 3, 4, 5 5
8 6 No Add 6 1, 2, 3, 4, 5, 6 6
9 5 Yes (at index 4) Skip 1, 2, 3, 4, 5, 6 6

Chapter 13: 2D Arrays (Multidimensional Arrays)

What are 2D Arrays?

A 2D array (two-dimensional array) is an array of arrays. Think of it as a table or matrix with rows and columns, like a spreadsheet or a tic-tac-toe board.

Visual Representation:

2D Array [3][4]:

           Col0   Col1  Col2  Col3

Row0   [10]   [20]   [30]   [40]

Row1   [50]   [60]   [70]   [80]

Row2   [90]  [100]  [110]  [120]

Real-world Examples:

  • Classroom seating: Rows and columns of desks.
  • Chess board: 8×8 grid.
  • Movie theater: Rows of seats.
  • Spreadsheet: Rows and columns of data.
  • mage pixels: Height × Width grid of colors.

2D Array Declaration and Initialization

Basic Syntax:

data_type array_name[rows][columns];

Different Initialization Methods:

Method Code Example
Declaration only int matrix[3][4];
Full initialization int matrix[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
Partial initialization int matrix[3][4] = {{1,2}, {5}}; // Rest are 0
Row-wise int matrix[ ][4] = {{1,2,3,4}, {5,6,7,8}};

Code Example 1: Basic 2D Array Operations

#include <stdio.h>

int main() {
    // Initialize a 3x4 matrix
    int matrix[3][4] = {
        {10, 20, 30, 40},
        {50, 60, 70, 80},
        {90, 100, 110, 120}
    };
    
    int rows = 3, cols = 4;
    int i, j;
    
    // Display the matrix
    printf("Matrix elements:\n");
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            printf("%4d ", matrix[i][j]);  // %4d for alignment
        }
        printf("\n");  // New line after each row
    }
    
    // Access specific elements
    printf("\nSpecific elements:\n");
    printf("matrix[0][0] = %d\n", matrix[0][0]);  // First element
    printf("matrix[1][2] = %d\n", matrix[1][2]);  // Second row, third column
    printf("matrix[2][3] = %d\n", matrix[2][3]);  // Last element
    
    return 0;
}

Output

10   20   30   40

50   60   70   80

90  100  110  120


Specific elements:

matrix[0] [0] = 10

matrix[1] [2] = 70

matrix[2] [3] = 120

Code Example 2: Input and Display Matrix

#include <stdio.h>

int main() {
    int matrix[3][12];
    int i, j;
    
    printf("Enter elements for a 3x3 matrix:\n");
    
    // Input matrix elements
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }
    
    // Display the matrix in proper format
    printf("\nMatrix you entered:\n");
    printf("-------------------\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%4d ", matrix[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

Output

Enter elements for a 3x3 matrix:

Enter element [0] [0]: 1

Enter element [0] [1]: 2

Enter element [0] [2]: 3

Enter element [1] [0]: 4

Enter element [1] [1]: 5

Enter element [1] [2]: 6

Enter element [2] [0]: 7

Enter element [2] [1]: 8

Enter element [2] [2]: 9


Matrix you entered:

-------------------

    1      2      3

    4      5      6

    7      8      9

Code Example 3: Student Grade Management System

#include <stdio.h>

int main() {
    // 4 students, 5 subjects each
    float grades[2][3];
    float studentTotal[2] = {0};
    float studentAverage[2];
    float subjectTotal[2] = {0};
    float subjectAverage[2];
    int students = 3, subjects = 2;
    int i, j;
    
    printf("Enter grades for 3 students (2 subjects each):\n");
    
    // Input grades
    for (i = 0; i < students; i++) {
        printf("\nStudent %d grades:\n", i + 1);
        for (j = 0; j < subjects; j++) {
            printf("Subject %d: ", j + 1);
            scanf("%f", &grades[i][j]);
        }
    }
    
    // Calculate totals and averages
    for (i = 0; i < students; i++) {
        for (j = 0; j < subjects; j++) {
            studentTotal[i] += grades[i][j];
            subjectTotal[j] += grades[i][j];
        }
        studentAverage[i] = studentTotal[i] / subjects;
    }
    
    for (j = 0; j < subjects; j++) {
        subjectAverage[j] = subjectTotal[j] / students;
    }
    
    // Display grade table
    printf("\n=== GRADE REPORT ===\n");
    printf("Student");
    for (j = 0; j < subjects; j++) {
        printf("  Sub%d", j + 1);
    }
    printf("  Total  Average\n");
    printf("-------------------------------\n");
    
    for (i = 0; i < students; i++) {
        printf("   %d   ", i + 1);
        for (j = 0; j < subjects; j++) {
            printf("%6.1f", grades[i][j]);
        }
        printf("%7.1f%8.2f\n", studentTotal[i], studentAverage[i]);
    }
    
    // Display subject averages
    printf("\nSubject Averages:\n");
    for (j = 0; j < subjects; j++) {
        printf("Subject %d: %.2f\n", j + 1, subjectAverage[j]);
    }
    
    return 0;
}

Line-by-Line Breakdown

Main Loop: Calculation Logic

// Calculate totals and averages
for (i = 0; i < students; i++) {
    for (j = 0; j < subjects; j++) {
        studentTotal[i] += grades[i][j];
        subjectTotal[j] += grades[i][j];
    }
    studentAverage[i] = studentTotal[i] / subjects;
}
for (j = 0; j < subjects; j++) {
    subjectAverage[j] = subjectTotal[j] / students;
}

Step 1: Assume Some Data

Suppose we have 3 students (students = 3) and 2 subjects (students = 2):

Subject
Student
Sub1 Sub2
Stu1 80 75
Stu2 60 85
Stu3 90 95

So, grades = { {80,75}, {60,85}, {90,95} }.

Initialize:

  • studentTotal = {0, 0, 0}
  • studentAverage = {00, 0, 0}
  • subjectTotal = {0, 0}
  • subjectAverage = {0, 0}

Step 2: The Outer Loop - per Student

Loop Index (i) Row (Student)
0 Student 1
1 Student 2
2 Student 3

Let's Trace Execution Step-by-Step

i = 0 (Student 1)

Inner loop (subjects):

  • j = 0 (Sub1):
  • studentTotal += grades; ⇒ 0+80=80

    subjectTotal += grades; ⇒ 0+80=80

  • j = 1 (Sub2):
  • studentTotal += grades; ⇒ 80+75=155

    subjectTotal += grades; ⇒ 0+75=75

    After both subjects:

  • studentTotal = 155
  • subjectTotal = 80, subjectTotal = 75
  • studentAverage = 155 / 2 = 77.5

i = 1 (Student 2)

  • j = 0 (Sub1):
  • studentTotal += grades; ⇒ 0+60=60

    subjectTotal += grades; ⇒ 80+60=140

  • j = 1 (Sub2):
  • studentTotal += grades; ⇒ 60+85=145

    subjectTotal += grades; ⇒ 75+85=160

    After both subjects:

  • studentTotal = 145
  • subjectTotal = 140, subjectTotal = 160
  • studentAverage = 145 / 2 = 72.5

i = 1 (Student 3)

  • j = 0 (Sub1):
  • studentTotal += grades; ⇒ 0+90=90

    subjectTotal += grades; ⇒ 140+90=230

  • j = 1 (Sub2):
  • studentTotal += grades; ⇒ 90+95=185

    subjectTotal += grades; ⇒ 160+95=255

    After both subjects:

  • studentTotal = 185
  • subjectTotal = 230, subjectTotal = 255
  • studentAverage = 185 / 2 = 92.5

Visual Step-through

Iteration         studentTotal         subjectTotal

-------------------------------------------------

Start               [0, 0]                     [0, 0, 0]

i=0, j=0          [10, 0]                   [10, 0, 0]

i=0, j=1          [30, 0]                   [10, 20, 0]

i=0, j=2          [60, 0]                   [10, 20, 30]

i=1, j=0          [60, 40]                 [50, 20, 30]

i=1, j=1          [60, 90]                 [50, 70, 30]

i=1, j=2          [60, 150]               [50, 70, 90]

Step 3: Subject Averages

for (j = 0; j < subjects; j++) {
    subjectAverage[j] = subjectTotal[j] / students;
}
  • subjectAverage = 230 / 376.67
  • subjectAverage = 255 / 385.00

Summary Table

Student Sub1 Sub2 Total Average
1 80 75 155 77.5
2 60 85 145 72.5
3 90 95 185 92.5
Subject Total Average
1 230 76.67
2 255 85.00

Output

Matrix Operations

Code Example 4: Matrix Addition

#include <stdio.h>

int main() {
    int matrixA[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int matrixB[3][3] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
    int result[3][3];
    int i, j;
    
    // Matrix addition
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            result[i][j] = matrixA[i][j] + matrixB[i][j];
        }
    }
    
    // Display matrices
    printf("Matrix A:\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%3d ", matrixA[i][j]);
        }
        printf("\n");
    }
    
    printf("\nMatrix B:\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%3d ", matrixB[i][j]);
        }
        printf("\n");
    }
    
    printf("\nA + B =\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%3d ", result[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

Output

Matrix A:

1    2    3

4    5    6

7    8    9


Matrix B:

9    8    7

6    5    4

3    2    1


A + B =

10    10    10

10    10    10

10    10    10

Code Example 5: Matrix Transpose

#include <stdio.h>

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    int transpose[4][3];  // Note: dimensions are swapped
    int i, j;
    
    // Calculate transpose
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            transpose[j][i] = matrix[i][j];
        }
    }
    
    // Display original matrix
    printf("Original Matrix (3x4):\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            printf("%3d ", matrix[i][j]);
        }
        printf("\n");
    }
    
    // Display transpose
    printf("\nTranspose Matrix (4x3):\n");
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            printf("%3d ", transpose[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

Output

Original Matrix (3x4):

1      2      3      4

5      6      7      8

9    10    11    12


Transpose Matrix (4x3):

1    5      9

2    6    10

3    7    11

4    8    12

Code Example 6: Tic-Tac-Toe Game (Mini-Project)

#include <stdio.h>

// Function declarations (prototypes) - tell compiler about functions before main()
void displayBoard(char board[3][3]);    // Function to display the game board
int checkWinner(char board[3][3]);      // Function to check if there's a winner
int isBoardFull(char board[3][3]);      // Function to check if board is full (not implemented)

int main() {
    // Initialize 3x3 game board with empty spaces
    // Each cell contains a space character ' ' representing an empty square
    char board[3][3] = {
        {' ', ' ', ' '},    // Row 0: all empty
        {' ', ' ', ' '},    // Row 1: all empty
        {' ', ' ', ' '}     // Row 2: all empty
    };
    
    // Game variables
    int row, col;               // Store player's move coordinates (0-2 for each)
    char currentPlayer = 'X';   // Track current player (starts with X)
    int gameWon = 0;           // Flag: 0 = no winner, 1 = someone won
    int moves = 0;             // Counter for total moves made (max 9 for tie)
    
    // Display game title and instructions
    printf("=== TIC-TAC-TOE GAME ===\n");
    printf("Players: X and O\n");
    printf("Enter row (0-2) and column (0-2)\n\n");
    
    // Main game loop - continues until someone wins OR board is full (9 moves)
    while (!gameWon && moves < 9) {
        
        // Show current state of the board
        displayBoard(board);
        
        // Prompt current player for their move
        printf("Player %c's turn\n", currentPlayer);
        printf("Enter row and column: ");
        scanf("%d %d", &row, &col);    // Read two integers from user
        
        // INPUT VALIDATION
        // Check if coordinates are within valid range (0-2 for both row and col)
        if (row < 0 || row > 2 || col < 0 || col > 2) {
            printf("Invalid position! Try again.\n");
            continue;    // Skip rest of loop, start over
        }
        
        // Check if chosen position is already occupied
        if (board[row][col] != ' ') {
            printf("Position already taken! Try again.\n");
            continue;    // Skip rest of loop, start over
        }
        
        // MAKE THE MOVE
        board[row][col] = currentPlayer;    // Place X or O in chosen position
        moves++;                           // Increment total move counter
        
        // CHECK FOR WINNER
        gameWon = checkWinner(board);      // Call function to check winning conditions
        if (gameWon) {
            displayBoard(board);           // Show final board state
            printf("Player %c wins!\n", currentPlayer);
            break;                         // Exit game loop immediately
        }
        
        // SWITCH PLAYERS
        // Ternary operator: if current is 'X' then switch to 'O', else switch to 'X'
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }
    
    // Check for tie game (no winner and all 9 positions filled)
    if (!gameWon && moves == 9) {
        displayBoard(board);
        printf("It's a tie!\n");
    }
    
    return 0;    // End program successfully
}

// FUNCTION: Display the current game board with grid lines and coordinates
void displayBoard(char board[3][3]) {
    int i, j;    // Loop counters for rows and columns
    
    // Print column headers (0, 1, 2)
    printf("\n   0   1   2\n");
    
    // Loop through each row
    for (i = 0; i < 3; i++) {
        printf("%d ", i);    // Print row number
        
        // Loop through each column in current row
        for (j = 0; j < 3; j++) {
            printf(" %c ", board[i][j]);    // Print cell content (X, O, or space)
            if (j < 2) printf("|");         // Add vertical separator between columns
        }
        printf("\n");    // New line after each row
        
        // Add horizontal separator line between rows (but not after last row)
        if (i < 2) printf("  -----------\n");
    }
    printf("\n");    // Extra blank line for spacing
}

// FUNCTION: Check all possible winning combinations
int checkWinner(char board[3][3]) {
    int i;    // Loop counter
    
    // CHECK ROWS - look for three in a row horizontally
    for (i = 0; i < 3; i++) {
        // Check if all three cells in row i contain same non-empty character
        if (board[i][0] != ' ' &&           // First cell not empty AND
            board[i][0] == board[i][1] &&   // First equals second AND
            board[i][1] == board[i][2]) {   // Second equals third
            return 1;    // Winner found!
        }
    }
    
    // CHECK COLUMNS - look for three in a row vertically
    for (i = 0; i < 3; i++) {
        // Check if all three cells in column i contain same non-empty character
        if (board[0][i] != ' ' &&           // Top cell not empty AND
            board[0][i] == board[1][i] &&   // Top equals middle AND
            board[1][i] == board[2][i]) {   // Middle equals bottom
            return 1;    // Winner found!
        }
    }
    
    // CHECK DIAGONAL 1 - top-left to bottom-right
    if (board[0][0] != ' ' &&               // Top-left not empty AND
        board[0][0] == board[1][1] &&       // Top-left equals center AND
        board[1][1] == board[2][2]) {       // Center equals bottom-right
        return 1;    // Winner found!
    }
    
    // CHECK DIAGONAL 2 - top-right to bottom-left
    if (board[0][2] != ' ' &&               // Top-right not empty AND
        board[0][2] == board[1][1] &&       // Top-right equals center AND
        board[1][1] == board[2][0]) {       // Center equals bottom-left
        return 1;    // Winner found!
    }
    
    return 0;    // No winner found
}

// NOTE: isBoardFull() function was declared but never implemented
// It would check if all 9 positions are filled (alternative way to detect ties)

Output

Memory Layout of 2D Arrays

How 2D Arrays are Stored:

int arr[3][4];

In memory, it's stored as a single block:

arr[0][0]  arr[0][1]  arr[0][2]  arr[0][3]

arr[1][0]  arr[1][1]  arr[1][2]  arr[1][3]

arr[2][0]  arr[2][1]  arr[2][2]  arr[2][3]

Row-major order: Elements are stored row by row.

2D Arrays with Functions

#include <stdio.h>

// FUNCTION: Display a matrix with proper formatting
// Parameters: matrix - 2D array with fixed 4 columns, rows - number of rows to display
// Note: In C, when passing 2D arrays to functions, all dimensions except the first must be specified
void displayMatrix(int matrix[][4], int rows) {  // Column size (4) must be specified
    int i, j;    // Loop counters for rows and columns
    
    // Outer loop: iterate through each row
    for (i = 0; i < rows; i++) {
        // Inner loop: iterate through each column in current row
        for (j = 0; j < 4; j++) {
            // Print each element with 4-character width for proper alignment
            // %4d ensures each number takes exactly 4 spaces (right-aligned)
            printf("%4d ", matrix[i][j]);
        }
        printf("\n");    // Move to next line after printing all columns in a row
    }
}

// FUNCTION: Calculate the sum of all elements in the matrix
// Parameters: matrix - 2D array with fixed 4 columns, rows - number of rows to process
// Returns: integer sum of all matrix elements
int matrixSum(int matrix[][4], int rows) {
    int sum = 0;     // Initialize sum accumulator to zero
    int i, j;        // Loop counters for rows and columns
    
    // Outer loop: iterate through each row
    for (i = 0; i < rows; i++) {
        // Inner loop: iterate through each column in current row
        for (j = 0; j < 4; j++) {
            // Add current element to running sum
            sum += matrix[i][j];    // Equivalent to: sum = sum + matrix[i][j]
        }
    }
    return sum;    // Return the total sum to calling function
}

int main() {
    // MATRIX INITIALIZATION
    // Declare and initialize a 3x4 matrix (3 rows, 4 columns)
    // Each row is initialized with specific values in curly braces
    int matrix[3][4] = {
        {1, 2, 3, 4},      // Row 0: elements 1, 2, 3, 4
        {5, 6, 7, 8},      // Row 1: elements 5, 6, 7, 8
        {9, 10, 11, 12}    // Row 2: elements 9, 10, 11, 12
    };
    
    // FUNCTION CALLS
    // Display the matrix in formatted output
    // Pass matrix name (which becomes a pointer) and number of rows (3)
    displayMatrix(matrix, 3);
    
    // Calculate and display the sum of all matrix elements
    // matrixSum() returns an integer which is directly used in printf()
    printf("Sum of all elements: %d\n", matrixSum(matrix, 3));
    
    return 0;    // Indicate successful program termination
}

Output

  1      2      3      4

  5      6      7      8

  9    10    11    12

  Sum of all elements: 78

Practice Exercises

Exercise 1: Write a program to multiply two 2×2 matrices.

Exercise 2: Create a program that finds the largest and smallest elements in a 2D array along with their positions.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    // VARIABLE DECLARATIONS
    // Declare three 2x2 matrices: two input matrices and one result matrix
    int matrixA[2][2];      // First input matrix (2 rows, 2 columns)
    int matrixB[2][2];      // Second input matrix (2 rows, 2 columns)
    int result[2][2];       // Result matrix to store A × B
    
    // Loop counters: i for rows, j for columns, k for matrix multiplication inner loop
    int i, j, k;
    
    // INPUT SECTION: Get elements for first matrix
    printf("Enter elements for first 2x2 matrix:\n");
    
    // Nested loop to read elements for matrix A
    for (i = 0; i < 2; i++) {           // Loop through rows (0 to 1)
        for (j = 0; j < 2; j++) {       // Loop through columns (0 to 1)
            // Prompt user with specific position (row, column)
            printf("A[%d][%d]: ", i, j);
            // Read integer and store in matrix A at position [i][j]
            scanf("%d", &matrixA[i][j]);
        }
    }
    
    // INPUT SECTION: Get elements for second matrix
    printf("\nEnter elements for second 2x2 matrix:\n");
    
    // Nested loop to read elements for matrix B
    for (i = 0; i < 2; i++) {           // Loop through rows (0 to 1)
        for (j = 0; j < 2; j++) {       // Loop through columns (0 to 1)
            // Prompt user with specific position (row, column)
            printf("B[%d][%d]: ", i, j);
            // Read integer and store in matrix B at position [i][j]
            scanf("%d", &matrixB[i][j]);
        }
    }
    
    // MATRIX MULTIPLICATION ALGORITHM
    // Formula: C[i][j] = Σ(A[i][k] × B[k][j]) for k = 0 to n-1
    for (i = 0; i < 2; i++) {           // Loop through rows of result matrix
        for (j = 0; j < 2; j++) {       // Loop through columns of result matrix
            // Initialize current result cell to zero before accumulation
            result[i][j] = 0;
            
            // Inner loop for dot product calculation
            // Multiply corresponding elements and sum them up
            for (k = 0; k < 2; k++) {
                // Add product of A[i][k] and B[k][j] to running sum
                // This implements: result[i][j] = A[i][0]*B[0][j] + A[i][1]*B[1][j]
                result[i][j] += matrixA[i][k] * matrixB[k][j];
            }
        }
    }
    
    // OUTPUT SECTION: Display all matrices with proper formatting
    
    // Display Matrix A
    printf("\nMatrix A:\n");
    for (i = 0; i < 2; i++) {           // Loop through rows
        for (j = 0; j < 2; j++) {       // Loop through columns
            // Print each element with 4-character width for alignment
            printf("%4d ", matrixA[i][j]);
        }
        printf("\n");                   // New line after each row
    }
    
    // Display Matrix B
    printf("\nMatrix B:\n");
    for (i = 0; i < 2; i++) {           // Loop through rows
        for (j = 0; j < 2; j++) {       // Loop through columns
            // Print each element with 4-character width for alignment
            printf("%4d ", matrixB[i][j]);
        }
        printf("\n");                   // New line after each row
    }
    
    // Display Result Matrix (A × B)
    printf("\nA × B =\n");
    for (i = 0; i < 2; i++) {           // Loop through rows
        for (j = 0; j < 2; j++) {       // Loop through columns
            // Print each result element with 4-character width for alignment
            printf("%4d ", result[i][j]);
        }
        printf("\n");                   // New line after each row
    }
    
    return 0;    // Indicate successful program termination
}

Summary Table of Steps

i j k=0 (A[i]*B[j]) k=1 (A[i]*B[j]) Final result[i][j]
0 0 1 × 5 = 5 2 × 7 = 14 5 + 14 = 19
0 1 1 × 6 = 6 2 × 8 = 16 6 + 16 = 22
1 0 3 × 5 = 15 4 × 7 = 28 15 + 28 = 43
1 1 3 × 6 = 18 4 × 8 = 32 18 + 32 = 50

Output

Enter a element for first 2x2 matrix:

A[0][0]: 1

A[0][1]: 2

A[1][0]: 3

A[1][1]: 4

Enter a element for second 2x2 matrix:

B[0][0]: 5

B[0][1]: 6

B[1][0]: 7

B[1][1]: 8


Matrix A:

1      2

3      4


Matrix b:

5      6

7      8


A X B:

15    17

19    21

Answer 2:

#include <stdio.h>

int main() {
    // MATRIX DECLARATION AND INITIALIZATION
    // Declare and initialize a 3x4 matrix (3 rows, 4 columns) with predefined values
    int matrix[3][4] = {
        {45, 23, 78, 12},    // Row 0: contains values 45, 23, 78, 12
        {89, 34, 56, 67},    // Row 1: contains values 89, 34, 56, 67
        {15, 91, 38, 52}     // Row 2: contains values 15, 91, 38, 52
    };
    
    // VARIABLE DECLARATIONS
    int rows = 3, cols = 4;     // Matrix dimensions (3 rows, 4 columns)
    int i, j;                   // Loop counters for rows and columns
    
    // Variables to store maximum and minimum values
    int max, min;               // Store the actual maximum and minimum values
    
    // Variables to store positions of maximum and minimum elements
    int maxRow, maxCol;         // Row and column indices of maximum element
    int minRow, minCol;         // Row and column indices of minimum element
    
    // INITIALIZATION PHASE
    // Initialize max and min with first element of matrix
    // This gives us a starting point for comparison
    max = min = matrix[0][0];   // Both max and min start with matrix[0][0] value
    
    // Initialize position variables to point to first element [0][0]
    maxRow = maxCol = minRow = minCol = 0;
    
    // SEARCH ALGORITHM: Find maximum and minimum elements
    // Use nested loops to traverse entire matrix
    for (i = 0; i < rows; i++) {        // Outer loop: iterate through each row
        for (j = 0; j < cols; j++) {    // Inner loop: iterate through each column
            
            // CHECK FOR NEW MAXIMUM
            // If current element is greater than current max, update max and its position
            if (matrix[i][j] > max) {
                max = matrix[i][j];     // Update maximum value
                maxRow = i;             // Update row position of maximum
                maxCol = j;             // Update column position of maximum
            }
            
            // CHECK FOR NEW MINIMUM  
            // If current element is smaller than current min, update min and its position
            if (matrix[i][j] < min) {
                min = matrix[i][j];     // Update minimum value
                minRow = i;             // Update row position of minimum
                minCol = j;             // Update column position of minimum
            }
        }
    }
    
    // OUTPUT SECTION: Display results
    
    // Display the entire matrix in formatted layout
    printf("Matrix:\n");
    for (i = 0; i < rows; i++) {        // Loop through each row
        for (j = 0; j < cols; j++) {    // Loop through each column in current row
            // Print each element with 4-character width for proper alignment
            printf("%4d ", matrix[i][j]);
        }
        printf("\n");                   // Move to next line after completing a row
    }
    
    // Display maximum element and its position
    // Format: value at position [row][column]
    printf("\nLargest element: %d at position [%d][%d]\n", 
           max, maxRow, maxCol);
    
    // Display minimum element and its position  
    // Format: value at position [row][column]
    printf("Smallest element: %d at position [%d][%d]\n", 
           min, minRow, minCol);
    
    return 0;    // Indicate successful program termination
}

Output

Matrix:

45    23    78    12

89    34    56    67

15    91    38    52


Largest element: 91 at position [2] [1]

Smallest element: 12 at position [0] [3]

Chapter 14: Strings

What are Strings?

A string is a sequence of characters (letters, digits, symbols) stored as an array of characters. In C, strings are null-terminated, meaning they end with a special character \0 (null character).

String vs Character:

  • Character: Single letter like 'A' (uses single quotes)
  • String: Sequence of characters like "Hello" (uses double quotes)

Real-world Examples:

  • Names: “John Smith”
  • Addresses: “123 Main Street”
  • Messages: “Welcome to C Programming!”
  • Passwords: “MyPassword123”

String Declaration and Initialization

Method 1: Character Array

char name[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

Method 2: String Literal (Most Common)

char name[] = "Hello"; // Size automatically calculated
char name[10] = "Hello"; // Size specified (allows for longer strings later)

Memory Layout:

String: "Hello"

Memory: [H] [e] [l] [l] [o] [\0]

Index:       0   1   2   3  4    5

Code Example 1: Basic String Operations

#include <stdio.h>
#include <string.h>

int main() {
    // Different ways to declare strings
    char greeting[] = "Hello World!";
    char name[50] = "Alice";
    char message[100];
    
    printf("Greeting: %s\n", greeting);
    printf("Name: %s\n", name);
    
    // Get string length
    printf("Length of greeting: %lu\n", strlen(greeting));
    printf("Length of name: %lu\n", strlen(name));
    
    // Copy strings
    strcpy(message, "Welcome to C Programming!");
    printf("Message: %s\n", message);
    
    // String concatenation
    strcat(name, " Johnson");
    printf("Full name: %s\n", name);
    
    return 0;
}

Output

Greeting: Hello World!

Name: Alice

Length of greeting: 12

Length of name: 5

Message: Welcome to C Programming!

Full name: Alice Johnson

String Input and Output

Code Example 2: Different Ways to Input Strings

#include <stdio.h>

int main() {
    char name[50];
    char city[50];
    char address[100];

    // Method 1: scanf() - stops at space
    printf("Enter your first name: ");
    scanf("%s", name); // No & needed for strings

    // Clear input buffer
    while (getchar() != '\n');

    // Method 2: gets() - reads entire line (including spaces)
    printf("Enter your city: ");
    gets(city);

    // Method 3: fgets() - safer than gets()
    printf("Enter your address: ");
    fgets(address, sizeof(address), stdin);

    printf("\n=== Your Information ===\n");
    printf("Name: %s\n", name);
    printf("City: %s\n", city);
    printf("Address: %s", address); // fgets includes \n

    return 0;
}

Output

Enter your first name: John

Enter your city: New York

Enter your address: 123 Main Street


=== Your Information ===

Name: John

City: New York

Address: 123 Main Street

Method Stops at Space? Safe? Includes Newline?
scanf("%s", str) Yes No - no buffer protection No
gets(str) No Dangerous - no buffer check No
fgets(str, size, stdin) No Safe - buffer protected Yes

A buffer is a temporary area in memory for holding data, used to make your C program's input and output faster and smoother.A buffer is a temporary storage area in computer memory that holds data while it is being moved from one place to another.

Essential String Functions

Code Example 3: String Functions Demo

#include <stdio.h>
#include <string.h>

int main() {
    // STRING VARIABLE DECLARATIONS
    char str1[50] = "Hello";   // String initialized with "Hello"
    char str2[50] = "World";   // String initialized with "World"
    char str3[50];             // Empty string for copy operations
    char str4[50] = "hello";   // String with lowercase "hello" (to show comparison)

    printf("=== STRING FUNCTIONS DEMO ===\n");

    // 1. strlen() - Find the length of a string
    // %lu format specifier for unsigned long returned by strlen()
    printf("strlen(\"%s\") = %lu\n", str1, strlen(str1));
    // Output: strlen("Hello") = 5

    // 2. strcpy() - Copy str1 into str3
    strcpy(str3, str1);  // str3 now contains "Hello"
    printf("After strcpy(str3, str1): str3 = \"%s\"\n", str3);

    // 3. strcat() - Concatenate (append) str2 to str1
    strcat(str1, str2);  // str1 becomes "HelloWorld"
    printf("After strcat(str1, str2): str1 = \"%s\"\n", str1);

    // Reset str1 for further operations (otherwise it remains "HelloWorld")
    strcpy(str1, "Hello");

    // 4. strcmp() - Compare two strings (case-sensitive)
    // Returns: 0 if equal, <0 if first < second, >0 if first > second (ASCII order)
    printf("strcmp(\"%s\", \"%s\") = %d\n", str1, str2, strcmp(str1, str2));  // "Hello" vs "World"
    printf("strcmp(\"%s\", \"%s\") = %d\n", str1, str1, strcmp(str1, str1));  // "Hello" vs "Hello"
    printf("strcmp(\"%s\", \"%s\") = %d\n", str1, str4, strcmp(str1, str4));  // "Hello" vs "hello" (case sensitive)

    // 5. strchr() - Find first occurrence of character in a string
    // Returns pointer to the character if found, else NULL
    char *pos = strchr(str1, 'e');  // Looks for 'e' in "Hello"
    if (pos != NULL) {
        // To get character position as index: subtract start address of str1
        printf("Character 'e' found at position: %ld\n", pos - str1);
    }

    // 6. strstr() - Find substring within another string
    // Returns pointer to first occurrence, else NULL
    char sentence[] = "C programming is fun";
    char *found = strstr(sentence, "program");
    if (found != NULL) {
        printf("\"program\" found in: \"%s\"\n", sentence);
    }

    return 0;  // Indicate successful execution
}


Output

=== STRING FUNCTIONS DEMO ===

strlen("Hello") = 5

After strcpy(str3, str1): str3 = "Hello"

After strcat(str1, str2): str1 = "HelloWorld"

strcmp("Hello", "World") = -15

strcmp("Hello", "Hello") = 0

strcmp("Hello", "hello") = -32

Character 'e' found at position: 1

"program" found in: "C programming is fun"

String Functions Reference:

Function Purpose Return Value Example
strlen(str) Get string length Number of characters strlen("Hello") $\to 5$
strcpy(dest, src) Copy string Destination string strcpy(a, "Hi")
strcat(dest, src) Concatenate strings Destination string strcat(a, "World") )
strcmp(str1, str2) Compare strings $0=$ equal, $<0=$ str1 $<$ str2, $>0=$ str1 $>$ str2 strcmp("A", "B") $\to$ negative
strchr(str, ch) Find character Pointer to character or NULL strchr("Hello", 'e')
strstr(str, substr) Find substring Pointer to substring or NULL strstr("Hello", "ll")

Code Example 4: String Processing Program

#include <stdio.h>
#include <string.h>
#include <ctype.h>  // For character functions

int main() {
    char text[200];
    int length, i;
    int vowels = 0, consonants = 0, digits = 0, spaces = 0, others = 0;
    
    printf("Enter a sentence: ");
    fgets(text, sizeof(text), stdin);
    
    // Remove newline from fgets
    text[strcspn(text, "\n")] = 0;
    
    length = strlen(text);
    
    // Analyze each character
    for (i = 0; i < length; i++) {
        char ch = tolower(text[i]);  // Convert to lowercase
        
        if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
            vowels++;
        } else if (ch >= 'a' && ch <= 'z') {
            consonants++;
        } else if (ch >= '0' && ch <= '9') {
            digits++;
        } else if (ch == ' ') {
            spaces++;
        } else {
            others++;
        }
    }
    
    // Display results
    printf("\n=== TEXT ANALYSIS ===\n");
    printf("Original text: \"%s\"\n", text);
    printf("Total characters: %d\n", length);
    printf("Vowels: %d\n", vowels);
    printf("Consonants: %d\n", consonants);
    printf("Digits: %d\n", digits);
    printf("Spaces: %d\n", spaces);
    printf("Other characters: %d\n", others);
    
    return 0;
}

Output

Enter a sentence: Hello World! I have 5 cats.


=== TEXT ANALYSIS ===

Original text: "Hello World! I have 5 cats."

Total characters: 28

Vowels: 8

Consonants: 13

Digits: 1

Spaces: 5

Other characters: 1

Code Example 5: String Manipulation Functions

#include <stdio.h>
#include <string.h>
#include <ctype.h>  // For character functions

// REVERSE the string in place (e.g., "Hello" -> "olleH")
void reverseString(char str[]) {
    int len = strlen(str);      // Get length of the string (not counting '\0')
    int i;
    // Swap characters from ends moving toward center (only up to the halfway point)
    for (i = 0; i < len / 2; i++) {
        char temp = str[i];                 // Temporary hold left character
        str[i] = str[len - 1 - i];          // Move right character to left
        str[len - 1 - i] = temp;            // Move left character to right
    }
}

// Convert all string characters to UPPERCASE (in place)
void toUpperCase(char str[]) {
    int i;
    // Step through each character until end of string ('\0')
    for (i = 0; str[i] != '\0'; i++)
        str[i] = toupper(str[i]);           // Convert to uppercase using ctype.h
}

// Convert all string characters to LOWERCASE (in place)
void toLowerCase(char str[]) {
    int i;
    // Step through each character
    for (i = 0; str[i] != '\0'; i++)
        str[i] = tolower(str[i]);           // Convert to lowercase
}

// Count the number of WORDS in a string (words separated by whitespace)
int countWords(char str[]) {
    int count = 0, inWord = 0, i;
    // Loop through each character of the string
    for (i = 0; str[i] != '\0'; i++) {
        // If character is NOT a space, tab, or newline, we're inside a word
        if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n') {
            if (!inWord) {      // If we weren't in a word before, new word starts here
                count++;        // Increment word count
                inWord = 1;     // Now we are inside a word
            }
        } else {
            inWord = 0;         // We hit space/tab/newline, so we're outside a word
        }
    }
    return count;
}

int main() {
    char original[] = "Hello";          // Original string to manipulate
    char copy1[50], copy2[50], copy3[50];  // Copies (large size for safety)

    strcpy(copy1, original);    // Make a copy for reversal
    strcpy(copy2, original);    // Make a copy for uppercase conversion
    strcpy(copy3, original);    // Make a copy for lowercase conversion

    printf("Original string: \"%s\"\n", original);
    printf("Word count: %d\n", countWords(original));    // Count how many words

    // Reverse and print
    reverseString(copy1);
    printf("Reversed: \"%s\"\n", copy1);

    // Convert to uppercase and print
    toUpperCase(copy2);
    printf("Uppercase: \"%s\"\n", copy2);

    // Convert to lowercase and print
    toLowerCase(copy3);
    printf("Lowercase: \"%s\"\n", copy3);

    return 0;           // End program
}


Output

Original string: "Hello World Programming"

Word count: 3

Reversed: "gnimmargorP dlroW olleH"

Uppercase: "HELLO WORLD PROGRAMMING"

Lowercase: "hello world programming"

Function What It Does Example Input Example Output
reverseString Reverses the string "Dog" "goD"
toUpperCase All letters become uppercase "Hi There" "HI THERE"
toLowerCase All letters become lowercase "Hi There" "hi there"
countWords Returns number of words "C is fun!\nYes" 4

Arrays of Strings

You can create arrays to store multiple strings:

Code Example 6: Student Names Management

#include <stdio.h>
#include <string.h>

int main() {
    // Declare a 2D char array to store up to 5 student names, each up to 29 characters (+1 for '\0')
    char students[5][30];
    int numStudents = 0;      // Tracks the number of students currently in the list
    int choice;               // For user menu selection
    int i;                    // General-purpose loop index
    char searchName[30];      // Buffer to store name being searched
    int found;                // Flag to indicate if search result is found

    do {
        // Display menu
        printf("\n=== STUDENT NAME MANAGER ===\n");
        printf("1. Add Student\n");
        printf("2. Display All Students\n");
        printf("3. Search Student\n");
        printf("4. Exit\n");
        printf("Choice: ");
        scanf("%d", &choice);

        switch (choice) {
            // Add new student name
            case 1:
                if (numStudents < 5) { // Prevent array overflow
                    printf("Enter student name: ");
                    // Reads a word (no spaces) into next empty slot
                    scanf("%s", students[numStudents]);
                    numStudents++;    // Increment student count
                    printf("Student added successfully!\n");
                } else {
                    printf("Maximum students reached!\n");
                }
                break;

            // Display all saved student names
            case 2:
                if (numStudents == 0) {
                    printf("No students found!\n");
                } else {
                    printf("\nList of Students:\n");
                    // Loop through each name and print it
                    for (i = 0; i < numStudents; i++) {
                        printf("%d. %s\n", i + 1, students[i]);
                    }
                }
                break;

            // Search for a student by name
            case 3:
                printf("Enter name to search: ");
                scanf("%s", searchName);
                found = 0; // Assume not found
                // Loop and compare each saved name to target
                for (i = 0; i < numStudents; i++) {
                    // strcmp returns 0 if strings match exactly
                    if (strcmp(students[i], searchName) == 0) {
                        printf("Student '%s' found at position %d\n", 
                               searchName, i + 1);
                        found = 1; // Mark as found
                        break;     // No need to continue searching
                    }
                }
                if (!found) {
                    printf("Student '%s' not found!\n", searchName);
                }
                break;

            // Exit the loop/program
            case 4:
                printf("Goodbye!\n");
                break;

            // Handle invalid choices
            default:
                printf("Invalid choice!\n");
        }
    } while (choice != 4); // Repeat until the user chooses to exit

    return 0; // End the program successfully
}


Output

Common String Problems and Solutions

Problem 1: Check if String is Palindrome

A palindrome is a word (or number, or phrase) that is spelled the same forwards and backwards. Examples: madam, level, RaceCar, noon

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// Function to check if a string is a palindrome (case-insensitive)
int isPalindrome(char str[]) {
    int len = strlen(str);     // Get length of the string
    int i;                    // Loop counter

    // Compare characters from start and end moving inwards
    for (i = 0; i < len / 2; i++) {
        // Convert both characters to lowercase and compare
        // If any pair doesn't match, it's not a palindrome
        if (tolower(str[i]) != tolower(str[len - 1 - i])) {
            return 0;         // Not a palindrome
        }
    }
    return 1;                 // All pairs matched: it's a palindrome
}

int main() {
    char word[100];           // Buffer to store user input (up to 99 characters + null terminator)

    printf("Enter a word: ");
    scanf("%s", word);        // Read a single word (no spaces) from user

    // Call isPalindrome to check, and display message accordingly
    if (isPalindrome(word)) {
        printf("'%s' is a palindrome!\n", word);
    } else {
        printf("'%s' is not a palindrome.\n", word);
    }

    return 0;                 // Return 0 to indicate success
}

Output

Enter a word: racecar

'racecar' is a palindrome!


Enter a word: hello

'hello' is not a palindrome.

Problem 2: Count Character Frequency

#include <stdio.h>
#include <string.h>

int main() {
    // Declare a character array to store the user input text (maximum 99 characters + 1 for '\0')
    char text[100];

    // Declare and initialize an array to store frequency of each character (ASCII 0 to 255)
    // All elements start at 0
    int frequency[256] = {0};

    int i; // Loop counter

    // Prompt the user to enter a string
    printf("Enter text: ");

    // Read a line of text (up to 99 characters) from standard input
    // fgets includes whitespace and stops at newline or buffer full
    fgets(text, sizeof(text), stdin);

    // Loop through each character of the input string
    for (i = 0; text[i] != '\0'; i++) {
        // Increment the frequency for the ASCII value of current character
        frequency[(int)text[i]]++;
    }

    // Display the character frequencies (ignoring the newline character)
    printf("\nCharacter frequencies:\n");

    // Loop through all ASCII values
    for (i = 0; i < 256; i++) {
        // Only print characters that occurred at least once AND are not the newline
        if (frequency[i] > 0 && i != '\n') { // '\n' has ASCII value 10
            printf("'%c': %d\n", i, frequency[i]);
        }
    }

    return 0; // Program ended successfully
}

Output

Enter text: hello world


Character frequencies:

' ': 1

'd': 1

'e': 1

'h': 1

'l': 3

'o': 2

'r': 1

'w': 1

Practice Exercises

Exercise 1: Write a program that reads a sentence and converts the first letter of each word to uppercase and the rest to lowercase (Title Case).

Exercise 2: Create a program that removes all spaces from a string and displays the result.

Answers:

Answer 1:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main() {
    char sentence[200];
    int i;
    int newWord = 1;  // Flag to indicate start of new word
    
    printf("Enter a sentence: ");
    fgets(sentence, sizeof(sentence), stdin);
    
    for (i = 0; sentence[i] != '\0'; i++) {
        if (sentence[i] == ' ' || sentence[i] == '\t' || sentence[i] == '\n') {
            newWord = 1;  // Next non-space character starts a new word
        } else if (newWord) {
            sentence[i] = toupper(sentence[i]);  // First letter uppercase
            newWord = 0;
        } else {
            sentence[i] = tolower(sentence[i]);  // Rest lowercase
        }
    }
    
    printf("Title case: %s", sentence);
    
    return 0;
}

Output

Enter a sentence: welcome to c programming

Title case: Welcome To C Programming:

Answer 2:

#include <stdio.h>
#include <string.h>

int main() {
    char original[100];
    char noSpaces[100];
    int i, j = 0;
    
    printf("Enter a string: ");
    fgets(original, sizeof(original), stdin);
    
    // Remove newline from fgets
    original[strcspn(original, "\n")] = 0;
    
    // Copy non-space characters
    for (i = 0; original[i] != '\0'; i++) {
        if (original[i] != ' ') {
            noSpaces[j] = original[i];
            j++;
        }
    }
    noSpaces[j] = '\0';  // Null terminate
    
    printf("Original: \"%s\"\n", original);
    printf("No spaces: \"%s\"\n", noSpaces);
    printf("Removed %lu spaces\n", strlen(original) - strlen(noSpaces));
    
    return 0;
}

Output

Enter a string: hello world

Original: "hello world"

No spaces: "helloworld"

Removed 1 spaces

Chapter 15: Pointer

What are Pointers?

A pointer is a variable that stores the memory address of another variable.

Why Use Pointers?

  • Directly access memory.
  • Improve performance and memory management.
  • Required for arrays, strings, and advanced function topics.
int a = 5;
int *ptr; // Declaration
ptr = &a; // Store address of a in ptr

Code Meaning
int *ptr; Declares a pointer to an integer called ptr.
ptr = &a; Assigns the memory address of the variable a to the pointer ptr.
*ptr Refers to the value at the memory address stored in ptr (dereferencing).

Code Example 1: Printing Pointer Address and Value

#include <stdio.h>

    int main() {
    int num = 10;
    int *p;
    p = #
    printf("Value of num: %d\\n", num);
    printf("Address of num: %p\\n", &num);
    printf("Pointer p stores address: %p\\n", p);
    printf("Value at address p: %d\\n", *p);
    return 0;
    }

Output

Value of num: 10

Address of num: 000000D14A9FFD74

Pointer p stores address: 000000D14A9FFD74

Value at address p: 10

Line-by-line Table:

Line of Code Purpose
int num = 10; Creates an integer variable named num and initializes it with the value 10.
int *p; Declares a pointer variable named p that can hold the memory address of an integer.
p = &num; Assigns the memory address of the num variable to the pointer p.
*p Accesses the value stored at the memory address held by the pointer p (this is called dereferencing the pointer).

Code Example 2: Changing Value with Pointers

#include <stdio.h>

int main() {
    int x = 25;
    int *px = &x;
    *px = 50; // Changes value of x through pointer

    printf("x = %d\\n", x);       // 50
    printf("*px = %d\\n", *px);   // 50
    return 0;
}

Output

x = 50

*px = 50

Code Example 3: Pointer Arithmetic

#include <stdio.h>

    int main() {
    int arr[3] = {10, 20, 30};
    int *ptr = arr;

    printf("%d\\n", *ptr); // 10
    ptr++; // Moves to next int in array
    printf("%d\\n", *ptr); // 20
    return 0;
    }

Output

10

20

  • ptr++: Advances pointer to next array element (for int, +4 bytes).

In C, when assigning a pointer to an array like int *ptr = arr; , the & (address-of) operator is not needed because the array name arr automatically represents the address of its first element. This means arr is equivalent to &arr in this context, making both int *ptr = arr; and int *ptr = &arr; valid and functionally identical for one-dimensional arrays.

Practice Exercises

Exercise 1: Declare an integer variable, create a pointer, assign the address, and print the value using the pointer.

Exercise 2: Write a program that uses a pointer to change the value of a float variable to 99.99.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    int n = 100;
    int *p = &n;
    printf("Value: %d\n", *p);
    return 0;
    }

Output

Value: 100

Answer 2:

#include <stdio.h>

int main() {
    float f = 12.34;
    float *pf = &f;
    *pf = 99.99;
    printf("%.2f\n", f);
    return 0;
}

Output

Value: 99.99

Chapter 16: Structures & Unions

What is a Structure (struct)?

A structure is a user-defined data type that groups related variables of different types. Each variable in the structure is known as a member of the structure.

Why Use Structures?

  • Organize related data (e.g., student: name, age, marks).
  • Each member can be different type.

Defining and Using Structures

struct Student {
    char name[50];
    int age;
    float marks;
};
Syntax Meaning
struct Student { ... } Defines a new structure type named Student.
. Used to access a field (or member) within a structure variable (e.g., s1.age).

Code Example 1: Declaring and Accessing a Structure

#include <stdio.h>

// Define a structure called "Student" 
// This creates a new user-defined data type
struct Student {
    char name[20];  
    int age;          
    float marks;      
};

int main() {
    // Create and initialize a structure variable 's1' of type 'Student'
    // This uses aggregate initialization with curly braces
    struct Student s1 = {"John", 18, 92.5};
    
    // Access and print the name member using dot notation
    printf("Name: %s\n", s1.name);
    
    // Access and print the age member using dot notation
     printf("Age: %d\n", s1.age);
    
    // Access and print the marks member using dot notation
    printf("Marks: %.2f\n", s1.marks);
    
    return 0;    // Indicates successful program execution
}

Output

Name: John

Age: 18

Marks: 92.50

Code Example 2: Array of Structures

#include <stdio.h>

struct Point {
    int x;
    int y;
};
int main() {
    struct Point points[2] = {{1,2}, {3,4}};
    for(int i = 0; i < 2; i++) {
        printf("(%d, %d)\\n", points[i].x, points[i].y);
    }
    return 0;
}

Step 1: Array Declaration and Initialization

struct Point points[9] = {{1,2}, {3,4}};

  • Memory is allocated for an array of 2 Point structures.
  • points is initialized with x=1, y=2.
  • points is initialized with x=3, y=4.
  • The nested braces {{1,2}, {3,4}} represent each structure's member values.

Step 2: First Loop Iteration (i=0)

printf("(%d, %d)\n", points[i].x, points[i].y);

  • points.x accesses the x member of first structure (value: 1)
  • points.y accesses the y member of first structure (value: 2).
  • Prints: (1, 2) followed by newline.

Step 3: Second Loop Iteration (i=1)

  • points.x accesses the x member of second structure (value: 3)
  • points.y accesses the y member of second structure (value: 4).
  • Prints: (3, 4) followed by newline.

Execution Table

Step i points[i].x points[i].y Printed Output
1 0 1 2 (1, 2)
2 1 3 4 (3, 4)

Output

(1, 2)

(3, 4)

Step 3: Nested Structures

#include <stdio.h>
    
struct Date {
    int day, month, year;
};
struct Student {
    char name[10];
    struct Date dob;
};

int main() {
    struct Student s = {"Jane", {15, 8, 2005}};
    printf("%s: %d/%d/%d\\n", s.name, s.dob.day, s.dob.month, s.dob.year);
    return 0;
}

Step-by-Step Logic

  • Step 1: struct Date is defined with three integer fields (day, month, year) to represent a date (like a birthday).
  • Step 2: struct Student is defined to represent a student's record.
    • It contains a character array name.
    • Most importantly, it has a member dob of type struct Date.
  • Step 3: When a variable of type struct Student is created, it will contain both the student's name and their date of birth grouped together in one structure.
  • Step 4: Access to nested members is done using two dots: studentVar.dob.day, studentVar.dob.month, studentVar.dob.year.

Output

Jane: 15/8/2005

What is a Union?

A union is like a structure but members share the same memory location. Only one member can be used at a time.

union Number {
    int i;
    float f;
};

Code Example 4: Accessing Union Members

#include <stdio.h>
union Data {
    int i;
    float f;
    char c;
};
int main() {
    union Data d;
    d.i = 25;
    printf("%d\\n", d.i);
    d.f = 45.5;
    printf("%.2f\\n", d.f);
    d.c = 'A';
    printf("%c\\n", d.c);
    return 0;
}

Output

25

45.50

A

(Only the last assigned value is reliable; previous is overwritten.)

How Union Works

Memory Sharing

  • All members (i, f, c) share the same memory location.
  • The union's size equals the size of its largest member (in this case, int or float, both typically 4 bytes).
  • When a new value is assigned to any member, it overwrites the previous data.

Step-by-Step Execution

Step Assignment Action Output
1 d.i = 25 Stores integer 25 in memory. 25
2 d.i = 45.50 Overwrites previous data with float 45.5. 45.50
3 d.i = 'A' Overwrites previous data with character 'A'. A

Key Characteristics

Memory Efficiency

  • Unlike structures where each member has separate memory, unions save memory by sharing the same location.
  • Only one member can store data at a time.

Use Cases

  • Memory-constrained environments where space is critical.
  • Type conversion scenarios where you need to interpret data differently.
  • Embedded systems programming where memory optimization is essential.

Structure vs Union Table

Aspect Structure Union
Memory Individual for each member Shared for all members
Usable fields All at once Only one at a time
Size Sum of all members Size of largest member

Practice Exercises

Exercise 1: Write a C program to define a structure Book with fields: title, author, price. Create a variable and print its info.

Exercise 2: Create a union Number with members int i, float f. Assign and print both, and observe the output.

Answers:

Answer 1:

#include <stdio.h>

struct Book {
    char title[50];
    char author[50];
    float price;
};
int main() {
    struct Book b = {"C Guide", "S. Kumar", 299.50};
    printf("%s by %s costs %.2f\n", b.title, b.author, b.price);
    return 0;
}

                                    

Output

C Guide by S. Kumar costs 299.50

Answer 2:

#include <stdio.h>

union Number {
    int i;
    float f;
};
int main() {
    union Number n;
    n.i = 10;
    printf("i: %d\n", n.i);
    n.f = 5.5;
    // Now, n.i will be overwritten
    printf("f: %.2f\n", n.f);
    printf("i (after assigning f): %d", n.i);
    return 0;
}

Output

i: 10

f: 5.50

i (after assigning f): 1085276160

Chapter 17: File I/O Basics

What is File I/O?

File I/O means reading from and writing to files (data stored permanently on disk).

Key C Functions

  • fopen(), fclose() - open/close file.
  • fprintf(), fscanf() - formatted output/input to file.
  • fgets(), fputs() - read/write strings.
  • fread(), fwrite() - binary data.

Code Example 1: Writing to a Text File

#include <stdio.h>

int main() {
    FILE *fp = fopen("output.txt", "w");   // Open (or create) output.txt in write mode; returns a FILE* or NULL on failure
    if (fp == NULL) {                      // Check if the file failed to open
        printf("File not created!\n");     // Inform about the error
        return 1;                          // Exit with non-zero status indicating failure
    }

    // Write formatted text to the file (like printf but targets the file stream fp)
    fprintf(fp, "Hello, File!\nThis is a file writing example.");

    fclose(fp);                             // Always close the file to flush buffers and free resources

    printf("Done writing.\n");              // Inform the user that writing is complete
    return 0;                               
}

FILE is basically a data type, and we need to create a pointer variable to work with it (fp).

Code Example 2: Reading from a Text File

#include <stdio.h>

int main() {
    char buffer[100];
    FILE *fp = fopen("output.txt", "r");
    if (fp == NULL) {
        printf("File couldn't be opened!\\n");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%s", buffer);
    }
    fclose(fp);
    return 0;
}

Step-by-Step Loop Execution

Before First Iteration

  • buffer is allocated in memory (empty initially).
  • fp points to the opened file at the beginning.

Each Iteration Process

Step Action Details
1 Call fgets() fgets(buffer, sizeof(buffer), fp) attempts to read from the file.
2 Read Operation Reads up to 99 characters OR until a newline (\n) is found.
3 Store in Buffer Characters are stored in buffer[] with a null terminator (\0) added.
4 Return Value Check Returns the buffer pointer on success, or NULL on EOF/error.
5 Condition Test != NULL checks if the read was successful.
6 Execute Body If the condition is true, printf("%s", buffer) displays the line.

Output

Hello, File!

This is a file writing example.

Iteration fgets() Reads Buffer Contains printf() Outputs Return Value
1st "Hello World\n" "Hello World\n\0" Hello World (with newline) buffer pointer
2nd "This is line 2\n" "This is line 2\n\0" This is line 2 (with newline) buffer pointer
3rd "End" "End\0" End (no newline in file) buffer pointer
4th EOF reached buffer unchanged (no printf executed) NULL

Code Example 3: Appending Data

#include <stdio.h>

int main() {
    char buffer[100];
    FILE *fp = fopen("output.txt", "r");
    if (fp == NULL) {
        printf("File couldn't be opened!\\n");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%s", buffer);
    }
    fclose(fp);
    return 0;
}

Table: fopen Modes

Mode Description
"r" Read (file must exist)
"w" Write (new or overwrite)
"a" Append
"r+" Read + Write (must exist)
"w+" Write + Read (overwrites)

Practice Exercises

Exercise 1: Write a C program to write your name and age into a file called info.txt.

Exercise 2: Make a C program that reads the file info.txt and prints its contents.

Answers:

Answer 1:

#include <stdio.h>

int main() {
    FILE *fp = fopen("info.txt", "w");
    fprintf(fp, "Name: Alex\nAge: 23\n");
    fclose(fp);
    return 0;
}
                    

Answer 2:

#include <stdio.h>

int main() {
    char line[50];
    FILE *fp = fopen("info.txt", "r");
    while (fgets(line, sizeof(line), fp) != NULL) {
        printf("%s", line);
    }
    fclose(fp);
    return 0;
}

Ad

C Programming Glossary

Term Definition
Array Collection of elements of same data type stored in consecutive memory locations
ASCII American Standard Code for Information Interchange - character encoding standard
Assignment Operator Operators used to assign values to variables (=, +=, -=, etc.)
Binary Number system using only 0 and 1
Break Statement Statement used to exit from a loop or switch case
Compiler Program that translates C source code into machine code
Conditional Statement Statements that execute based on whether a condition is true or false
Continue Statement Statement that skips rest of current loop iteration and continues with next
Data Type Classification of data (int, float, char, double)
Declaration Statement that introduces a variable or function name
Definition Statement that actually creates/implements a function
Escape Sequence Special character combinations starting with backslash ($`\n`, etc.)
Expression Combination of variables, operators, and values that evaluates to a result
Function Block of code that performs a specific task
Header File File containing function declarations and definitions (#include )
Identifier Names given to variables, functions, arrays, etc.
Initialization Assigning initial value to a variable when declared
Iteration Repetition of a process (loops)
Keyword Reserved words in C language (int, for, if, while, etc.)
Library Function Pre-written functions provided by C (printf, scanf, strlen, etc.)
Loop Programming construct that repeats a block of code
Null Character Special character (`\0`) that marks the end of a string
Operator Symbol that performs an operation (+, -, *, /, %, ==, etc.)
Parameter Variable in function definition that receives a value
Pointer Variable that stores memory address of another variable
Preprocessor Program that processes source code before compilation (#include, #define)
Recursion Function calling itself
Return Statement Statement that exits a function and optionally returns a value
Scope Region where a variable or function can be accessed
Statement Complete instruction in C (ends with semicolon)
String Sequence of characters ending with null character
Structure User-defined data type that groups related data
Syntax Rules and structure of C language
Variable Named memory location that stores data

Further Learning Resources

Recommended Books

  1. The C Programming Language” by Brian Kernighan and Dennis Ritchie
    • The definitive C programming book by the creators.
  2. C Programming: A Modern Approach” by K.N. King
    • Comprehensive and beginner-friendl.y
  3. Head First C” by David Griffiths
    • Visual and engaging approach to learning C.

Development Tools

  1. IDEs and Editors
    • Visual Studio Code (with C extensions)
    • Code::Blocks
    • Dev-C++
    • CLion (Professional)
  2. Online Compilers
    • Repl.it
    • CodeChef IDE
    • CodeChef IDE

Next Steps After This Tutorial

  1. Data Structures: Learn linked lists, stacks, queues, trees.
  2. Advanced C: Pointers in depth, dynamic memory allocation.
  3. System Programming: File handling, process management.
  4. C++: Object-oriented programming extension of C.
  5. Embedded Programming: Using C for microcontrollers and IoT

Congratulations! 🎉

You’ve completed the comprehensive 50-hour C Programming tutorial. You now have a solid foundation in C programming and are ready to tackle more advanced topics and real-world programming challenges. Remember, the key to mastering programming is consistent practice and building projects. Keep coding and exploring new concepts!

Remember, programming is a lifelong learning journey. The logical thinking and problem-solving mindset you develop with C will serve you well in any tech career. Keep practicing, challenge yourself with new problems, and embrace the power of code!

Happy Coding!

About Website

TechTutorials is a beginner-friendly learning platform offering step-by-step tutorials in programming, ethical hacking, networking, automation, and Windows setup. Learn through hands-on projects, clear explanations, and real-world examples using practical tools and open-source resources—no signups, no tracking, just actionable knowledge to accelerate your technical skills.

AD

Color Space

Discover Perfect Palettes

AD

AD

Featured Wallpapers (For desktop)

Download for FREE!

Wallpaper 1
Wallpaper 23
Wallpaper 46
Wallpaper 81
Wallpaper 111
Wallpaper 116