C Programming by Yash Sir: Complete Guide with Worked Examples

Build C from evaluation rules to pointers with worked output traces, a recursion call stack, memory diagrams, common traps, and a clear route into exam and placement practice.

KnowledgeGate Team

Exam prep & CS education

Updated 4 Aug 20267 min read

C has barely 32 keywords, yet exact rules make it difficult: integer division discards a part, loop tests have precise timing, functions receive values, and an array name is not a pointer variable. Predicting by feel picks the wrong option. Tracing does not: write the state down, apply the rule, read the answer off.

The C Programming map, and how to study it in order

Study C in six connected blocks:

  1. Fundamentals: data types, operators and expressions decide every value.

  2. Control flow: if-else, loops and switch decide what runs and how often.

  3. Functions and recursion: calls divide work; the call stack explains recursive output.

  4. Arrays, pointers and strings: one memory model connects data, addresses and text.

  5. Storage classes, structures and unions: these control lifetime, visibility and layout.

  6. Dynamic memory, macros and files: these complete the language for larger programs.

Functions and recursion, followed by arrays and pointers, carry much of the weight in exams and interviews. Arrays lead into the sorting algorithms comparison; structures and pointers build linked structures. Yash Jain (Yash Sir) teaches this ground in 40 concept lessons and then 59 worked coding questions, which is the concept-then-practice order worth keeping.

Fundamentals: types, operators and the rules that decide outputs

For int a = 7, b = 2;, C evaluates a / b as 3 and a % b as 1:

a / b                 // 3
a % b                 // 1
a / b * b + a % b     // 3 * 2 + 1 = 7

The third result must equal a: positive integer quotient and remainder follow (a / b) * b + a % b == a.

The operands, not the destination, decide conversion. float f = 7 / 2; performs integer division first and stores 3.0. float g = 7 / 2.0; has a floating-point operand and stores 3.5.

For precedence, int k = 2 + 3 * 4 % 5; becomes 2 + ((3 * 4) % 5), then 2 + (12 % 5), then 2 + 2, so k is 4. Bracket expressions before calculating.

Control flow: trace the state, not the syntax

Use one column per variable and one row per iteration:

int s = 0, i = 1;
while (i <= 10) {
    s += i;
    i += 3;
}

i at test

s after addition

i after update

1

1

4

4

5

7

7

12

10

10

22

13

The next test, 13 <= 10, fails. Four iterations leave s = 22 and i = 13. Reporting i = 10 forgets the final update.

In a switch with x = 2, suppose cases 1, 2 and 3 print their names and only case 3 has break. Execution enters case 2 and falls through, printing two three. Default is skipped. A case label is an entry point, not a fence.

A do-while tests after its body, so it always runs at least once.

Functions and recursion: trace the call stack

C passes arguments by value. With caller variables x = 3 and y = 8, swap(x, y) changes only copies. To change the originals, pass addresses and dereference them.

Now trace this recursion exactly:

void fun(int n) {
    if (n == 0) return;
    fun(n / 10);
    printf("%d ", n % 10);
}

Calling fun(2764) creates five calls: fun(2764) -> fun(276) -> fun(27) -> fun(2) -> fun(0). The last returns without printing. On the unwind, fun(2) prints 2, fun(27) prints 7, fun(276) prints 6, and fun(2764) prints 4. Output: 2 7 6 4.

Move printf before the call and the descent prints 4 6 7 2. Work before or after the recursive call decides the order.

A five-frame call stack for fun(2764) showing each recursive call and, on unwinding, the digits 2, 7, 6, 4 printed in that order.

Arrays, pointers and strings: use one memory model

The identity is a[i] == *(a + i). With int a[5] = {10, 20, 30, 40, 50}; int *p = a;, *(a + 3) is 40, p[1] is 20, and sizeof(a) / sizeof(a[0]) is 20 / 4 = 5 for 4-byte integers.

