আমরা C প্রোগ্রামিংয়ের দীর্ঘ এই যাত্রার শেষ পর্বে এসে পৌঁছেছি। গত তিন পর্বে আমরা ভিত্তি থেকে শুরু করে লিংকড লিস্ট পর্যন্ত পথচলা করেছি।
আজকের পর্বটি একটু ভিন্ন। আমরা কেবল নতুন জিনিস শিখব না, বরং আগের সব জ্ঞানকে এক সুতোয় গেঁথে ফেলব। আমরা শিখব স্ট্যাক ও কিউ—যা সফটওয়্যার ইঞ্জিনিয়ারিংয়ের প্রাণ। শিখব সর্টিং ও সার্চিং, যা ডেটাকে সুশৃঙ্খল করে। আর শেষ করব একটি পেশাদার মানের প্রোজেক্ট দিয়ে, যা আপনার পোর্টফোলিওতে রাখার মতো। চলুন, শেষ এই অধ্যায়টি জয় করি! 🏆
🔄 পর্ব-৩ এর সংক্ষিপ্ত পুনরালোচনা
- বিটওয়াইজ অপারেটর (
&,|,<<) দিয়ে দ্রুত পারমিশন চেক করা। - ফাংশন পয়েন্টার দিয়ে কলব্যাক মেকানিজম।
- সিঙ্গলি লিংকড লিস্ট তৈরি, ইনসার্ট, ডিলিট।
- মাল্টি-ফাইল প্রোগ্রামিং (Header File) এবং ‘লাইব্রেরি ম্যানেজমেন্ট’ প্রোজেক্ট।
আজ আমরা সেই লিংকড লিস্টকে আরও শক্তিশালী করব এবং অ্যালগরিদমের জগতে পা রাখব।
🥞 অধ্যায় ১৮: স্ট্যাক (Stack) – LIFO (Last In, First Out)
স্ট্যাক একটি বিশেষ ধরনের ডেটা স্ট্রাকচার। এটাকে প্লেটের স্ট্যাকের মতো ভাবুন—যে প্লেটটি সবশেষে রাখা হয়, সেটিই প্রথমে উঠানো হয় (LIFO)।
স্ট্যাকের প্রধান দুটি অপারেশন:
- Push: উপরে নতুন এলিমেন্ট যোগ করা।
- Pop: উপরের এলিমেন্টটি বের করে আনা।
নিচে অ্যারে-ভিত্তিক স্ট্যাক (সরল ও দ্রুত) এর উদাহরণ দেওয়া হলো:
c
#include <stdio.h>
#define MAX 100
int stack[MAX];
int top = -1; // খালি স্ট্যাক বোঝায়
// Push অপারেশন
void push(int value) {
if (top >= MAX - 1) {
printf("❌ স্ট্যাক ওভারফ্লো! (স্ট্যাক ভর্তি)\n");
return;
}
stack[++top] = value;
printf("✅ %d Push করা হয়েছে।\n", value);
}
// Pop অপারেশন
int pop() {
if (top < 0) {
printf("❌ স্ট্যাক আন্ডারফ্লো! (স্ট্যাক খালি)\n");
return -1;
}
return stack[top--];
}
// স্ট্যাকের শীর্ষ দেখা (Peek)
int peek() {
if (top < 0) return -1;
return stack[top];
}
int main() {
push(10);
push(20);
push(30);
printf("পপ করা মান: %d\n", pop()); // আউটপুট: 30
printf("বর্তমান শীর্ষ: %d\n", peek()); // আউটপুট: 20
return 0;
}
💡 বাস্তব ব্যবহার: ব্রাউজারের ‘ব্যাক’ বোতাম, ফাংশন কলের মেমোরি ম্যানেজমেন্ট (কল স্ট্যাক), এবং রিকারশনের ভিত্তি হলো এই স্ট্যাক।
🚶 অধ্যায় ১৯: কিউ (Queue) – FIFO (First In, First Out)
কিউ হলো স্ট্যাকের ঠিক উল্টো। এটি টিকিট কাউন্টারের লাইনের মতো—যে আগে আসে, সে আগে সার্ভিস পায় (FIFO)।
কিউর প্রধান দুটি অপারেশন:
- Enqueue: পেছনে (Rear) যোগ করা।
- Dequeue: সামনে (Front) থেকে বের করা।
নিচে সার্কুলার অ্যারে-ভিত্তিক কিউ (মেমোরি অপটিমাইজড) এর উদাহরণ:
c
#include <stdio.h>
#define MAX 5
int queue[MAX];
int front = -1, rear = -1;
// Enqueue (যোগ)
void enqueue(int value) {
if ((rear + 1) % MAX == front) {
printf("❌ কিউ ভর্তি!\n");
return;
}
if (front == -1) front = 0; // প্রথম এলিমেন্ট
rear = (rear + 1) % MAX;
queue[rear] = value;
printf("✅ %d যোগ হয়েছে।\n", value);
}
// Dequeue (বের করা)
int dequeue() {
if (front == -1) {
printf("❌ কিউ খালি!\n");
return -1;
}
int data = queue[front];
if (front == rear) { // শেষ এলিমেন্ট বের করলে রিসেট
front = rear = -1;
} else {
front = (front + 1) % MAX;
}
return data;
}
int main() {
enqueue(5);
enqueue(10);
enqueue(15);
printf("Dequeue: %d\n", dequeue()); // আউটপুট: 5
printf("Dequeue: %d\n", dequeue()); // আউটপুট: 10
return 0;
}
💡 বাস্তব ব্যবহার: প্রিন্টারের জব লিস্ট, সিপিইউ টাস্ক শিডিউলিং, ওয়েব সার্ভারের রিকুয়েস্ট হ্যান্ডলিং।
🔗 অধ্যায় ২০: ডাবলি লিংকড লিস্ট (Doubly Linked List)
সিঙ্গলি লিংকড লিস্টে আমরা শুধু সামনের দিকে যেতে পারতাম। কিন্তু ডাবলি লিংকড লিস্টে প্রতিটি নোডে দুটি পয়েন্টার থাকে—একটি পরের নোডের জন্য (next), অন্যটি আগের নোডের জন্য (prev)। ফলে আমরা সামনে ও পেছনে—উভয় দিকেই ট্রাভার্স করতে পারি।
c
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* prev;
struct Node* next;
};
// সামনে থেকে ইনসার্ট
void insertFront(struct Node** head, int data) {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = *head;
if (*head != NULL) (*head)->prev = newNode;
*head = newNode;
}
// লিস্ট প্রিন্ট (সামনে থেকে পেছনে)
void displayForward(struct Node* head) {
struct Node* temp = head;
printf("সামনে -> পেছনে: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
insertFront(&head, 30);
insertFront(&head, 20);
insertFront(&head, 10);
displayForward(head); // আউটপুট: 10 20 30
return 0;
}
কেন প্রয়োজন? ব্রাউজারের হিস্ট্রি (পেছানো/সামানো) বা মিউজিক প্লেয়ারের প্লেলিস্টে এটি ব্যবহার হয়।
📊 অধ্যায় ২১: সার্চিং ও সর্টিং অ্যালগরিদম
২১.১ বাইনারি সার্চ (Binary Search)
এটি শুধু সর্টেড অ্যারেতে কাজ করে। প্রতি ধাপে এটি অ্যারেকে অর্ধেক ভাগ করে ফেলে। ফলে অনুসন্ধান অত্যন্ত দ্রুত হয়।
c
int binarySearch(int arr[], int size, int target) {
int left = 0, right = size - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
২১.২ বাবল সর্ট (Bubble Sort)
এটি সবচেয়ে সহজ সর্টিং অ্যালগরিদম। এটি পাশাপাশি এলিমেন্ট তুলনা করে এবং ভুল ক্রমে থাকলে সোয়াপ করে। যদিও এটি বড় ডেটার জন্য ধীর, তবে বোঝার জন্য দারুণ।
c
void bubbleSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// সোয়াপ
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
🛡️ অধ্যায় ২২: স্পেশাল কিওয়ার্ড – const ও volatile (পেশাদারদের টুল)
const: এটি ভেরিয়েবলকে রিড-ওনলি করে দেয়। আপনি চাইলে ফাংশন প্যারামিটারেconstব্যবহার করে নিশ্চিত করতে পারেন যে ফাংশনটি সেই ভেরিয়েবলের মান পরিবর্তন করবে না।cvoid printValue(const int *ptr) { // *ptr = 10; // এই লাইনটি কম্পাইল হবে না (এরর) printf(“%d”, *ptr); }volatile: এটি কম্পাইলারকে বলে যে, এই ভেরিয়েবলের মান যেকোনো সময় বাইরে থেকে (হার্ডওয়্যার বা অন্য থ্রেড) পরিবর্তন হতে পারে। তাই কম্পাইলার এটিকে অপটিমাইজ করবে না। এটি এমবেডেড সিস্টেম ও মাল্টিথ্রেডিং-এ অপরিহার্য।
🏢 অধ্যায় ২৩: গ্র্যান্ড প্রোজেক্ট – ‘এমপ্লয়ি পেল রোল ম্যানেজমেন্ট সিস্টেম’
এখন আমরা একটি বড় প্রোজেক্ট তৈরি করব, যেখানে থাকবে:
- স্ট্যাক (সর্বশেষ যোগ করা কর্মচারীকে দেখানো)।
- কিউ (কর্মচারীদের তালিকা ব্রাউজ করা)।
- লিংকড লিস্ট (সমস্ত কর্মচারী সংরক্ষণ)।
- ফাইল হ্যান্ডলিং (ডেটা সেভ)।
- সর্টিং (বেতন অনুযায়ী সাজানো)।
কোডটি মডুলার করার জন্য আমরা তিনটি ফাইল তৈরি করব (ধারণাগতভাবে দেখানো হলো):
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Employee {
int id;
char name[50];
float salary;
struct Employee* next;
};
// ১. লিংকড লিস্টে যোগ
void addEmployee(struct Employee** head, int id, char name[], float salary) {
struct Employee* emp = (struct Employee*) malloc(sizeof(struct Employee));
emp->id = id; strcpy(emp->name, name); emp->salary = salary; emp->next = NULL;
if (*head == NULL) { *head = emp; return; }
struct Employee* temp = *head;
while (temp->next != NULL) temp = temp->next;
temp->next = emp;
}
// ২. সর্টিং (বাবল সর্ট - লিংকড লিস্টের জন্য অ্যারে নিয়ে কাজ করা সহজ)
void sortBySalary(struct Employee* head) {
if (head == NULL) return;
int count = 0;
struct Employee* temp = head;
while (temp) { count++; temp = temp->next; }
// অ্যারেতে কপি করে সর্ট
float *salaries = (float*) malloc(count * sizeof(float));
temp = head; int i = 0;
while (temp) { salaries[i++] = temp->salary; temp = temp->next; }
// বাবল সর্ট
for (int i = 0; i < count-1; i++)
for (int j = 0; j < count-i-1; j++)
if (salaries[j] > salaries[j+1]) {
float s = salaries[j]; salaries[j] = salaries[j+1]; salaries[j+1] = s;
}
printf("✅ সর্টেড বেতনের তালিকা: ");
for (int i = 0; i < count; i++) printf("%.2f ", salaries[i]);
printf("\n");
free(salaries);
}
// ৩. ফাইলে সেভ
void saveToFile(struct Employee* head) {
FILE* f = fopen("employees.txt", "w");
struct Employee* temp = head;
while (temp) {
fprintf(f, "%d|%s|%.2f\n", temp->id, temp->name, temp->salary);
temp = temp->next;
}
fclose(f);
printf("💾 ফাইলে সেভ হয়েছে!\n");
}
// ৪. স্ট্যাক (শেষ ৩ জন দেখানো)
void showLastThree(struct Employee* head) {
// স্ট্যাকের মতো LIFO নীতিতে শেষ ৩ জন দেখানো
int count = 0;
struct Employee* temp = head;
while (temp) { count++; temp = temp->next; }
if (count < 3) { printf("মোট কর্মচারী ৩ এর কম!\n"); return; }
temp = head;
int skip = count - 3;
for (int i = 0; i < skip; i++) temp = temp->next;
printf("🆕 সবশেষ যোগ দেওয়া ৩ জন (Stack LIFO):\n");
while (temp) {
printf("ID: %d, নাম: %s, বেতন: %.2f\n", temp->id, temp->name, temp->salary);
temp = temp->next;
}
}
int main() {
struct Employee* head = NULL;
int choice, id;
char name[50];
float salary;
while (1) {
printf("\n🏢 **এমপ্লয়ি ম্যানেজমেন্ট সিস্টেম**\n");
printf("1. কর্মচারী যোগ করুন\n");
printf("2. বেতন অনুযায়ী সাজান (Sort)\n");
printf("3. শেষ ৩ জন দেখুন (Stack)\n");
printf("4. সেভ ও প্রস্থান\n");
printf("পছন্দ: "); scanf("%d", &choice); getchar();
if (choice == 1) {
printf("আইডি: "); scanf("%d", &id); getchar();
printf("নাম: "); gets(name);
printf("বেতন: "); scanf("%f", &salary);
addEmployee(&head, id, name, salary);
} else if (choice == 2) {
sortBySalary(head);
} else if (choice == 3) {
showLastThree(head);
} else if (choice == 4) {
saveToFile(head);
printf("👋 প্রস্থান করছি।\n");
break;
}
}
return 0;
}
🏁 পুরো সিরিজের উপসংহার ও পরবর্তী করণীয়
অভিনন্দন! আপনি “C Programming A to Z” -এর এই চার পর্বের বিশাল জার্নি সফলভাবে শেষ করেছেন।
আপনি এখন যা জানেন:
- C-এর সিনট্যাক্স ও বুনিয়াদি।
- পয়েন্টার, মেমোরি ম্যানেজমেন্ট ও ডায়নামিক ডেটা স্ট্রাকচার (লিংকড লিস্ট, স্ট্যাক, কিউ)।
- ফাইল হ্যান্ডলিং, প্রিপ্রসেসর, এবং মাল্টি-ফাইল প্রোগ্রামিং।
- বেসিক অ্যালগরিদম (সার্চ ও সর্ট)।
আপনি এখন C প্রোগ্রামার। কিন্তু এখানেই থেমে যাবেন না।
পরবর্তী পথচলা:
১. ডেটা স্ট্রাকচার আরও গভীরে: ট্রি (Binary Tree), গ্রাফ, হ্যাশ টেবল।
২. অ্যালগরিদম ডিজাইন: মার্জ সর্ট, কুইক সর্ট, ডায়নামিক প্রোগ্রামিং।
৩. সিস্টেম প্রোগ্রামিং: Linux-এ Socket Programming, Multithreading with Pthreads।
C হলো আপনার প্রোগ্রামিং জীবনের সবচেয়ে মূল্যবান বিনিয়োগ। এটি শিখলে অন্য যেকোনো ভাষা (জাভা, পাইথন, C++) শিখতে আপনার সময় লাগবে অর্ধেকেরও কম।
ToLearnTeam-এর পক্ষ থেকে আপনার উজ্জ্বল ভবিষ্যতের জন্য শুভকামনা। কোড লিখতে থাকুন, নতুন কিছু তৈরি করতে থাকুন। পৃথিবী আপনার জন্য অপেক্ষা করছে!
Full Advanced Course in C
- C Programming A to Z: শূন্য থেকে বিশেষজ্ঞ হওয়ার সম্পূর্ণ গাইড
- C Programming A to Z (পর্ব-২): মেমোরি, ম্যাক্রো ও রিয়েল-লাইফ প্রোজেক্ট
- C Programming A to Z (পর্ব-৩): ডেটা স্ট্রাকচার, বিটওয়াইজ ম্যাজিক ও মাল্টি-ফাইল প্রোজেক্ট
- C Programming A to Z (পর্ব-৪): অ্যালগরিদম, স্ট্যাক, কিউ ও গ্র্যান্ড ফাইনাল প্রোজেক্ট
- C Programming A to Z (বোনাস পর্ব-৫): প্রো টুলচেইন, বাইনারি ফাইল ও ডিবাগিং ম্যাজিক
- C Programming A to Z (পর্ব-৬): ট্রি, গ্রাফ, বিগ-ও নোটেশন ও ক্যাপস্টোন প্রোজেক্ট
- C Programming A to Z (পর্ব-৭): মাল্টিথ্রেডিং, সকেট নেটওয়ার্কিং ও প্রো বিল্ড সিস্টেম
- C Programming A to Z (পর্ব-৮): প্রোফাইলিং, সিকিউরিটি, কন্ডিশন ভেরিয়েবল ও প্রোডাকশন লগার
