Complete C Programming Guide for BSc CSIT 1st Semester (TU) | Notes, Solved Programs, Pointers & Exam Preparation
Introduction
C is 50 years old and still the most important language you'll learn in your first year. That might sound strange when you could be learning Python or JavaScript instead, but the reason BSc CSIT puts C in the first semester isn't tradition — it's that C teaches you things no higher-level language does. In Python you never think about memory addresses. In JavaScript you never worry about whether your data will fit in 4 bytes. C makes you think about all of that, which is exactly why systems programmers, embedded engineers, operating system developers, and compiler writers still reach for it when they need control over what the hardware actually does.
The operating system running on your laptop right now — Linux, Windows, macOS — is written in C. The CPython interpreter that runs Python programs is written in C. The firmware sitting inside your phone's processor is written in C. When you understand C, you understand the layer that almost everything else is built on top of.
For your BSc CSIT first-semester exam specifically, C is also one of the highest-scoring subjects if you prepare the right way. Unlike theory-heavy subjects where marks depend on how much you've memorized, C rewards students who've actually sat down and written programs. You can walk into the exam having practiced fifty programs and feel genuinely confident about what's coming. This guide is built around helping you do exactly that.
Official Course Information
| Particular | Details |
|---|---|
| Course Title | C Programming |
| Course Code | CSC115 |
| Semester | First Semester |
| Nature of Course | Theory + Lab |
| Full Marks | 60 + 20 + 20 |
| Pass Marks | 24 + 8 + 8 |
| Credit Hours | 3 |
Course Description and Objective
CSC115 covers structured programming using the C programming language. The course is designed to familiarise students with the techniques of programming in C — not just syntax, but logic building and program development capability that the rest of the BSc CSIT program depends on. The lab component (20 marks) is substantial and expects you to write, compile, debug, and test real programs across all eleven units, including a small integrative project pulling concepts from multiple units.
Official Unit-Wise Syllabus Overview
| Unit | Title | Hours |
|---|---|---|
| 1 | Problem Solving with Computer | 2 |
| 2 | Elements of C | 4 |
| 3 | Input and Output | 2 |
| 4 | Operators and Expressions | 4 |
| 5 | Control Statements | 4 |
| 6 | Arrays | 6 |
| 7 | Functions | 5 |
| 8 | Structure and Union | 5 |
| 9 | Pointers | 6 |
| 10 | File Handling in C | 4 |
| 11 | Introduction to Graphics | 3 |
Units 6 and 9 carry the most hours and are consistently the most exam-heavy. File Handling (Unit 10) is frequently underestimated — many students skip it during preparation and lose straightforward marks. Unit 1 (Problem Solving, Algorithms, Flowcharts) is short but almost always appears as a short-question opener.
Why C is Called the Mother of Modern Languages
Dennis Ritchie developed C at Bell Labs in the early 1970s, and the reason it's still taught everywhere has nothing to do with nostalgia. C++ is a superset of C. Java borrowed its syntax. PHP and Python share significant design DNA with it. If you learn C properly, you'll notice you already understand the skeleton of every one of those languages the first time you see them.
More practically: C gives you direct access to memory through pointers, which means you're not insulated from the hardware by layers of runtime garbage collectors or virtual machines. When you write int a = 10; in C, that variable lives at a specific address in your computer's RAM, and C gives you a tool — the pointer — to find and work with that address directly. No other language at this level of the curriculum teaches you to think that way.
The Structure of a C Program
Every valid C program has the same skeleton. Understanding each part isn't just useful for explaining it in an exam — it's what makes error messages readable when something goes wrong.
#include <stdio.h> /* Preprocessor directive — includes the standard I/O library */
int main() { /* main() is where execution always starts. int means it returns an integer. */
printf("Hello, World!\n"); /* printf() prints to the screen. \n is a newline character. */
return 0; /* return 0 tells the operating system the program ran successfully. */
}
The preprocessor directive #include <stdio.h> runs before the compiler sees your code — it pastes in the definitions of functions like printf and scanf from the standard input/output library, so the compiler knows what they are. Without it, using printf would cause a "function not declared" error.
The main() function is mandatory and special: it's the single entry point the operating system calls when it launches your program. You can have hundreds of other functions in a C program, but execution always starts at main. The return 0; at the end is a convention — by returning 0, your program tells the OS "finished without errors," while a non-zero return value signals something went wrong.
Data Types
C has a relatively small set of built-in data types, but each one has a specific size and range that you're expected to know, because choosing the wrong type can cause unexpected behavior in programs.
| Data Type | Size | Typical Range |
|---|---|---|
int |
4 bytes | −2,147,483,648 to 2,147,483,647 |
unsigned int |
4 bytes | 0 to 4,294,967,295 |
short |
2 bytes | −32,768 to 32,767 |
long |
4 or 8 bytes | At least −2,147,483,648 to 2,147,483,647 |
float |
4 bytes | ~1.2×10⁻³⁸ to ~3.4×10³⁸ (6–7 decimal digits) |
double |
8 bytes | ~2.3×10⁻³⁰⁸ to ~1.7×10³⁰⁸ (15 decimal digits) |
char |
1 byte | −128 to 127 (or 0 to 255 unsigned) |
A char stores a single character, but C actually stores its ASCII numeric value — char c = 'A'; stores the number 65 internally, which is why you can do arithmetic on chars.
Operators and Precedence
C has a larger set of operators than most students expect, and operator precedence governs which operation happens first in an expression without explicit parentheses.
Types of Operators
Arithmetic: + - * / %
The % operator gives the remainder of integer division — 17 % 5 gives 2. It doesn't work on floats.
Relational: == != > < >= <=
These return 0 (false) or 1 (true). A very common mistake is writing = (assignment) instead of == (comparison) inside an if condition.
Logical: && || !
&& is true only when both sides are true. || is true when at least one side is true. ! flips true to false and false to true.
Bitwise: & | ^ ~ << >>
These operate directly on the binary representation of a value.
Increment/Decrement: ++ --
Pre-increment ++i adds 1 before the expression is evaluated. Post-increment i++ adds 1 after. The difference matters inside expressions like a = ++i; vs a = i++;.
Assignment: = += -= *= /= %=
Operator Precedence (High to Low)
| Priority | Operators |
|---|---|
| Highest | () [] -> . |
! ~ ++ -- (unary -) * & sizeof |
|
* / % |
|
+ - |
|
<< >> |
|
< <= > >= |
|
== != |
|
& |
|
^ |
|
| |
|
&& |
|
|| |
|
?: |
|
| Lowest | = += -= etc. |
When in doubt, use parentheses — they're clearer for the reader and they override precedence exactly the way you intend.
Control Statements
If-Else
if (a > b) {
printf("A is greater");
} else if (a == b) {
printf("Equal");
} else {
printf("B is greater");
}
Switch
Switch works only on integer types (including char). It's cleaner than a long if-else chain when you're comparing one variable against many specific values. Always remember break — without it, execution "falls through" to the next case, which is sometimes intentional but usually a bug.
switch (day) {
case 1: printf("Monday"); break;
case 2: printf("Tuesday"); break;
default: printf("Other day");
}
Loops
/* For loop: use when you know the count in advance */
for (i = 0; i < 5; i++) {
printf("%d ", i);
}
/* While loop: use when the condition depends on runtime input */
while (n > 0) {
printf("%d ", n % 10);
n = n / 10;
}
/* Do-while: guarantees at least one execution */
do {
printf("Enter positive number: ");
scanf("%d", &n);
} while (n <= 0);
break exits the nearest loop or switch immediately. continue skips the rest of the current iteration and jumps to the next one. Both only affect one level — if you're in a nested loop, break exits the inner loop but not the outer one.
Functions
A function is a named, reusable block of code. Every C program has at least one — main — but breaking your code into smaller named functions is what makes programs readable and testable.
/* Function prototype — tells the compiler this function exists before it's defined */
int add(int a, int b);
int main() {
int result = add(5, 3);
printf("Sum: %d", result);
return 0;
}
/* Function definition */
int add(int a, int b) {
return a + b;
}
Call by Value vs. Call by Reference
This is one of the most commonly tested topics in the exam, and the distinction matters because it determines whether a function can actually modify the caller's variables.
| Aspect | Call by Value | Call by Reference |
|---|---|---|
| What's passed | A copy of the variable | The memory address of the variable |
| Effect on original | No effect — the function sees its own copy | Function can modify the original |
| How it works in C | Default behavior | Pass a pointer, dereference inside the function |
| Example | swap(a, b) → doesn't swap the originals |
swap(&a, &b) → actually swaps |
/* Call by value — original is unchanged */
void trySwap(int a, int b) {
int temp = a; a = b; b = temp; /* swaps the local copies only */
}
/* Call by reference — original changes */
void realSwap(int *a, int *b) {
int temp = *a; *a = *b; *b = temp;
}
Arrays
An array is a contiguous block of memory holding multiple values of the same type. The index always starts at 0, so an array declared as int arr[5] has valid indices 0 through 4.
1D Arrays
int arr[5] = {10, 20, 30, 40, 50};
/* Traversal */
for (i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
2D Arrays and Matrix Operations
int a[2][3] = {{1,2,3},{4,5,6}};
/* Matrix addition */
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
sum[i][j] = a[i][j] + b[i][j];
}
}
/* Matrix transpose */
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
transpose[j][i] = matrix[i][j];
}
}
Array Name is a Pointer
This is something a lot of students miss: the array name arr is actually the address of the first element, equivalent to &arr[0]. So arr[i] and *(arr + i) are exactly the same thing in C. This is how arrays and pointers are connected, which sets up the next section.
Pointers — The Most Important Topic
Pointers are where C separates itself from almost every other language students encounter first, and they're consistently the highest-weighted topic in TU exams. They deserve serious time.
What Is a Pointer?
Every variable in your program is stored somewhere in RAM, at a specific address. When your program runs int a = 10;, the operating system allocates 4 bytes of memory at some address — say, 1000 — and stores the value 10 there. A pointer is simply a variable that holds a memory address instead of a data value.
int a = 10; /* a holds the value 10, stored at some address */
int *p = &a; /* p holds the ADDRESS of a. The & operator gives you an address. */
printf("%d", a); /* prints 10 — the value */
printf("%p", p); /* prints the address, something like 0x7fff5894 */
printf("%d", *p); /* prints 10 — dereferencing: go to that address and read the value */
The * in a declaration (int *p) means "p is a pointer to int." The * in an expression (*p) means "go to the address stored in p and read/write the value there." These are the same symbol doing two different things depending on context — a common source of early confusion.
Pointer Arithmetic
You can add and subtract integers from pointers, but the result depends on the pointer's type:
int arr[] = {10, 20, 30};
int *p = arr; /* p points to arr[0] */
p++; /* p now points to arr[1] — moved forward by sizeof(int) = 4 bytes */
printf("%d", *p); /* prints 20 */
Adding 1 to an int * doesn't just add 1 to the raw address — it adds sizeof(int) bytes (usually 4), moving to the next integer-sized slot. This is how arrays and pointers work together: iterating through an array by incrementing a pointer is functionally identical to using an index.
Pointer to a Function (Call by Reference Revisited)
void increment(int *p) {
(*p)++; /* dereference p, then increment the value at that address */
}
int main() {
int x = 5;
increment(&x); /* pass x's address */
printf("%d", x); /* prints 6 — the original was actually modified */
return 0;
}
Without the pointer, increment(x) would get a copy of 5, increment the copy, and throw it away — x would still be 5. With the pointer, you're working directly on the original.
Pointer and Array Relationship
Since an array name evaluates to the address of its first element:
int arr[] = {1, 2, 3, 4, 5};
int *p = arr; /* NOT &arr — arr already gives the address */
/* These are identical: */
printf("%d", arr[2]); /* index notation */
printf("%d", *(p + 2)); /* pointer arithmetic notation */
This is why C functions that accept arrays actually receive a pointer — you can't "pass" an array in C the way you pass a simple variable. What gets passed is the address of the first element, and the function works from there.
Dynamic Memory Allocation
So far every array or variable you've declared has its size fixed at compile time — int arr[100] always reserves 100 integers whether you use 5 or 100. Dynamic memory allocation lets you request memory at runtime, exactly the amount you actually need.
#include <stdio.h>
#include <stdlib.h> /* malloc, calloc, realloc, free are in stdlib.h */
int main() {
int n;
printf("How many numbers? "); scanf("%d", &n);
int *arr = (int*) malloc(n * sizeof(int)); /* request n integers worth of memory */
if (arr == NULL) {
printf("Memory allocation failed");
return 1;
}
for (int i = 0; i < n; i++) scanf("%d", &arr[i]);
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
free(arr); /* always release dynamically allocated memory when done */
return 0;
}
| Function | Purpose |
|---|---|
malloc(size) |
Allocates size bytes, returns void pointer (contents uninitialized) |
calloc(n, size) |
Allocates n elements of size bytes each, initializes to zero |
realloc(ptr, new_size) |
Resizes a previously allocated block |
free(ptr) |
Releases dynamically allocated memory back to the OS |
Every malloc/calloc must be paired with exactly one free. Forgetting free causes a memory leak — the program keeps consuming RAM without releasing it, which matters for long-running programs.
Common Pointer Mistakes
Uninitialized pointer: int *p; followed immediately by *p = 5; is undefined behavior — p holds a garbage address, and you're writing to some unknown location in memory. Always initialize: int *p = NULL; or int *p = &someVariable;.
Null pointer dereference: Trying to read or write through a NULL pointer causes a crash (segmentation fault). Always check if (p != NULL) before dereferencing a pointer that might be null.
Dangling pointer: If you take the address of a local variable inside a function and return that pointer, the memory it pointed to is freed when the function exits — the returned pointer is now pointing at garbage.
/* Wrong — returns address of a local variable that no longer exists */
int* dangerousFunction() {
int local = 42;
return &local; /* Don't do this */
}
Structures and Unions
A structure groups variables of different types under one name. A union also groups variables, but all members share the same memory location — only one can hold a valid value at a time.
/* Structure */
struct Student {
int id;
char name[50];
float marks;
};
struct Student s1;
s1.id = 101;
Structure vs. Union
| Aspect | Structure | Union |
|---|---|---|
| Memory | Each member gets its own memory | All members share the same memory |
| Size | Sum of all members' sizes (+ padding) | Size of the largest member |
| Active members | All members can hold values simultaneously | Only one member holds a valid value at a time |
| Use case | Grouping related but independent data | Memory-efficient storage where only one value is needed at a time |
Unit 1: Problem Solving with Computer — Algorithms and Flowcharts
The course starts here, not with code, and that's deliberate. Before you write a single line of C you're expected to know how to break a problem into steps that a computer can follow — that skill is called algorithmic thinking, and it's what separates programmers who can solve new problems from those who can only copy existing solutions.
An algorithm is a finite, step-by-step procedure for solving a problem. It must have a definite start and end, and each step must be unambiguous. A flowchart is the same algorithm drawn visually using standard symbols: a rounded rectangle for start/end, a parallelogram for input/output, a rectangle for processing steps, and a diamond for decisions.
The standard symbols:
| Symbol | Shape | Used For |
|---|---|---|
| Terminal | Oval / Rounded rectangle | Start and End |
| Process | Rectangle | Calculations, assignments |
| Input/Output | Parallelogram | scanf, printf |
| Decision | Diamond | if, while conditions |
| Flow lines | Arrows | Direction of execution |
Before writing any program in the exam, sketching the algorithm or flowchart as a first step is good practice — it organises your thinking and gives you partial marks even if your final code has a small error.
The compilation pipeline is also tested here: you write source code (.c file) → the compiler translates it to object code → the linker combines object files and libraries into an executable → you run and test it → debugging fixes errors found during testing. Understanding this pipeline explains why "my code compiles but crashes" and "my code gives wrong output" are two different kinds of problems requiring different approaches.
Unit 10: File Handling in C
Everything you've written so far disappears when the program ends. File handling is how you make data persist — reading from and writing to files stored on disk rather than only working with in-memory variables.
#include <stdio.h>
int main() {
FILE *fp; /* FILE is a special type defined in stdio.h */
fp = fopen("data.txt", "w"); /* open for writing — creates file if it doesn't exist */
if (fp == NULL) {
printf("Error opening file");
return 1;
}
fprintf(fp, "Hello, file!\n"); /* write to file like printf, but with fp first */
fclose(fp); /* always close when done */
return 0;
}
File Opening Modes
| Mode | Meaning |
|---|---|
"r" |
Read only — file must already exist |
"w" |
Write — creates file or overwrites if it exists |
"a" |
Append — writes at the end, preserving existing content |
"r+" |
Read and write — file must exist |
"w+" |
Read and write — creates or overwrites |
"a+" |
Read and append |
Key File Functions
| Function | Purpose |
|---|---|
fopen() |
Opens a file, returns a FILE pointer (NULL on failure) |
fclose() |
Closes a file and flushes any buffered output |
fprintf() |
Writes formatted data to a file (like printf to a file) |
fscanf() |
Reads formatted data from a file (like scanf from a file) |
fgetc() / fputc() |
Read/write one character at a time |
fgets() / fputs() |
Read/write one line at a time |
fseek() |
Move the file position pointer (for random access) |
ftell() |
Returns current position in the file |
rewind() |
Moves position back to start of file |
feof() |
Returns true when end of file is reached |
ferror() |
Returns true if a file error occurred |
Reading a File Character by Character
FILE *fp = fopen("data.txt", "r");
char ch;
while ((ch = fgetc(fp)) != EOF) {
printf("%c", ch);
}
fclose(fp);
EOF (End Of File) is a special value returned by fgetc and similar functions when there's nothing more to read. Checking for it is the standard way to read a file of unknown length.
Storing and Reading Student Records (Common Exam Question)
#include <stdio.h>
struct Student {
char name[50];
int roll;
float marks;
};
int main() {
FILE *fp;
struct Student s;
/* Write a record */
fp = fopen("students.txt", "w");
printf("Name: "); scanf("%s", s.name);
printf("Roll: "); scanf("%d", &s.roll);
printf("Marks: "); scanf("%f", &s.marks);
fprintf(fp, "%s %d %.2f\n", s.name, s.roll, s.marks);
fclose(fp);
/* Read it back */
fp = fopen("students.txt", "r");
while (fscanf(fp, "%s %d %f", s.name, &s.roll, &s.marks) != EOF) {
printf("%-20s %4d %6.2f\n", s.name, s.roll, s.marks);
}
fclose(fp);
return 0;
}
The single most important habit with file handling: always check whether fopen() returned NULL before doing anything else with the file pointer, and always call fclose() when you're done. Missing either is a common source of data loss and crashes.
Unit 11: Introduction to Graphics in C
The graphics unit covers Turbo C / BGI (Borland Graphics Interface) graphics functions — graphics.h based programming that lets you draw shapes and lines in a graphical window. This is mostly an introductory exposure; the real-world significance is that it shows students how a program can control pixels rather than just printing text.
#include <graphics.h>
#include <conio.h>
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\TC\\BGI"); /* initialize graphics mode */
circle(200, 200, 100); /* draws circle at center (200,200) with radius 100 */
line(0, 0, 640, 480); /* draws line from top-left to bottom-right */
rectangle(100, 100, 300, 300); /* draws rectangle */
setcolor(RED); /* change drawing color */
outtextxy(150, 400, "Hello Graphics!"); /* output text at position */
getch();
closegraph(); /* always close graphics mode before exit */
return 0;
}
Important Graphics Functions
| Function | What It Does |
|---|---|
initgraph(&gd, &gm, path) |
Initializes the graphics system |
closegraph() |
Closes graphics mode and returns to text mode |
circle(x, y, r) |
Draws circle at center (x,y) with radius r |
line(x1, y1, x2, y2) |
Draws line between two points |
rectangle(x1, y1, x2, y2) |
Draws rectangle with given corners |
ellipse(x, y, sa, ea, rx, ry) |
Draws ellipse arc |
arc(x, y, sa, ea, r) |
Draws arc |
floodfill(x, y, border) |
Fills a bounded region with current fill color |
setcolor(color) |
Sets the current drawing color |
setbkcolor(color) |
Sets the background color |
getmaxx() / getmaxy() |
Returns maximum x/y screen coordinate |
outtextxy(x, y, str) |
Outputs text at screen position |
cleardevice() |
Clears the graphics screen |
The exam rarely goes deep on graphics — short notes, the initgraph/closegraph pair, and two or three drawing function examples are the most you should expect in a theory question, though the lab requires actually running and testing a graphics program.
Solved Programs
These cover the patterns that appear most consistently on TU exam papers. Study the logic of each one, not just the code.
1. Prime Number Check
#include <stdio.h>
int main() {
int n, i, flag = 0;
printf("Enter number: ");
scanf("%d", &n);
if (n <= 1) { printf("Not prime"); return 0; }
for (i = 2; i <= n / 2; i++) {
if (n % i == 0) { flag = 1; break; }
}
printf(flag == 0 ? "Prime" : "Not prime");
return 0;
}
2. Fibonacci Series
#include <stdio.h>
int main() {
int n, a = 0, b = 1, c, i;
printf("How many terms? "); scanf("%d", &n);
printf("%d %d ", a, b);
for (i = 3; i <= n; i++) {
c = a + b;
printf("%d ", c);
a = b; b = c;
}
return 0;
}
3. Factorial (Recursive)
#include <stdio.h>
int factorial(int n) {
if (n == 0 || n == 1) return 1;
return n * factorial(n - 1);
}
int main() {
int n;
printf("Enter n: "); scanf("%d", &n);
printf("%d! = %d", n, factorial(n));
return 0;
}
4. Palindrome Check
#include <stdio.h>
int main() {
int n, rev = 0, orig, rem;
printf("Enter number: "); scanf("%d", &n);
orig = n;
while (n != 0) {
rem = n % 10;
rev = rev * 10 + rem;
n /= 10;
}
printf(orig == rev ? "Palindrome" : "Not palindrome");
return 0;
}
5. Swap Two Numbers Using Pointers
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
printf("Before: x=%d y=%d\n", x, y);
swap(&x, &y);
printf("After: x=%d y=%d\n", x, y);
return 0;
}
6. Matrix Addition
#include <stdio.h>
int main() {
int a[3][3], b[3][3], sum[3][3], i, j;
/* Input a and b, then: */
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
sum[i][j] = a[i][j] + b[i][j];
/* Print sum */
return 0;
}
7. Matrix Transpose
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
transpose[j][i] = matrix[i][j];
8. Bubble Sort
for (i = 0; i < n - 1; i++) {
for (j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
9. Find Largest Element in Array
int max = arr[0];
for (i = 1; i < n; i++)
if (arr[i] > max) max = arr[i];
printf("Largest: %d", max);
10. Linear Search
int found = -1;
for (i = 0; i < n; i++) {
if (arr[i] == target) { found = i; break; }
}
printf(found == -1 ? "Not found" : "Found at index %d", found);
11. String Reverse Without Library Function
char str[100], rev[100];
int len = 0;
while (str[len] != '\0') len++;
for (i = 0; i < len; i++) rev[i] = str[len - 1 - i];
rev[len] = '\0';
12. Count Vowels in a String
int count = 0;
for (i = 0; str[i] != '\0'; i++) {
char c = tolower(str[i]);
if (c=='a'||c=='e'||c=='i'||c=='o'||c=='u') count++;
}
13. Sum and Average of Array Elements
int sum = 0;
for (i = 0; i < n; i++) sum += arr[i];
printf("Sum: %d, Average: %.2f", sum, (float)sum / n);
14. Power of a Number (Using Loop)
int base, exp, result = 1;
for (i = 0; i < exp; i++) result *= base;
printf("%d^%d = %d", base, exp, result);
15. Student Structure with Marks Calculation
#include <stdio.h>
struct Student {
char name[50];
int marks[5];
float avg;
};
int main() {
struct Student s;
int sum = 0;
scanf("%s", s.name);
for (int i = 0; i < 5; i++) {
scanf("%d", &s.marks[i]);
sum += s.marks[i];
}
s.avg = sum / 5.0;
printf("%s: %.2f", s.name, s.avg);
return 0;
}
Exam Pattern Analysis
CSC115 has 11 units across 45 teaching hours, but marks are not evenly distributed. Pointers (Unit 9, 6 hrs) and Arrays (Unit 6, 6 hrs) come up almost every year — usually one theory question (explain pointer arithmetic, explain array memory representation) and one practical program (swap using pointers, matrix transpose). Functions (Unit 7) appear in both theory (call by value vs. reference, scope of variables) and practical (recursive factorial, Fibonacci) forms. File Handling (Unit 10) is consistently underestimated by students but appears as a reliable 2–3 mark short question or a mid-length write-a-program question.
Unit 1 (algorithms and flowcharts) almost always appears as an early short question — draw a flowchart for X, or write an algorithm for Y — and it's very quick marks if you know the standard symbols. Problem Solving and Elements of C (Units 1–2) together take only 6 teaching hours but set up everything else, so don't skip them.
Short questions cover definitions and comparisons (pointer vs. array, structure vs. union, call by value vs. call by reference, file modes). Long questions almost always require writing a complete working program — comments showing your understanding of each step help when the code itself has a minor error, since TU examiners often award partial marks for correct logic even with small syntax slips.
30-Day Study Plan
- Days 1–3: Units 1–3 — problem solving, algorithms and flowcharts, C program structure, data types, I/O with scanf/printf
- Days 4–6: Unit 4 — all operator types, precedence table, expression evaluation
- Days 7–9: Unit 5 — if/else/switch, all three loop types, break/continue, nested loops
- Days 10–14: Unit 6 — 1D and 2D arrays, matrix operations, strings and string library functions
- Days 15–19: Unit 7 — user-defined functions, recursion, call by value vs. reference, scope and lifetime of variables
- Days 20–22: Unit 8 — structures, unions, nested structures, pointer to structure
- Days 23–27: Unit 9 — full pointer coverage: arithmetic, arrays and pointers, pointers to functions, dynamic memory allocation
- Days 28–29: Unit 10 — file handling: fopen/fclose modes, fprintf/fscanf, reading/writing records
- Day 30: Unit 11 graphics overview + write 10 programs from memory, review all comparison tables
Last-Night Revision Sheet
Must-remember syntax:
- Every statement ends with
; scanf()needs&before the variable name (except for string arrays)- Array index starts at 0
*preads/writes the value at address p;&agives the address of areturn 0;at the end of main signals successful completion
Five highest-priority topics for the exam:
- Pointers (swap using pointer, pointer arithmetic)
- Loops (all three types, nested loops for patterns)
- Functions (recursive factorial, recursive Fibonacci)
- Arrays (matrix addition, bubble sort, largest element)
- Structures (definition, accessing members with
.)
Three mistakes that cost the most marks:
- Using
=instead of==in a condition - Forgetting
&inscanf("%d", &n) - Returning address of a local variable from a function
Common Mistakes to Avoid
The = vs == bug catches nearly every student at least once — if (a = 5) assigns 5 to a and is always true, while if (a == 5) actually checks the condition. The missing & in scanf is the other classic: scanf("%d", n) instead of scanf("%d", &n) silently reads into a garbage address instead of the variable you meant. Infinite loops usually happen when the loop's termination condition is wrong or the update step is missing — always trace through a small example by hand before trusting that a loop is correct. With pointers specifically, the biggest mistake is using an uninitialized pointer without assigning it to a valid address first.
Comparison Tables
Pre-defined vs. User-Defined Functions
| Aspect | Pre-defined (Library) Function | User-Defined Function |
|---|---|---|
| Definition | Already written in C standard library | Written by the programmer |
| Header needed | Yes (e.g., #include <math.h>) |
No header needed (just declare/define) |
| Examples | printf, scanf, sqrt, strlen |
Any function you write yourself |
while vs do-while
| Aspect | while | do-while |
|---|---|---|
| Check condition | Before first execution | After first execution |
| Minimum executions | 0 (may never run) | 1 (always runs at least once) |
Array vs. Pointer
| Aspect | Array | Pointer |
|---|---|---|
| Memory allocation | Fixed at compile time | Can point anywhere |
| Name behavior | Array name is a constant pointer | Pointer variable can be reassigned |
| Initialization | int arr[5] = {1,2,3,4,5}; |
int *p = arr; |
Frequently Asked Questions (FAQs)
Is C Programming difficult for BSc CSIT students?
The concepts themselves aren't especially hard, but C has less tolerance for mistakes than most languages — a missing semicolon or misplaced & causes an error the compiler won't always explain clearly. The learning curve is steeper early on but flattens quickly once you've written a few dozen programs.
Which topic carries the most marks in the C Programming exam? Pointers, functions, and loops tend to be heaviest based on consistent past paper patterns. Pointers alone often appear in both theory and practical sections.
Do I need to memorize code, or understand it? Understanding. You'll rarely get exactly the same program you've seen before. The exam expects you to take a concept (recursion, pointer arithmetic, array traversal) and apply it to a slightly different problem. Students who memorize outputs without understanding logic struggle with new variations.
What's the best way to practice programming for the exam? Close your notes and write programs from scratch. Even if you've read the bubble sort ten times, actually typing it out will immediately reveal which parts you don't actually remember. Aim to write each exam-relevant program from memory at least twice.
Why does my program compile but give wrong output?
Almost always a logic error — a wrong loop condition, an off-by-one index, or a missing update step. Add printf statements at key points to print intermediate values and trace through the logic. This is called "print debugging" and it's the most useful debugging skill for exam-level programs.
How is recursion different from using a loop? A recursive function calls itself to break a problem into smaller subproblems, stopping at a base case. A loop iterates through steps explicitly. Both can solve the same problems in most cases, but recursion is often more elegant for problems that have a naturally recursive structure, like tree traversal or factorial calculation.
What does "segmentation fault" mean? It means your program tried to access memory it's not allowed to — usually caused by a null or uninitialized pointer being dereferenced, or an array being accessed out of bounds.
Is the lab component easy? The lab usually involves writing and running programs on a computer, which is more forgiving than the written exam because you can actually test whether your code works. Students who've been writing programs regularly throughout the semester find the lab significantly easier than those who only revise on paper.
What's the difference between ++i and i++?
Both add 1 to i, but ++i (pre-increment) applies the increment before using the value in an expression, while i++ (post-increment) uses the current value first, then increments. In a simple loop like for(i=0; i<n; i++), the difference doesn't matter. In expressions like a = i++ vs a = ++i, it does.
Can I use void as the return type of main()?
Technically the C standard requires int main(), not void main(). Some compilers accept void main() without complaint, but it's non-standard and should be avoided in exam answers — always use int main() and return 0;.
Conclusion
C rewards the work you put in. The students who score highest on the practical and theory components of this exam aren't necessarily the smartest in the room — they're the ones who sat down and actually wrote programs. Pointers will feel confusing for a while and then suddenly click. K-maps in Digital Logic felt the same way for most students. The click happens faster if you stop rereading explanations and start making your own code run.
Use this guide to understand the concepts, then close it and write the programs yourself. That's the prep that actually shows up in the exam.
For related subjects, you may also find useful: BSc CSIT Mathematics-I (MTH117) Complete Guide, Introduction to Information Technology (CSC114) Complete Guide, Digital Logic (CSC116) Complete Guide, and Physics (PHY118) Complete Guide.
0 Comments