On a 64-bit machine with 8-byte pointers, sizeof(p) is 8 while sizeof(a) stays 20. An array name converts to a pointer in many expressions, but the array remains five objects.

For char s[] = "GATE";, sizeof(s) is 5, including the terminator, while strlen(s) is 4. Writing through a char * to a string literal is undefined. An array parameter becomes a pointer, so the whole-array sizeof trick stops working across a call.

A five-element int array holding 10 to 50 across addresses 1000 to 1016, with pointer p at 1000 and *(a + 3) reaching value 40.

Structures and pointers combine into nodes in binary trees and binary search trees.

Storage classes, structures and unions: state and layout

A function containing static int c = 0; c++; return c; returns 1, 2, 3 across three calls. The variable is initialised once and lives for the whole run. Plain int c = 0 is recreated, so the results are 1, 1, 1.

auto is block-local, static preserves lifetime, extern refers to a definition elsewhere, and register asks the compiler to keep a heavily used local in a register, which is also why you cannot take its address. Scope says where a name is usable; lifetime says how long its object exists.

Structure members have separate storage; union members share the largest member's storage. With 4-byte integers and alignment, struct { char c; int i; } commonly occupies 8 bytes after padding, while union { char c; int i; } occupies 4. Padding is implementation-defined, so check the integer size and alignment a question states before computing either total.

Dynamic memory, macros and files: allocation, expansion and streams

int *q = malloc(5 * sizeof(int)); reserves twenty uninitialised bytes; calloc(5, sizeof(int)) reserves the same twenty and zeroes them. sizeof(q) is 8 on that same 64-bit machine, not 20, so an allocated block carries no size you can query. Free it exactly once: reading after free, or a double free, is undefined.

Macros are text, not values. #define SQR(x) x*x makes SQR(2+3) expand to 2+3*2+3, which is 11, not 25. Parenthesise the parameter and the body: #define SQR(x) ((x)*(x)) gives 25.

fopen returns NULL when it cannot open the file, so test the pointer before the first read. Mode "r" fails on a missing file, "w" truncates an existing file to zero length, and "a" keeps the contents and writes at the end.

C traps that cost marks

  • Assignment in a condition: if (x = 5) assigns a non-zero value, making the condition true. Check = versus ==.

  • Integer averaging: (7 + 2) / 2 is 9 / 2, then 4, not 4.5. A float destination cannot recover the fraction.

  • A stray semicolon: for (i = 0; i < 5; i++); runs an empty body five times. The next block runs once with i = 5.

  • A C character constant: sizeof('A') is sizeof(int) in C, typically 4, not 1. C++ treats this differently.

  • A missing address: scanf("%d", n) supplies a value, not an address. Use &n for an ordinary int.

  • Unsequenced modifications: the i++ + ++i family has undefined behaviour. Answer “undefined”, never a guessed number.

  • A dangling else: it binds to the nearest unmatched if. Add braces while tracing.

How GATE and interviews test C, and the next step

GATE places C inside Programming and Data Structures. Recent papers have used output-prediction MCQs and NATs around recursion and pointer arithmetic. Check the official GATE site of the conducting institute for a particular attempt's syllabus and marks scheme.

Placement tests use the same traces; interviews ask you to explain them. Draw the recursion stack and state when each print runs.

KnowledgeGate's published question bank carries over 1,000 C Programming questions: about 125 on loops and iteration, over 110 on operators and expressions, and roughly 260 across arrays and pointers. Once the C traces feel routine, move on to Data Structures MCQs.

The short version

  • For positive integers, (a / b) * b + a % b == a.

  • Trace loops in a variable table, including the final update before a failed test.

  • Printing after a recursive call gives unwind order; printing before it gives call order.

  • An array is a row of objects, while a pointer is one object holding an address.

  • A static local variable remembers its value across calls.

Learn the sequence in the C Language Course by Yash Sir. For the data structures and languages that build on C, browse Coding and DSA Courses for Placements.