30.6.25

Chapter Index: Learn 'C'

🌟 CHAPTER INDEX: LEARN 'C' (8 Chapters)

Chapter Topic Link Page Date
Chapter 1 First Steps in 'C' Visit 1–19 17 Jun 2025
How 'C' Programs Work? Visit 19–31 19 Jun 2025
Chapter 2 Making Decisions in 'C' Visit 31–72 20 Jun 2025
Chapter 3 Repeating with Loops Visit 72–115 21 Jun 2025
Code Control: IFs, LOOPs & BREAKs Visit 115–123 22 Jun 2025
Chapter 4 Switching Decisions in 'C' Visit 144–148 23 Jun 2025
Chapter 5 Functions and Pointers Made Simple Visit 157–171 24 Jun 2025
Functions Visit 171–178 24 Jun 2025
Pointers Visit 171–189 25 Jun 2025
Recursion Visit 189–201 25 Jun 2025
Chapter 6 Understanding Data Types Better Visit 201–223 26 Jun 2025
Variables Visit 223–234 26 Jun 2025
Chapter 7 The Preprocessor Visit 234–258 27 Jun 2025
If's Visit 258–263 27 Jun 2025
Chapter 8 Arrays and Strings Visit 263–277 28 Jun 2025
Array Passing Visit 277–287 28 Jun 2025
Array Things Visit 287–300 29 Jun 2025
Array of Pointers Visit 300–304 29 Jun 2025
Strings in Metamorphosis Visit 304–344 30 Jun 2025

20250630 16:00 Strings in Metamorphosis

                                              

← Previous 🏠 Homepage

                                                                                                

 - Strings in Metamorphosis



- When Letters Line Up and Do a Dance 

What are Strings?



  • A string is just a bunch of characters hanging out in a char array.

  • Like int arr[5] stores numbers, char name[10] stores characters.

  • And here's the twist: strings must end with a special guest — \0 (null character).
    Think of it like a secret agent that tells the program: “Stop! End of string here!”

Example:

char name[] = {'H','E','L','L','O','\0'};

Or, the cooler shortcut:

char name[] = "HELLO"; // C adds '\0' for you!

Why care about \0?




Without it, your string is like a sentence with no full stop.

The program won’t know when to shut up.

Printing Strings



Here’s a basic way to print strings:

while (name[i] != '\0') {
   printf("%c", name[i]);
   i++;
}

Or even cooler:

char *ptr = name;
while (*ptr != '\0') {
   printf("%c", *ptr);
   ptr++;
}

Wanna be super cool? Just do:

printf("%s", name); // Easy-peasy lemon squeezy 

Input from User:



scanf("%s", name);

BUT! Only works for one-word names like Batman.
So "Bruce Wayne"? Nope.

To get full names (multi-word), use:

gets(name); // Accepts spaces too
puts(name); // Prints it with a new line

Just don’t let your string get too long or your program might freak out. 

Pointers & Strings:


char str[] = "Hello"; // normal string
char *p = "Hello";     // string pointer

Key Difference:

  • str1 = "Bye"; (error! arrays can’t be reassigned)

  • p = "Bye"; (pointers are chill)

Also:

  • You can't do str2 = str1; 

  • But q = s; works fine if they’re pointers. 

- Spellbook of 'C'


strlen() – String Length Detector

Job: Counts how many characters are in your string (not including \0)
Example:

strlen("Bamboozled"); // 10

DIY version:

int xstrlen(char *s) {
  int len = 0;
  while (*s != '\0') {
    len++;
    s++;
  }
  return len;
}

strcpy() – Copy-Paste Master

Job: Copies one string into another

strcpy(target, source);

Make sure target is big enough — it doesn’t ask before copying! 

DIY version:

void xstrcpy(char *t, const char *s) {
  while (*s != '\0') {
    *t = *s;
    t++;
    s++;
  }
  *t = '\0'; // Don’t forget to end it!
}

strcat() – The String Gluer

Job: Joins one string to the end of another

strcat(target, source);

"Hello" + "World" = "HelloWorld"
Just make sure target has enough space… or C will go full Hulk! 

You can try making your own xstrcat() for fun!

strcmp() – String Gladiator

Job: Compares two strings to see if they’re same

strcmp("Tom", "Tom");    // 0 → perfect match
strcmp("Tom", "Tim");    // not 0 → mismatch

Returns:

  • 0 if they match (yay!)

  • >0 or <0 if they don’t (depends on ASCII)

Example:

