C Language — BIT Exam
2083 BS • Complete Study Guide • English + नेपाली
Introduction to C Language
C is a general-purpose, procedural programming language developed in 1972 by Dennis Ritchie at Bell Labs. It is the foundation of modern computing and the most important language for BIT students.
Why is C Important?
- The oldest and most fundamental language — root of almost all modern languages
- Operating Systems (Linux, Windows, macOS) are written in C
- Fast and efficient — works close to hardware
- Foundation subject for BIT — master C, everything else becomes easier
- Used in embedded systems, drivers, game engines, and system software
Basic Structure of a C Program
#include <stdio.h> // Header file — needed for input/output int main() { // Main function — execution starts here printf("Hello, World!\n"); // Print output to screen return 0; // 0 = program ran successfully }
#include <stdio.h>, printf() and scanf() will NOT work. Every C program must include this header.
⚙️ How Does a C Program Run?
Source Code (.c) → Compiler (gcc) → Object Code (.o) → Linker → Executable (.exe / a.out)
2. Compilation — converts C to assembly
3. Assembly — converts assembly to machine code
4. Linking — combines object files into executable
C Keywords (Reserved Words)
These words have special meaning in C and CANNOT be used as variable names:
int float double char void long short unsigned
if else switch case break default return
for while do goto continue
struct union typedef enum sizeof static extern
Variables & Data Types
A variable is a named container in memory that stores data. Every variable must be declared with a data type before use.
Primary Data Types
| Data Type | Size | Range | Example |
|---|---|---|---|
| int | 2/4 bytes | -32768 to 32767 | int age = 20; |
| float | 4 bytes | 3.4e-38 to 3.4e+38 | float gpa = 3.8; |
| double | 8 bytes | Larger than float | double pi = 3.14; |
| char | 1 byte | -128 to 127 | char grade = 'A'; |
| void | 0 | No value | void main() |
Variable Declaration & Rules
int age = 20; // Integer variable float marks = 85.5; // Floating-point variable char grade = 'A'; // Character variable (single quotes) const int MAX = 100; // Constant — cannot be changed later long int pop = 1000000; // Larger integer
✔ Can contain letters, digits (0-9), and underscores
✘ Cannot start with a digit (e.g., 2marks is INVALID)
✘ Cannot use keywords (e.g., int, float)
✘ Cannot contain spaces (use_underscore instead)
Format Specifiers
| Specifier | Data Type | Example |
|---|---|---|
| %d | int | printf("%d", age); |
| %f | float | printf("%f", gpa); |
| %lf | double | printf("%lf", pi); |
| %c | char | printf("%c", grade); |
| %s | string | printf("%s", name); |
| %o | octal int | printf("%o", 8); → 10 |
| %x | hexadecimal | printf("%x", 255); → ff |
| %p | pointer address | printf("%p", ptr); |
Operators
Operators perform operations on variables and values. C has a rich set of operators grouped by purpose.
Arithmetic Operators
| Operator | Name | Example | Result |
|---|---|---|---|
| + | Addition | 5 + 3 | 8 |
| - | Subtraction | 5 - 3 | 2 |
| * | Multiplication | 5 * 3 | 15 |
| / | Division | 10 / 3 | 3 (integer) |
| % | Modulus | 10 % 3 | 1 (remainder) |
10/3 = 3 (integer division, truncates decimal) BUT 10.0/3 = 3.333 (float division). Modulus (%) is used to check odd/even: if(n % 2 == 0) means even!
Relational & Logical Operators
| Operator | Meaning | Example |
|---|---|---|
| == | Equal to | a == b |
| != | Not equal to | a != b |
| < > <= >= | Less/Greater than | a < b |
| && | Logical AND — both must be true | a>0 && b>0 |
| || | Logical OR — one must be true | a>0 || b>0 |
| ! | Logical NOT — reverses truth | !(a==b) |
Increment / Decrement Operators
int a = 5; printf("%d", a++); // Output: 5 (post-increment: print first, then increase) printf("%d", ++a); // Output: 7 (pre-increment: increase first, then print) int x = 10, y; y = x--; // y=10, x=9 (post-decrement) y = --x; // y=8, x=8 (pre-decrement)
Post (a++): use value FIRST, then change it.
Assignment & Bitwise Operators
| Operator | Meaning | Equivalent |
|---|---|---|
| += | Add and assign | a = a + b |
| -= | Subtract and assign | a = a - b |
| *= | Multiply and assign | a = a * b |
| /= | Divide and assign | a = a / b |
| & | Bitwise AND | — |
| | | Bitwise OR | — |
| ^ | Bitwise XOR | — |
| << >> | Left/Right Shift | — |
Input / Output
Functions to receive data from the user and display results on screen. All require #include <stdio.h>.
printf() — Formatted Output
printf("Name: %s, Age: %d\n", name, age); printf("Marks: %.2f\n", marks); // .2f = 2 decimal places printf("%10d\n", num); // Right-aligned, field width 10 printf("%-10d\n", num); // Left-aligned, field width 10 printf("%05d\n", num); // Zero-padded, width 5
scanf() — Formatted Input
int age; scanf("%d", &age); // & (address-of) is MANDATORY for scanf! float marks; scanf("%f", &marks); char name[50]; scanf("%s", name); // Arrays don't need & — name is already an address scanf("%49s", name); // Safer — limits input to 49 chars scanf("%d %d", &a, &b); // Multiple inputs at once
scanf("%d", age) → ❌ WRONG — program may crash!scanf("%d", &age) → ✅ CORRECT — & gives the memory address
Other I/O Functions
| Function | Purpose | Note |
|---|---|---|
| getchar() | Read single character | Returns int |
| putchar(c) | Print single character | — |
| gets(s) | Read full line (with spaces) | Unsafe — use fgets |
| puts(s) | Print string + newline | Simpler than printf |
| fgets(s,n,stdin) | Safe line input | Recommended |
Control Flow — if / else / switch
Control flow statements decide which block of code runs based on conditions. They are the decision-making tools of C.
if-else Statement
int marks = 75; if (marks >= 80) { printf("Distinction!\n"); } else if (marks >= 60) { printf("First Division\n"); // This block runs } else if (marks >= 45) { printf("Second Division\n"); } else { printf("Fail!\n"); }
switch Statement
int day = 3; switch(day) { case 1: printf("Sunday"); break; case 2: printf("Monday"); break; case 3: printf("Tuesday"); break; // This runs default: printf("Invalid day"); }
break, execution "falls through" to the next case — all remaining cases run! This is called fall-through behavior.
Ternary Operator
A compact one-line alternative to if-else: condition ? value_if_true : value_if_false
int a = 10, b = 20; int max = (a > b) ? a : b; // max = 20 printf("%s", (a%2==0) ? "Even" : "Odd"); // "Even" int abs_val = (a < 0) ? -a : a; // Absolute value
Loops — for, while, do-while
Loops execute a block of code repeatedly as long as a condition is true. They are essential for repetitive tasks.
for Loop — Use when count is known
// Syntax: for(initialization; condition; update) for(int i=1; i<=10; i++) { printf("%d ", i); // Prints 1 2 3 4 5 6 7 8 9 10 } // Factorial of n int n=5, fact=1; for(int i=1; i<=n; i++) { fact *= i; // fact = 1*2*3*4*5 = 120 } printf("Factorial = %d", fact);
while Loop — Use when condition is known
int i = 1; while(i <= 5) { printf("%d\n", i); i++; // WARNING: Forgetting this creates an infinite loop! } // Sum of digits of a number int num = 1234, sum = 0; while(num > 0) { sum += num % 10; // Get last digit num /= 10; // Remove last digit } printf("Sum = %d", sum); // 10
do-while — Executes at least once
int i = 1; do { printf("%d\n", i); i++; } while(i <= 5); /* KEY DIFFERENCE: Even if condition is false from start, do-while executes the body at least ONCE */ int x = 10; do { printf("Runs once!"); // This prints even though 10 > 5 is false below } while(x < 5); // Condition checked AFTER first run
while — when you know the condition but not the count
do-while — when you need to run at least once (e.g., menus)
Nested Loops — Pattern Printing
// Right-angle triangle pattern for(int i=1; i<=5; i++) { // Outer: controls rows for(int j=1; j<=i; j++) { // Inner: controls columns printf("* "); } printf("\n"); } /* Output: * * * * * * * * * * * * * * * */ // break and continue for(int i=1; i<=10; i++) { if(i == 5) break; // Exits loop entirely if(i % 2 == 0) continue; // Skips even numbers printf("%d ", i); // Prints: 1 3 }
Functions
A function is a reusable block of code that performs a specific task. Functions make programs modular, readable, and maintainable.
Function Syntax
#include <stdio.h> // 1. Function Declaration (Prototype) — tells compiler about the function int add(int a, int b); // 2. Function Definition — the actual code int add(int a, int b) { return a + b; // Returns the sum } // 3. Function Call — executing the function int main() { int result = add(5, 3); printf("Sum = %d", result); // Output: Sum = 8 return 0; }
Recursion
A function that calls itself. Must have a base case to stop, otherwise runs forever.
// Factorial using recursion int factorial(int n) { if(n == 0 || n == 1) return 1; // Base case — MUST have this! return n * factorial(n - 1); // Recursive call } // factorial(5) = 5 * factorial(4) // = 5 * 4 * factorial(3) // = 5 * 4 * 3 * 2 * 1 = 120 // Fibonacci using recursion int fib(int n) { if(n <= 1) return n; return fib(n-1) + fib(n-2); }
Call by Value vs Call by Reference
// Call by Value — original variable is NOT changed void byValue(int x) { x = 100; // Only local copy changes } // Call by Reference — original variable IS changed void byRef(int *x) { *x = 100; // Dereferences pointer — changes original } int main() { int a = 5; byValue(a); // a is still 5 after this call byRef(&a); // a is now 100 after this call }
Arrays
An array stores multiple values of the same data type under a single variable name. Elements are accessed via an index starting from 0.
1D Array
int marks[5] = {90, 85, 78, 92, 88}; // [0] [1] [2] [3] [4] ← indices printf("%d", marks[0]); // 90 — first element printf("%d", marks[4]); // 88 — last element // Print all elements using a loop int sum = 0; for(int i=0; i<5; i++) { printf("%d ", marks[i]); sum += marks[i]; } printf("\nTotal = %d", sum);
2D Array (Matrix)
int matrix[3][3] = { {1, 2, 3}, // Row 0 {4, 5, 6}, // Row 1 {7, 8, 9} // Row 2 }; printf("%d", matrix[1][2]); // 6 — Row 1, Column 2 // Print full matrix for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { printf("%d ", matrix[i][j]); } printf("\n"); }
Array Searching & Sorting
// Bubble Sort — swap adjacent elements int arr[] = {64, 34, 25, 12, 22}; int n = 5; for(int i=0; i<n-1; i++) { for(int j=0; j<n-i-1; j++) { if(arr[j] > arr[j+1]) { int temp = arr[j]; // Swap arr[j] = arr[j+1]; arr[j+1] = temp; } } } // Result: {12, 22, 25, 34, 64}
Strings
In C, a string is a character array terminated by a null character \0. There is no dedicated string data type — strings are built using char arrays.
String Declaration & Input
#include <string.h> // Required for string functions char name[50] = "Ram Bahadur"; // Stored as: R a m ... r \0 char city[20]; scanf("%s", city); // Stops at space — only gets first word fgets(city, 20, stdin); // Reads full line — recommended! // String stored as array of chars with \0 at end // "Hello" = {'H','e','l','l','o','\0'}
String Functions (from string.h)
| Function | Purpose | Example |
|---|---|---|
| strlen(s) | Returns length of string | strlen("Ram") = 3 |
| strcpy(dest, src) | Copies string src to dest | strcpy(a, "Hello") |
| strcat(dest, src) | Appends src to dest | strcat("Ram ", "Bdr") |
| strcmp(s1, s2) | Compares two strings | Returns 0 if equal |
| strupr(s) | Converts to uppercase | strupr("hello")="HELLO" |
| strlwr(s) | Converts to lowercase | strlwr("HI")="hi" |
| strrev(s) | Reverses string | strrev("abc")="cba" |
Returns negative if s1 < s2 (alphabetically before)
Returns positive if s1 > s2 (alphabetically after)
Pointers
A pointer is a variable that stores the memory address of another variable. Pointers are C's most powerful feature — essential for dynamic memory, arrays, and functions.
Pointer Basics
int num = 10; int *ptr; // Pointer declaration — stores address of int ptr = # // & = "address of" operator printf("%d\n", num); // 10 — value of num printf("%p\n", ptr); // 0x7fff — memory address (varies) printf("%d\n", *ptr); // 10 — * dereference = value at address *ptr = 20; // Change value via pointer printf("%d\n", num); // 20 — num is now changed!
& — Address-of: gets the memory address of a variable* — Dereference: gets the value at that memory address
Pointer & Arrays
int arr[] = {10, 20, 30}; int *p = arr; // arr already represents the address of arr[0] printf("%d\n", *p); // 10 — arr[0] printf("%d\n", *(p+1)); // 20 — arr[1] printf("%d\n", *(p+2)); // 30 — arr[2] p++; // Move pointer to next element printf("%d\n", *p); // 20 — now points to arr[1]
Null Pointer & Pointer Rules
int *ptr = NULL; // Safe initialization — points to nothing if(ptr != NULL) { // Always check before dereferencing! printf("%d", *ptr); } // Dangling pointer — AVOID this! int *dp; // printf("%d", *dp); ← Undefined behavior! Never use uninitialized pointer
Structures
A structure is a user-defined data type that groups variables of different data types under one name. Perfect for modeling real-world entities like students, employees, or products.
Structure Definition & Usage
#include <stdio.h> // Define structure blueprint struct Student { char name[50]; int roll; float marks; }; int main() { struct Student s1; // Create a variable of type Student struct Student s2 = {"Hari", 102, 90.5}; // Initialize directly s1.roll = 101; // Access with dot (.) operator s1.marks = 85.5; printf("Roll: %d, Marks: %.1f\n", s1.roll, s1.marks); return 0; }
typedef & Arrow Operator
// typedef creates an alias — no need to write "struct" every time typedef struct { int x, y; } Point; Point p1 = {3, 4}; // Cleaner — no "struct" keyword needed printf("%d", p1.x); // 3 — dot operator for direct variable // Pointer to struct — use arrow (->) operator Point *ptr = &p1; printf("%d", ptr->x); // 3 — arrow replaces (*ptr).x printf("%d", (*ptr).y); // 4 — equivalent way (less readable)
. when you have a struct variable: s1.rollUse
-> when you have a pointer to a struct: ptr->roll
Array of Structures
struct Student students[3] = { {"Ram", 101, 85.5}, {"Sita", 102, 92.0}, {"Hari", 103, 78.5} }; for(int i=0; i<3; i++) { printf("Name: %s, Marks: %.1f\n", students[i].name, students[i].marks); }
File Handling
File handling allows C programs to permanently store and retrieve data by reading from and writing to files on disk.
File Opening Modes
| Mode | Meaning | Note |
|---|---|---|
| "r" | Read only | File must exist |
| "w" | Write (create/overwrite) | Creates new or erases existing |
| "a" | Append | Adds to end of file |
| "r+" | Read + Write | File must exist |
| "w+" | Write + Read | Overwrites existing |
| "a+" | Append + Read | Preserves existing data |
File Read & Write Example
#include <stdio.h> int main() { FILE *fp; // FILE pointer — declared in stdio.h // ── Write to file ────────────────────────── fp = fopen("data.txt", "w"); if(fp == NULL) { printf("Error opening file!\n"); return 1; } fprintf(fp, "Roll: %d, Marks: %.2f\n", 101, 85.5); fclose(fp); // Always close the file! // ── Read from file ───────────────────────── char buffer[100]; fp = fopen("data.txt", "r"); while(fgets(buffer, 100, fp) != NULL) { printf("%s", buffer); // Print each line } fclose(fp); return 0; }
fopen() returns NULL if file cannot be opened — always check!fclose() is mandatory — without it, data may not be saved to disk.
File Functions Summary
| Function | Purpose |
|---|---|
| fopen(name, mode) | Open a file |
| fclose(fp) | Close a file |
| fprintf(fp, ...) | Write formatted data |
| fscanf(fp, ...) | Read formatted data |
| fgets(s, n, fp) | Read a line |
| fputs(s, fp) | Write a string |
| feof(fp) | Check end of file |
| rewind(fp) | Go back to beginning of file |
BIT Exam Quiz
Test your preparation with exam-style questions covering all 12 chapters!