strcmp("Jerry", "Ferry");   // returns 4 ('J' - 'F')
strcmp("Jerry", "Jerryboy");// returns -32 ('\0' - ' ')

DIY version:

int xstrcmp(char *s1, char *s2) {
  while (*s1 && *s2 && *s1 == *s2) {
    s1++;
    s2++;
  }
  return *s1 - *s2;
}


29.6.25

20250629 16:30 Array of Pointers

                 

← Previous 🏠 Homepage Next Chapter →

                                           


Array of Pointers – A GPS to Data!



What if you had a list that only stored addresses (locations)? 
That’s an array of pointers! Each element is a pointer (basically, a little guy holding a house number).

int *arr[4];
int i = 31, j = 5, k = 19, l = 71;
arr[0] = &i;
arr[1] = &j;
arr[2] = &k;
arr[3] = &l;

Now arr is like a list of spies that tell you where the secret treasure (data) is hidden!
Use *arr[m] to open the treasure chest and see the number inside. 

It’s just like:

“Hey arr[0], where’s i? Oh, 31? Thanks buddy!”

Pointer Array from an Array



You can even create a pointer array that points to different elements of another array:

static int a[] = { 0, 1, 2, 3, 4 };
int *p[] = { a, a + 1, a + 2, a + 3, a + 4 };

Now:

  • p = address list

  • *p = address of a[0]

  • **p = value at that address = 0

Like a pointer-caption! 

Three-Dimensional Array – The Data Cube!





A 3D array is like a box of boxes of boxes. (Matrix inside a matrix inside a matrix!)

int arr[3][4][2] = {
  { {2, 4}, {7, 8}, {3, 4}, {5, 6} },
  { {7, 6}, {3, 4}, {5, 3}, {2, 3} },
  { {8, 9}, {7, 2}, {3, 4}, {5, 1} }
};

This means:

  • 3 layers (think: floors of a building )

  • 4 rows on each floor

  • 2 columns in each row

Want the number 1?

arr[2][3][1]

Break it down:

  • 2 → 3rd floor

  • 3 → 4th row

  • 1 → 2nd column

But wait, pointer magic time!

*( *( *( arr + 2 ) + 3 ) + 1 )

Same result — just sounds like a math wizard’s chant 
Don't worry, it's all memory arithmetic in disguise!

- Summary!



What’s an Array?

An array is a group of similar items stored together.
Think: A row of boxes with numbers on them!

int nums[5] = {10, 20, 30, 40, 50};
  • nums[0] = 10

  • nums[1] = 20

  • *(nums + 1) = 20 (same thing!)

2D Arrays = Tables 

int marks[3][2] = {
  {101, 80},
  {102, 90},
  {103, 85}
};

Looks like a table of students: roll no & marks!

Pointers + Arrays = Magic

  • arr[i] == *(arr + i)

  • arr[i][j] == *(*(arr + i) + j)

Yes, it’s memory wizardry! 

Array of Pointers

You can store addresses in arrays too!

int *ptrs[3];

They point to variables or arrays.

3D Arrays = Data Cubes 

arr[2][3][1] = value

A 3D array is just arrays inside arrays inside arrays!


28.6.25

20250629 09:00 Array things


← Previous 🏠 Homepage Next Chapter →
                                                          

                                            

Arrays: The Organized Wardrobe of C



Think of an array like a cupboard with multiple drawers. Each drawer has a number (called an index), and you can store your socks (values) inside!

int num[] = { 24, 34, 12, 44, 56, 17 };

num[0] means the 1st drawer, which has 24.
But here's the twist:
*(num + 0) is the same thing!
Even this works: 0[num] 
Yes, i[num] == num[i] — C is cool (and a little crazy!).

The Real Thing: Access Array in 4 Crazy Ways!



printf("%d", num[i]);
printf("%d", *(num + i));
printf("%d", *(i + num));
printf("%d", i[num]);

All print the same value. C is basically saying:
"Hey, I’m flexible — call me however you like!" 

2D Arrays: The Spreadsheet of 'C'



Imagine a school chart where each row is a student, and columns are their roll number and marks.

int stud[4][2] = {
  {1234, 56},
  {1212, 33},
  {1434, 80},
  {1312, 78}
};

Here:

  • stud[0][0] → Roll No. of student 1

  • stud[0][1] → Marks of student 1

Just like Excel — but with more semicolons and fewer colors 

Memory Trick: It’s All Linear!

Even though we think in rows and columns, C stores everything in a single line (row by row).
Like how noodles are packed — long and continuous 

Pointers + 2D Arrays = Magic!



*( *(s + 2) + 1 ) == s[2][1]

Don't worry, it's not Harry Potter spells 🪄 — it's just pointer magic!

  • s + 2 → Go to 3rd row (0-based)

  • *(s + 2) → Address of 3rd row

  • *( *(s + 2) + 1 ) → 2nd column of 3rd row

So basically: *( *(s + i) + j ) == s[i][j]
Boom! 

Pointer to an Array (aka GPS to a Row)



int (*p)[2]; // p is a pointer to an array of 2 ints

Now you can go row by row like a pro!

You get the address of each row:

p = &s[i]; // point to row i

Then use:

pint = p;

And access elements using:

*(pint + j)

Like saying, "Hey C, take me to row i, column j!" 

Passing 2D Arrays to Functions: 3 Flavors




Like ice cream, there are 3 ways:

1. Using a plain int* pointer:

* (q + i * col + j)

Calculate the exact spot like a math wizard. 

2. Using pointer to array:

int (*q)[4];

Move row-by-row, then jump to columns.

3. Using normal 2D array notation:

int q[][4];

Old-school and easy! Just say q[i][j].

All roads lead to Rome... or in this case, the array element. 

20250628 15:00 Array passing

  

← Previous 🏠 Homepage Next Chapter →
                                   

                                                



1. Passing Array Elements — One at a Time!




You can pass one box (element) from the array to a function:

Call by Value:

display(marks[i]);  // just sending the value
void display(int m) {
   printf("%d", m);  // m is just a copy
}

You’re giving the function a photocopy of the value. It can't change the original. 

Call by Reference:

disp(&marks[i]);  // sending the address
void disp(int *n) {
   printf("%d", *n);  // dereference and print the real thing!
}

You’re giving the function a key to the real box (memory address). 

2. Passing the Whole Array to a Function




Why send elements one by one when you can send the whole army? 

int num[] = {24, 34, 12, 44, 56, 17};
display(num, 6);  // OR display(&num[0], 6);
void display(int *j, int n) {
  for (int i = 0; i < n; i++) {
    printf("element = %d\n", *j);
    j++;  // move to next soldier
  }
}

Boom! You just passed the entire array using its base address.

3. Pointers + Arrays = Besties!



Pointers and arrays are like twins :

  • num[i] is the same as *(num + i)

  • Arrays live in contiguous memory (next to each other)

4. Pointer Magic Show



int num[] = {24, 34, 12, 44, 56, 17};
int *j = &num[0];

for (int i = 0; i < 6; i++) {
  printf("address = %u, element = %d\n", j, *j);
  j++;
}

Every time you do j++, it jumps to the next element (2 bytes ahead for int). It’s like hopping from box to box! 

Pointers Can Fight (And Compare!)



int *j = &arr[4];
int *k = arr + 4;

if (j == k)
  printf("Same location!");

Yes, you can compare pointers. But beware:
Don’t try pointer + pointer
Don’t multiply or divide them
It’ll confuse poor 'C' 

So, When to Use What?

Situation Use This
Access in fixed order     Use pointers 
Access randomly or complex logic     Use subscripts 
Want speed?     Pointers zoom! 



27.6.25

20250628 09:30 Chapter 8 - Arrays


← Previous 🏠 Homepage Next Chapter →
                                            

                                             




First, a Problem:

int x;
x = 5;
x = 10;
printf("%d", x); // Prints 10

Why not 5? Because poor x can only remember one thing at a time. 

But what if you had to store marks of 100 students? You could make 100 variables...
Or you could just use one awesome array. 

So, What’s an Array?



An array is like a row of boxes , all of the same type (like all int, or all float).

Each box has:

  • A name (like marks)

  • A position (called an index, starting from 0)

Example:

int marks[5] = {48, 88, 69, 23, 96};

Here:

  • marks[0] is 48

  • marks[1] is 88

  • And guess what? marks[4] is 96
    But if you ask for marks[5], C gets angry. It doesn't exist!

Declaring an Array



int marks[30];

Means: "Hey C! Reserve 30 boxes to store integers!" 

Let's Build a Cool Example



int marks[30];  // 30 students
int sum = 0, avg;
for (int i = 0; i < 30; i++) {
    printf("Enter marks: ");
    scanf("%d", &marks[i]);  // Put marks in each box
}
for (int i = 0; i < 30; i++) {
    sum += marks[i];  // Add all marks together
}
avg = sum / 30;
printf("Average marks = %d", avg);

1.Array Initialization – Give It a Head Start!



Instead of stuffing values after declaring the array, why not feed it right away?

int num[6] = {2, 4, 12, 5, 45, 5};   // Full buffet 
int n[] = {2, 4, 12, 5, 45, 5};      // No size? No problem!
float press[] = {12.3, 34.2, -23.4, -11.3}; // Floats love arrays too

Tips:

  • If you don’t initialize, C fills it with garbage (not banana peels, but random numbers).

  • If you use static, C is kind enough to fill all with 0. Zero is love 

2.Memory Magic – Where Arrays Live



int arr[8];

Boom  — 8 boxes (a.k.a. memory slots) are created:

  • In Turbo C: 2 bytes each = 16 bytes total

  • In modern systems: 4 bytes each = 32 bytes

And guess what? All boxes are side by side — like besties in a train compartment 

But remember: uninitialized = garbage inside! Unless declared static.

3.Beware of Array Overflow – C Won’t Warn You!



Here comes the monster:

int num[40], i;
for (i = 0; i <= 100; i++)
    num[i] = i;  // Yikes! 

You’re writing way past the array’s limit. What happens?

  • C says nothing 

  • You might overwrite other data

  • Or even crash your program 

C doesn’t babysit. It’s your job to stay within the bounds. No crossing the array border!


20250627 16:00 If's

                                      

← Previous 🏠 Homepage Next Chapter →
                                         

#if & #elif – If your code has trust issues...



Think of #if like a “bouncer” at a party:
"If the condition is true, you can enter this part of the code."

#if AGE >= 18
  printf("Welcome to the party!\n");
#else
  printf("Go back to school, kid!\n");
#endif

You can also do:

#if LEVEL == HARD || MODE == CRAZY
  // Challenge accepted
#endif

Use #elif to make it fancier:

#if ADAPTER == VGA
  // VGA code
#elif ADAPTER == SVGA
  // SVGA code
#else
  // Potato mode (EGA)
#endif

#elif = fewer #endifs = cleaner code = less headache!

#undef – Break with a macro



If you don't want to use a macro anymore (maybe it's being annoying), just do:

#undef PI

Now PI is no longer defined. Like a ghosted ex—poof, gone! 

#pragma – Secret commands to your compiler



Think of #pragma like whispering to the compiler:
"Hey... do something cool (or weird)."

#pragma startup and #pragma exit




They let you run special functions before and after main().
#pragma startup fun1
#pragma exit fun2

void fun1() { printf("Warming up...\n"); }
void fun2() { printf("Shutting down...\n"); }

void main() {
  printf("Main program running!\n");
}

Output:

Warming up...
Main program running!
Shutting down...

Note: The startup function runs before main(), and the exit function runs after it ends. Like putting on shoes before going out—and taking them off after coming back.

#pragma warn – Mute those annoying warning messages



Example:

#pragma warn -rvl // suppress return value warning
#pragma warn -par // suppress unused parameter warning
#pragma warn -rch // suppress unreachable code warning

Now even if you write messy code, compiler will say:
“I saw nothing.”

But don’t do this forever—it’s like ignoring a leaky tap. One day… 


Wrap-Up !



Directive What It Does
#if, #elif, #else, #endif Chooses which code to compile
#undef Erases a macro
#pragma Sends special instructions to the compiler (e.g., startup, exit, suppress warnings)

The preprocessor is like a code genie – it grants your wishes before compilation even begins. 
Use its powers wisely, and it’ll make your coding life a lot more magical.

Need the last part of the chapter? Just shout "abracadabra"! 

26.6.25

20250627 9:30 Chapter 7 : C's Secret Assistant-The Preprocessor

     

← Previous 🏠 Homepage Next Chapter →
                            

                                                

                                   


C Preprocessor – The Brainy Assistant Before Compilation!



Before your C program even gets to run, it goes through this nerdy assistant called the preprocessor. Think of it like your program’s personal butler—it sets everything up, does the boring chores, and hands a neat, ready-to-go version to the compiler. 

What Does It Do?



It looks for commands starting with # and handles 4 main tasks:

  1. Macro Expansion – Like shortcuts in texting.

    • #define PI 3.14 → Every time you write PI, it auto-replaces with 3.14.

    • Saves time and effort—change in one place = change everywhere!

    • Bonus: No semicolon at the end!

  2. Macros with Arguments – Like mini inline functions.

    #define SQUARE(x) (x * x)
    

    Be careful! Wrap in brackets or math will go wild!
    64 / SQUARE(4) becomes 64 / 4 * 4 

  3. File Inclusion – Copy-paste entire files!

    #include <stdio.h>` or `#include "myfile.h"`
    

    Boom! That file becomes part of your program.

  4. Conditional Compilation – Include/exclude parts of code.

    #ifdef DEBUG
       printf("Debugging...");
    #endif
    

    Only compiles if DEBUG is defined. Sneaky, right?

Macro vs Function – Who Wins?



Macros Functions
Faster (no real call)     Slower (function call time)
Can make code BIG     Compact
No type-checking      Type-safe 
Compiler can't debug inside     Easy to debug

Use macros for small stuff, and functions for big jobs!

Gotchas:

  • Don't put spaces: [#define AREA(x).not #define AREA (x)] 

  • Wrap your macro body in parentheses!

  • You can use \ to break a macro into multiple lines.

 Why Care?

  • Makes your code clean, readable, and change-friendly.

  • Saves you from typing the same thing 100 times.

  • Helps your program wear sunglasses  – cool, clean, and sharp!

File Inclusion – Copy-Paste Magic!



Want to borrow code from another file? Just do this:

#include "filename"    // Look in your folder (current directory)
#include <filename>    // Look in standard folders (like library)

It’s like calling a friend to do some work for you!

Use it when:

  • You have a big program and want to split it into smaller parts.

  • You always use certain functions/macros and want to reuse them easily.

Usually, files included like this are called header files (.h), like:

#include <stdio.h>
#include <math.h>

Conditional Compilation – Code with Switches!



This lets you hide or show parts of your code like magic tricks.

Example:

#ifdef DEBUG
   printf("Debugging mode ON!");
#endif

Use cases:

  1. Hide old code without deleting it!
    (Clients always change their minds, right? )

  2. Run same code on different computers:

#ifdef INTEL
   // Code for Intel PC
#else
   // Code for Motorola PC
#endif
  1. Prevent duplicate file includes:

#ifndef __MYFILE_H
#define __MYFILE_H
// Your awesome code here!
#endif

So it’s included just once, not twice!


20250626 16:30 Variables

    

← Previous 🏠 Homepage Next Chapter →
                                   

                                          


Storage Classes – Where Variables Live & How Long                                                           

                                         


Auto 

  • Lives in: Memory

  • Starts with: Garbage value

  • Scope: Inside the block

  • Life: Until block ends

Register

  • Lives in: CPU Register (if available)

  • Faster access (good for loop counters!)

  • Starts with: Garbage

  • Can’t store float or double

Static

  • Lives in: Memory

  • Starts at: 0

  • Scope: Local

  • Life: Lives forever (retains value across function calls)

  • Use when value must be remembered between calls

External Storage Class (extern)

Where it lives: Memory
Default value: 0
Scope: Global — available to all functions
Lifetime: As long as the program is alive 

Global Variables 



Variables declared outside all functions are global. That means any function can use them — no permission slip needed!

Example:

int i;

main() {
  printf("%d", i);  // prints 0
  increment();
  decrement();
}

increment() { i++; }
decrement() { i--; }

Result? 

The same i is used and updated by all functions. One big happy variable family.

extern int y; vs int y = 31;

  • extern int y; → Just tells the compiler “Hey, y exists somewhere!”

  • int y = 31; → This actually creates y and gives it a home (in memory).

A variable can be declared (extern) many times but defined (int y = 31;) only once.

Local vs Global Name Clash



int x = 10;

main() {
  int x = 20;
  printf("%d", x);    // prints 20 (local wins!)
  display();
}

display() {
  printf("%d", x);    // prints 10 (global x)
}


One Last Thing About static Globals

If you write:

static int count;

outside all functions — it acts like extern, but only within the same file. So it’s a private global — like a secret agent 

When to Use Which Storage Class?



Here’s your cheat sheet for smart C programming:

Storage Class Use It When...
auto  You just need a variable for temporary work. Like a sticky note — use and throw.
register You need speed — loop counters or frequently accessed stuff. Just remember, CPU registers are few, so don’t overdo it! 
static You want to remember a value between function calls. Like a goldfish with memory — but better. 
extern You want one variable that everyone in the program can use, across functions and even files. Like a public notice board. 

Pro Tips:



  • Don't spam register or you'll run out of CPU registers.

  • Don’t declare everything extern — wastes memory.

  • Use static only when you need to remember stuff between function calls.

  • Most of the time, auto is just perfect. Simple. Clean. Done.


rating System

Loading...

Understanding Arrays in C

The Bookshelf Analogy & Book-Author Example Arrays are one of the most essential concepts in C programming. They let you store multiple ...