সরাসরি পর্বে যান
পর্ব ৩৯ · ৫৫-এর মধ্যে · মডিউল ৬

C প্রোগ্রামিং — ভ্যারিয়েবল, শর্ত আর লুপ

C Programming Basics — Variables, Data Types, Operators, Decisions and Loops

Taught in Bangla, this lesson introduces C programming: program structure with #include and main(), data types, variables, printf and scanf, operators including the integer-division trap and type casting, decisions with if, else-if, switch and the ternary operator, and for, while and do-while loops. It works through classic exam programs such as factorial, Fibonacci and prime checks, plus reading compiler errors.

এই পর্বে যা শিখবেন

  • C প্রোগ্রামের গঠন — #include, main(), statement, comment, keyword আর identifier-এর নিয়ম
  • ডেটা টাইপ (int, float, double, char), format specifier, ভ্যারিয়েবল, কনস্ট্যান্ট আর printf-scanf
  • অপারেটর — integer ভাগের ফাঁদ, %, && || !, i++ বনাম ++i, type casting
  • if, else-if ladder, nested if, switch-case, ?: আর for, while, do-while, break, continue, nested loop
  • HSC আর চাকরির পরীক্ষার ক্লাসিক প্রোগ্রাম হাতে লেখা, dry-run করা আর compiler-এর error পড়া

১ · C কী, আর এত বছর পরেও কেন C

পর্ব ৩৮-এ দেখেছেন, প্রোগ্রাম হলো কম্পিউটারের জন্য ধাপে ধাপে লেখা নির্দেশ, আর অ্যালগরিদম ও ফ্লোচার্ট দিয়ে সেই ধাপগুলো আগে কাগজে সাজানো হয়। এবার সেই ধাপগুলো একটি আসল প্রোগ্রামিং ভাষায় লেখার পালা। HSC ICT-র পঞ্চম অধ্যায়ে সেই ভাষা হলো C.

C একটি high-level language — মানুষ পড়তে পারে এমন শব্দ (if, while, return) দিয়ে লেখা হয়। কিন্তু অন্য অনেক high-level ভাষার চেয়ে C মেশিনের অনেক কাছাকাছি থাকে। C-র একটি লাইন প্রায়ই CPU-র কয়েকটি মাত্র নির্দেশে বদলে যায়। তাই C-তে লেখা প্রোগ্রাম ছোট হয়, দ্রুত চলে, আর খুব কম মেমরিতেও চলতে পারে।

⚡ ছোট আর দ্রুত

C-র মূল ভাষা খুব ছোট — হাতে গোনা কিছু keyword. বাড়তি কোনো স্তর নেই, তাই প্রোগ্রাম সরাসরি মেশিনের ভাষায় অনুবাদ হয়ে দ্রুত চলে।

compiled language

🖥️ সবখানে C

Linux kernel, Windows আর macOS-এর ভেতরের অনেক অংশ, রাউটার, গাড়ির যন্ত্রাংশ, মাইক্রোওয়েভের চিপ — যেখানে গতি আর কম মেমরি দরকার, সেখানে C.

OS · embedded

🧱 অন্য ভাষার ভিত

C++, Java, C#, JavaScript-এর if, for, { } আর ; — সবই C থেকে নেওয়া। C শিখলে এসব ভাষার অর্ধেক লেখা চেনা লাগে।

C-family syntax

জন্মকথা: ১৯৬৯ সালে যুক্তরাষ্ট্রের Bell Labs-এ Ken Thompson একটি নতুন অপারেটিং সিস্টেম Unix লেখা শুরু করেন — assembly ভাষায়। Thompson আগে B নামে একটি ছোট ভাষা বানিয়েছিলেন। তাঁর সহকর্মী Dennis Ritchie B-কে বদলে ডেটা টাইপ যোগ করেন, আর নতুন ভাষার নাম দেন C. ভাষাটির জন্মসাল হিসেবে সাধারণত ১৯৭২ ধরা হয়। ১৯৭৩ সালে Unix-এর বেশিরভাগ অংশ C-তে নতুন করে লেখা হয় — অপারেটিং সিস্টেমের মতো বড় কাজ high-level ভাষায় লেখার প্রথম দিকের সফল উদাহরণ। ১৯৭৮ সালে Brian Kernighan আর Ritchie-র বই “The C Programming Language” প্রকাশিত হয়, যা আজও “K&R” নামে পরিচিত।

কোথায় লিখবেন, কীভাবে চালাবেন

C প্রোগ্রাম চালাতে লাগে একটি compiler — যে পুরো source code পড়ে মেশিনের ভাষার একটি চালানো যায় এমন ফাইল (Windows-এ .exe) বানায়। পর্ব ২৩-এ দেখেছেন, আপনার লেখা কোড কীভাবে স্তরে স্তরে নেমে ট্রানজিস্টর পর্যন্ত পৌঁছায়; আর পর্ব ৩৮-এ compiler আর interpreter-এর পার্থক্য। শুরু করার তিনটি সহজ পথ:

  • অনলাইন compiler (যেমন OnlineGDB, Programiz) — কিছু install না করে ব্রাউজারেই লিখে চালান। মোবাইলেও চলে।
  • Code::Blocks — Windows-এর জন্য compiler-সহ (MinGW) সংস্করণ নামালে সব একসাথে পাবেন। এ ধরনের লেখা, compile আর চালানোর সব কাজ এক জায়গায় দেয় এমন সফটওয়্যারকে বলে IDE.
  • VS Code — হালকা editor; সাথে আলাদা করে gcc compiler আর C extension বসাতে হয়।
gcc main.c -o main     # main.c থেকে main নামের প্রোগ্রাম বানাও
./main                 # প্রোগ্রামটি চালাও (Windows-এ: main.exe)

রান্নার রেসিপি আর রাঁধুনি: source code হলো খাতায় লেখা রেসিপি। compiler একজন অনুবাদক, যে পুরো রেসিপি একবারে পড়ে রাঁধুনির ভাষায় একটি পরিষ্কার নির্দেশপত্র বানিয়ে দেয়। রেসিপিতে বানান ভুল থাকলে অনুবাদক কাজ শুরুই করবে না — এটাই compile error. আর অনুবাদ ঠিক হলেও রেসিপিতে লবণ বেশি লেখা থাকলে রান্না খারাপ হবে — এটা logical error, যা compiler ধরতে পারে না।

২ · C প্রোগ্রামের গঠন — #include, main আর সেমিকোলন

প্রথম প্রোগ্রাম, যেভাবে পরীক্ষার খাতায় লেখা হয়:

/* My first C program */
#include <stdio.h>

int main()
{
    printf("Hello, Bangladesh!\n");   // পর্দায় লেখা দেখাও
    return 0;
}
প্রত্যাশিত আউটপুট:
Hello, Bangladesh!

প্রতিটি লাইনের কাজ আলাদা:

অংশকী করে
/* ... */, // ...Comment — মানুষের জন্য নোট; compiler পুরোপুরি বাদ দেয়। /* */ কয়েক লাইন জুড়ে, // শুধু লাইনের বাকিটুকু।
#include <stdio.h>Preprocessor directive — compile শুরুর আগেই header file stdio.h (standard input-output) জুড়ে দেয়, যেখানে printf আর scanf-এর পরিচয় লেখা।
int main()main function — প্রোগ্রাম এখান থেকেই শুরু হয়। প্রতিটি C প্রোগ্রামে ঠিক একটি main থাকে।
{ }বাঁকা বন্ধনী — main-এর শরীরের শুরু আর শেষ। ভেতরের সব নির্দেশ main-এর অংশ।
printf(...);একটি statement — একটি পূর্ণ নির্দেশ। প্রতিটি statement-এর শেষে ; বাধ্যতামূলক, বাংলা বাক্যের দাঁড়ির মতো।
return 0;main শেষ; অপারেটিং সিস্টেমকে জানায় “সব ঠিকঠাক শেষ হয়েছে” (0 মানে সফল)।

কিছু বইয়ে void main() বা #include <conio.h> আর getch() দেখবেন — পুরোনো Turbo C-র অভ্যাস। Standard C-তে main-এর ধরন int, আর conio.h সব compiler-এ নেই। নিরাপদ পথ: int main() আর শেষে return 0;.

Keyword আর identifier — নাম রাখার নিয়ম

Keyword হলো C-র নিজের সংরক্ষিত শব্দ — int, float, if, else, for, while, return ইত্যাদি। মূল ANSI C-তে keyword ছিল ৩২টি; পরের সংস্করণগুলোতে আরও কয়েকটি যোগ হয়েছে। এগুলো অন্য কোনো কাজে নাম হিসেবে ব্যবহার করা যায় না।

ভ্যারিয়েবল বা ফাংশনের জন্য আপনি যে নাম দেন, তা identifier. নিয়মগুলো পরীক্ষায় প্রায়ই আসে:

  • অক্ষর (A–Z, a–z), অঙ্ক (0–9) আর underscore (_) ছাড়া কিছু চলবে না — space, -, @, . নিষেধ।
  • প্রথম অক্ষর অঙ্ক হতে পারবে না: roll2 বৈধ, 2roll অবৈধ।
  • keyword নাম হবে না: float অবৈধ, Float বৈধ (কারণ C বড়-ছোট হাতের অক্ষর আলাদা ধরে — marks আর Marks দুটি আলাদা নাম)।
  • অর্থপূর্ণ নাম দিন: x-এর চেয়ে total_marks অনেক বেশি বোঝায়।

৩ · ডেটা টাইপ, ভ্যারিয়েবল আর printf-scanf

Variable হলো মেমরির (RAM) একটি নাম দেওয়া ঘর, যেখানে একটি মান রাখা যায় আর পরে বদলানো যায়। C-তে প্রতিটি ঘরের একটি নির্দিষ্ট data type থাকে — ঘরে কী ধরনের মান থাকবে আর ঘরটি কত বড় হবে, তা আগে বলে দিতে হয়।

রান্নাঘরের পাত্র: চাল রাখার জন্য ড্রাম, তেলের জন্য বোতল, লবণের জন্য ছোট কৌটা। পাত্রের গায়ে লেবেল (নাম) লাগানো, আর পাত্রের ধরন ঠিক করে কী রাখা যাবে। বোতলে চাল ঢালতে গেলে সমস্যা। C-তে int marks; লেখা মানে: “marks নামের একটি পূর্ণসংখ্যার পাত্র দাও।”

টাইপকী রাখেসাধারণ আকারformat specifierউদাহরণ
intপূর্ণসংখ্যা৪ বাইট (পুরোনো Turbo C-তে ২)%dint roll = 25;
floatদশমিক সংখ্যা (প্রায় ৬–৭ অঙ্ক নির্ভুল)৪ বাইট%ffloat gpa = 4.75;
doubleবড়/বেশি নির্ভুল দশমিক (প্রায় ১৫ অঙ্ক)৮ বাইট%lfdouble pi = 3.14159265;
charএকটি অক্ষর (আসলে তার ASCII নম্বর)১ বাইট%cchar grade = 'A';

৪ বাইট int-এ রাখা যায় প্রায় −২১৪ কোটি থেকে +২১৪ কোটি পর্যন্ত। char-এ 'A' লিখলে ভেতরে জমা হয় তার ASCII নম্বর 65 (পর্ব ১৮)। খেয়াল করুন, অক্ষরের জন্য একক উদ্ধৃতি 'A', আর লেখার (string) জন্য দ্বৈত উদ্ধৃতি "Hello".

ভ্যারিয়েবল ঘোষণা আর কনস্ট্যান্ট

int a, b, sum;          // তিনটি int ঘর, এখনো মান দেওয়া হয়নি
int count = 0;          // ঘোষণার সাথেই প্রাথমিক মান
float price = 12.50;
#define PI 3.1416       // প্রোগ্রামজুড়ে PI মানে 3.1416
const int MAX = 100;    // MAX-এর মান আর বদলানো যাবে না

যে মান প্রোগ্রাম চলার সময় বদলায় না, তা constant. দুইভাবে বানানো যায়: #define PI 3.1416 — preprocessor compile-এর আগেই প্রতিটি PI-র জায়গায় 3.1416 বসিয়ে দেয় (শেষে ; বা = নেই)। আর const int MAX = 100; — একটি ভ্যারিয়েবল, যার মান বদলাতে গেলে compiler error দেয়। একটি জরুরি সতর্কতা: মান না দিয়ে ঘোষণা করা ভ্যারিয়েবলে (যেমন উপরের sum) আগে থেকে যা খুশি আবর্জনা মান থাকতে পারে — যোগফলের ঘর সবসময় 0 দিয়ে শুরু করুন।

printf — পর্দায় লেখা

printf-এর প্রথম অংশ উদ্ধৃতির ভেতরের লেখা; তার ভেতরে %d, %f-এর মতো চিহ্ন হলো format specifier — “এখানে একটি মান বসবে, এই ধরনের।” মানগুলো দেওয়া হয় কমা দিয়ে, একই ক্রমে।

int roll = 25;
float gpa = 4.75;
char grade = 'A';
printf("Roll: %d\tGPA: %.2f\tGrade: %c\n", roll, gpa, grade);
প্রত্যাশিত আউটপুট:
Roll: 25	GPA: 4.75	Grade: A

%.2f মানে দশমিকের পরে ঠিক দুই ঘর। শুধু %f দিলে ছয় ঘর আসত: 4.750000. আর \n, \t হলো escape sequence — উল্টো দাগ (\) দিয়ে শুরু হওয়া বিশেষ চিহ্ন, যা টাইপ করা যায় না এমন কাজ বোঝায়:

লিখুনফল
\nনতুন লাইন (new line)
\ttab — কয়েক ঘর ফাঁকা, কলাম সাজাতে
\\একটি \ চিহ্ন
\"লেখার ভেতরে একটি "
%%printf-এ একটি % চিহ্ন (এটি escape sequence নয়, printf-এর নিজের নিয়ম)

scanf — কীবোর্ড থেকে পড়া, আর & চিহ্নের রহস্য

scanf ব্যবহারকারীর টাইপ করা মান পড়ে ভ্যারিয়েবলে রাখে। লক্ষ করুন ভ্যারিয়েবলের নামের আগে &:

#include <stdio.h>

int main()
{
    int a, b, sum;
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    sum = a + b;
    printf("Sum = %d\n", sum);
    return 0;
}
নমুনা রান:
Enter two numbers: 15 27
Sum = 42

& হলো address-of operator. &a মানে “a ঘরটি মেমরির কোন ঠিকানায় আছে।” printf-কে শুধু মান দিলেই চলে — সে পড়ে দেখাবে। কিন্তু scanf-কে মান লিখতে হবে, তাই তার দরকার ঘরের ঠিকানা। কুরিয়ার সার্ভিসের মতো: পার্সেল পাঠাতে চাইলে প্রাপকের নাম বললে হবে না, ঠিকানা দিতে হবে। & ভুলে গেলে প্রোগ্রাম ভুল জায়গায় লিখতে চেষ্টা করে, আর প্রায়ই হঠাৎ বন্ধ (crash) হয়ে যায়।

একই ধাঁচে বৃত্তের ক্ষেত্রফল — #define আর float-সহ:

#include <stdio.h>
#define PI 3.1416

int main()
{
    float r, area;
    printf("Enter radius: ");
    scanf("%f", &r);
    area = PI * r * r;
    printf("Area = %.2f\n", area);
    return 0;
}
নমুনা রান:
Enter radius: 5
Area = 78.54
মূল ধারণা

printf আর scanf-এ format specifier আর ভ্যারিয়েবলের টাইপ মিলতেই হবে: int → %d, float → %f, char → %c, double → scanf-এ %lf. না মিললে compiler হয়তো শুধু warning দেবে, কিন্তু আউটপুট হবে আবোলতাবোল।

৪ · অপারেটর — হিসাব, তুলনা আর যুক্তি

গাণিতিক অপারেটর আর integer ভাগের ফাঁদ

Arithmetic operator পাঁচটি: + - * / %. প্রথম তিনটি স্কুলের মতোই। ঝামেলা ভাগে। দুটি int ভাগ করলে ফলও int হয় — দশমিকের পরের অংশ কেটে ফেলা হয়, পূর্ণসংখ্যায় রাউন্ড করা হয় না। একে বলে integer division. তাই 7 / 2 = 3, 3.5 নয়; আর 2 / 3 = 0. ভাগশেষ পেতে modulus operator %: 7 % 2 = 1. % শুধু পূর্ণসংখ্যায় চলে।

% পরীক্ষার প্রোগ্রামে সবচেয়ে কাজের অপারেটর: n % 2 == 0 মানে জোড় সংখ্যা; n % 10 দেয় শেষ অঙ্ক (1234 % 10 = 4); n / 10 শেষ অঙ্ক ফেলে দেয় (1234 / 10 = 123). মৌলিক সংখ্যা, অঙ্কের যোগফল, উল্টো সংখ্যা — সবই এই দুই কৌশলে।

তুলনা আর যুক্তি

ধরনঅপারেটরউদাহরণ (a = 7, b = 2)ফল
Relational> < >= <=a >= 71 (সত্য)
== !=a == b0 (মিথ্যা)
Logical&& (AND — দুটিই সত্য)a > 5 && b > 50
|| (OR — অন্তত একটি)a > 5 || b > 51
! (NOT — উল্টো)!(a == b)1

C-তে আলাদা “সত্য-মিথ্যা” টাইপ ছাড়াই কাজ চলে: 0 মানে মিথ্যা, শূন্য ছাড়া যেকোনো মান সত্য। তুলনার ফল হয় 1 বা 0. এই লজিক্যাল অপারেটরগুলো পর্ব ১৯-২০-এর AND, OR, NOT গেটেরই প্রোগ্রামের রূপ। আর = (মান বসানো) আর == (সমান কি না দেখা) সম্পূর্ণ আলাদা — এই পার্থক্য অংশ ৮-এ আবার আসবে।

Assignment, compound আর ++ / −−

= হলো assignment operator: ডানের মান হিসাব করে বাঁয়ের ঘরে রাখে। sum = sum + i; গণিতে অসম্ভব, কিন্তু C-তে মানে “sum-এর পুরোনো মানের সাথে i যোগ করে আবার sum-এ রাখো।” সংক্ষেপে লেখা যায় sum += i; — একইভাবে -=, *=, /=, %=.

এক বাড়ানো বা কমানো এত বেশি লাগে যে আলাদা increment/decrement operator আছে: i++ বা ++i মানে i = i + 1. একা লিখলে দুটি একই। পার্থক্য তখনই, যখন একই লাইনে মানটি ব্যবহারও হয়:

int i = 5, a, b;
a = i++;    // আগে ব্যবহার, পরে বাড়ানো: a = 5, তারপর i = 6
b = ++i;    // আগে বাড়ানো, পরে ব্যবহার: i = 7, তারপর b = 7
printf("%d %d %d\n", a, b, i);
প্রত্যাশিত আউটপুট:
5 7 7

এড়িয়ে চলুন: একই statement-এ একই ভ্যারিয়েবলকে দুবার বদলানো — যেমন i = i++ + ++i; বা printf("%d %d", i++, i++);. C standard এর ফল নির্দিষ্ট করেনি; একেক compiler একেক উত্তর দিতে পারে। কোনো প্রশ্নে এমন কোড দেখলে সঠিক উত্তর হলো “undefined behaviour” — অনুমান করা একটি সংখ্যা নয়।

অগ্রাধিকার (precedence)

একটি expression-এ অনেক অপারেটর থাকলে কোনটি আগে, তা ঠিক করে operator precedence — অনেকটা গণিতের BODMAS-এর মতো। মোটা দাগে ক্রম: () → ++ -- ! → * / % → + - → < > <= >= → == != → && → || → = += .... তাই 2 + 3 * 4 = 14, আর 10 - 4 / 2 = 8. সন্দেহ হলে বন্ধনী দিন — বন্ধনী কোডকে পরিষ্কারও করে।

Type conversion — int আর float মিশলে

একটি অপারেশনে int আর float মিশলে C নিজে থেকেই int-কে float বানিয়ে হিসাব করে: 7 / 2.0 = 3.5. কিন্তু দুটিই int হলে আগে int ভাগ হয়, তারপর ফল float ঘরে রাখলেও হারানো .5 আর ফেরে না। সমাধান type casting — বন্ধনীতে টাইপ লিখে নিজে রূপান্তর করা: (float)a / b. নিচের ধাপগুলোতে মেমরির ভেতরে কী ঘটে দেখুন:

1int a = 7, b = 2;2float c = a / b;3printf("%f\n", c);4c = (float)a / b;5printf("%f\n", c);
মেমরির ঘর
a (int, ৪ বাইট)
b (int, ৪ বাইট)
মাঝের হিসাব
c (float, ৪ বাইট)
  1. দুটি int ঘর। a-তে 7, b-তে 2. দুটিই পূর্ণসংখ্যার ঘর — ভগ্নাংশ রাখার কোনো জায়গা নেই।
  2. আগে ডান দিক। =-এর ডান দিক আগে হিসাব হয়: a / b. দুটিই int, তাই integer division — 3.5 নয়, 3. বাঁয়ের ঘরটি float কি না, ডান দিকের হিসাব তা জানেই না।
  3. দেরিতে রূপান্তর। 3 এবার float ঘরে ঢুকে 3.0 হলো। কিন্তু .5 তো আগেই হারিয়ে গেছে — আউটপুট 3.000000. এটাই পরীক্ষার সবচেয়ে প্রিয় ফাঁদ।
  4. Cast আগে। (float)a ভাগের আগেই a-র একটি float কপি (7.0) বানায়; a নিজে বদলায় না। এখন float ÷ int, তাই C b-কেও 2.0 বানিয়ে float ভাগ করে: 3.5.
  5. সঠিক উত্তর। 3.500000. মনে রাখুন: (float)(a / b) লিখলে আবার 3.0 আসবে — কারণ বন্ধনীর ভেতরের int ভাগ আগে হয়ে যায়। Cast বসাতে হয় ভাগের আগে।

৫ · সিদ্ধান্ত — if, else-if, switch আর ?:

প্রোগ্রাম সবসময় সোজা লাইনে চলে না। পর্ব ৩৮-এর ফ্লোচার্টে যেটি হীরার আকারের সিদ্ধান্ত-বাক্স, C-তে সেটি if-else. বন্ধনীতে শর্ত; সত্য হলে প্রথম block, মিথ্যা হলে else-এর block.

#include <stdio.h>

int main()
{
    int n;
    printf("Enter a number: ");
    scanf("%d", &n);
    if (n % 2 == 0)
        printf("%d is even\n", n);
    else
        printf("%d is odd\n", n);
    return 0;
}
নমুনা রান:
Enter a number: 17
17 is odd

else-if ladder — অনেকগুলো পথ, একটিই বেছে নেওয়া

দুইয়ের বেশি পথ থাকলে একের পর এক শর্ত সাজানো হয় — একে বলে else-if ladder (মইয়ের মতো ধাপে ধাপে)। ওপর থেকে শর্ত দেখা হয়; প্রথম যে শর্ত সত্য, শুধু সেটির কাজ চলে, বাকি সব বাদ। এর সেরা উদাহরণ SSC-HSC-র গ্রেডিং:

নম্বর৮০–১০০৭০–৭৯৬০–৬৯৫০–৫৯৪০–৪৯৩৩–৩৯০–৩২
গ্রেডA+AA-BCDF
পয়েন্ট5.004.003.503.002.001.000.00
#include <stdio.h>

int main()
{
    int marks;
    printf("Enter marks: ");
    scanf("%d", &marks);
    printf("%d\n", marks);

    if (marks < 0 || marks > 100) printf("Invalid marks\n");
    else if (marks >= 80) printf("Grade: A+ (GP 5.00)\n");
    else if (marks >= 70) printf("Grade: A  (GP 4.00)\n");
    else if (marks >= 60) printf("Grade: A- (GP 3.50)\n");
    else if (marks >= 50) printf("Grade: B  (GP 3.00)\n");
    else if (marks >= 40) printf("Grade: C  (GP 2.00)\n");
    else if (marks >= 33) printf("Grade: D  (GP 1.00)\n");
    else printf("Grade: F  (GP 0.00)\n");

    return 0;
}

ইনপুট হিসেবে আগে থেকে 72 দেওয়া আছে, তাই আউটপুট Grade: A (GP 4.00). ইনপুটের পরের printf("%d\n", marks) লাইনটি শুধু অনলাইনে চালালে আপনার দেওয়া সংখ্যাটি দেখানোর জন্য — খাতায় লিখতে হবে না। লক্ষ করুন, marks >= 70 লেখার সময় “&& marks < 80” লিখতে হয়নি: ৮০ বা তার বেশি হলে আগের ধাপেই ধরা পড়ত, তাই এই ধাপে পৌঁছানো মানেই নম্বর ৮০-র কম। শর্তের ক্রম উল্টে দিলে (আগে >= 33) সবাই D পাবে — নিজে বদলে চালিয়ে দেখুন। প্রথম লাইনের || শর্তটি ভুল ইনপুট (−৫ বা ১২০) ধরে।

1scanf → marks = 722if (marks < 0 || marks > 100)3else if (marks >= 80)4else if (marks >= 70)  → "A"5else if (marks >= 60)6else if ... (50, 40, 33)7else → "F"
শর্ত পরীক্ষা
marks
এখন দেখা হচ্ছে
ফল
  1. ইনপুট। scanf ব্যবহারকারীর টাইপ করা 72 পড়ে marks ঘরে রাখে।
  2. প্রথম ধাপ — ভুল ইনপুট? 72 < 0 মিথ্যা, 72 > 100-ও মিথ্যা। OR-এর দুই দিকই মিথ্যা, তাই পুরো শর্ত মিথ্যা — পরের else-এ নামুন।
  3. ৮০ বা বেশি? না। এই ধাপও বাদ।
  4. ৭০ বা বেশি? হ্যাঁ — প্রথম সত্য শর্ত। এর printf চলে: Grade: A.
  5. বাকিগুলো আর দেখাই হয় না। 72 তো ৬০-এর বেশিও, ৩৩-এর বেশিও — কিন্তু ladder-এ একটি শর্ত সত্য হলেই বাকি সব else বাদ পড়ে। প্রোগ্রাম সোজা return 0;-এ চলে যায়। আলাদা আলাদা if লিখলে (else ছাড়া) 72-এর জন্য A, A-, B, C, D সব ছাপা হতো!

Nested if — শর্তের ভেতরে শর্ত

একটি if-এর ভেতরে আরেকটি if থাকলে তা nested if. এর ভালো উদাহরণ তিনটি সংখ্যার মধ্যে বড়টি বের করা (লিপ ইয়ারও nested if দিয়ে লেখা যায়, তবে অংশ ৭-এ সেটি && আর || দিয়ে দেখবেন):

if (a > b) {
    if (a > c) printf("Largest = %d\n", a);
    else       printf("Largest = %d\n", c);
} else {
    if (b > c) printf("Largest = %d\n", b);
    else       printf("Largest = %d\n", c);
}

প্রতিটি if আর else-এর পরে বাঁকা বন্ধনী দেওয়ার অভ্যাস করুন। বন্ধনী না দিলে if-এর অধীনে থাকে শুধু ঠিক পরের একটি statement — দ্বিতীয় লাইনটি ভেতরে মনে হলেও আসলে সবসময় চলে।

switch-case — একটি মানের অনেক সম্ভাবনা

একটি ভ্যারিয়েবলের মান 1, 2, 3 … এমন নির্দিষ্ট মানের কোনটি, তা দেখতে switch সবচেয়ে পরিষ্কার। USSD মেনু (*247# চাপলে যে তালিকা আসে) ঠিক এমন: “1 চাপলে Send Money, 2 চাপলে Cash Out …”.

int day;
scanf("%d", &day);
switch (day) {
    case 1: printf("Saturday\n");  break;
    case 2: printf("Sunday\n");    break;
    case 3: printf("Monday\n");    break;
    case 4: printf("Tuesday\n");   break;
    case 5: printf("Wednesday\n"); break;
    case 6: printf("Thursday\n");  break;
    case 7: printf("Friday\n");    break;
    default: printf("Invalid day\n");
}
নমুনা রান:
7
Friday

প্রতিটি case-এর শেষে break বলে “কাজ শেষ, switch থেকে বেরোও”। break ভুলে গেলে মিলে যাওয়া case থেকে নিচের সব case-এর কাজও একে একে চলে — একে বলে fall-through. ধরুন case 6-এ break নেই, আর day = 6: আউটপুট আসবে Thursday, তারপর Friday. মিল না পেলে চলে default. switch-এর case-এ শুধু পূর্ণসংখ্যা বা অক্ষরের (char) নির্দিষ্ট মান বসে — case marks >= 80: বা float মান চলে না। তাই গ্রেডিংয়ের মতো পরিসরের (range) কাজে else-if ladder-ই ঠিক।

Conditional operator ?: — এক লাইনের if-else

ছোট সিদ্ধান্তের জন্য conditional operator: শর্ত ? মান১ : মান২. শর্ত সত্য হলে মান১, নইলে মান২. যেমন max = (a > b) ? a : b; — দুটির বড়টি max-এ। C-র একমাত্র অপারেটর যে তিনটি অংশ নেয়, তাই একে ternary operator-ও বলে।

৬ · লুপ — for, while আর do-while

১ থেকে ১০০ পর্যন্ত যোগ করতে ১০০টি লাইন কেউ লেখে না। একই কাজ বারবার করার নির্দেশের নাম loop. প্রতিটি লুপের তিনটি অংশ থাকে: শুরুর মান (initialization), চলতে থাকার শর্ত (condition), আর প্রতিবার বদল (update). এর যেকোনো একটি ভুল হলে লুপ হয় একবারও চলে না, নয়তো কখনো থামে না।

🔁 for

কতবার চলবে আগে থেকে জানা থাকলে। তিন অংশ এক লাইনে: for (i = 1; i <= 10; i++).

নামতা · যোগফল · factorial

⏳ while

শর্ত আগে দেখে, তারপর কাজ। কতবার চলবে আগে জানা না থাকলে — যেমন “সংখ্যা শূন্য না হওয়া পর্যন্ত”।

অঙ্ক আলাদা করা

🔂 do-while

কাজ আগে, শর্ত পরে — তাই শর্ত শুরু থেকেই মিথ্যা হলেও অন্তত একবার চলে। শেষে while (...);-এর সেমিকোলন খেয়াল করুন।

মেনু · ইনপুট যাচাই

একই কাজ — ১ থেকে n পর্যন্ত যোগ — তিন লুপে:

/* for */
for (i = 1; i <= n; i++)
    sum = sum + i;

/* while */
i = 1;
while (i <= n) {
    sum = sum + i;
    i++;
}

/* do-while */
i = 1;
do {
    sum = sum + i;
    i++;
} while (i <= n);

for loop-এ তিনটি অংশ এক জায়গায় থাকায় ভুল কম হয়। while loop-এ update (i++) ভেতরে নিজে লিখতে হয় — ভুলে গেলে i কখনো বাড়ে না, শর্ত চিরকাল সত্য, আর তৈরি হয় infinite loop. do-while loop-এর পার্থক্যটি নিচের ছোট পরীক্ষায় দেখুন — শর্ত শুরু থেকেই মিথ্যা:

1int i = 10;2while (i < 5) { printf("W%d\n", i); i++; }3do { printf("D%d\n", i); i++; } while (i < 5);
অবস্থা
i
কী ঘটল
শরীর কতবার চলল
  1. শুরু। i = 10, আর দুই লুপেরই শর্ত i < 5 — শুরু থেকেই মিথ্যা।
  2. while — দরজায় পাহারাদার। ঢোকার আগেই শর্ত দেখা হয়। মিথ্যা, তাই শরীর একবারও চলে না; কিছুই ছাপা হয় না। while-কে বলে entry-controlled loop.
  3. do-while — আগে কাজ, পরে প্রশ্ন। শরীর আগে চলে: D10 ছাপা হয়, i হয় 11. তারপর শর্ত দেখা হয় — মিথ্যা, তাই থামে। ফল: অন্তত একবার চলেছে। একে বলে exit-controlled loop. মেনু দেখানোর মতো কাজে এটিই দরকার — মেনু অন্তত একবার তো দেখাতেই হবে।

Dry-run: factorial-এর লুপ ধাপে ধাপে

৫! = ৫ × ৪ × ৩ × ২ × ১ = ১২০. প্রোগ্রামে গুণফল রাখার ঘর fact শুরু হয় 1 দিয়ে (যোগফল শুরু হয় 0 দিয়ে, গুণফল 1 দিয়ে — 0 দিলে সব গুণ 0 হয়ে যেত)। কাগজে একটি টেবিল বানিয়ে প্রতিটি ধাপে ভ্যারিয়েবলের মান লিখে যাওয়াকে বলে dry run — পরীক্ষার খাতায় আউটপুট বের করার সবচেয়ে নির্ভরযোগ্য পদ্ধতি:

1int i, n = 5, fact = 1;2for (i = 1; i <= n; i++)3    fact = fact * i;4printf("Factorial of %d = %d\n", n, fact);
dry-run টেবিল
i
i <= 5 ?
fact
  1. প্রস্তুতি। n = 5, fact = 1. i-তে এখনো কিছু বসানো হয়নি।
  2. i = 1. for-এর প্রথম অংশ একবারই চলে: i = 1. শর্ত 1 <= 5 সত্য, তাই fact = 1 × 1 = 1. তারপর i++.
  3. i = 2. 2 <= 5 সত্য → fact = 1 × 2 = 2.
  4. i = 3. fact = 2 × 3 = 6.
  5. i = 4. fact = 6 × 4 = 24.
  6. i = 5. 5 <= 5 — এখনো সত্য (<=, শুধু < নয়)। fact = 24 × 5 = 120. তারপর i++ করে i হয় 6.
  7. i = 6 — শর্ত মিথ্যা। লুপ থামে, printf চলে: Factorial of 5 = 120. খেয়াল করুন, লুপের পরে i-র মান 6, 5 নয় — “লুপ শেষে i কত?” এ ধরনের প্রশ্ন প্রায়ই আসে। শরীর চলেছে ৫ বার, কিন্তু শর্ত দেখা হয়েছে ৬ বার।

int-এ factorial বেশি দূর যায় না: ১২! = ৪৭,৯০,০১,৬০০ পর্যন্ত ঠিক আছে, কিন্তু ১৩! = ৬২২ কোটির বেশি — ৪ বাইট int-এর সীমা (প্রায় ২১৪ কোটি) পেরিয়ে যায়, আর উত্তর আসে ভুল, এমনকি ঋণাত্মক। পর্ব ১৭-এর overflow এখানে বাস্তবে দেখা দেয়। বড় factorial-এর জন্য long long আর %lld ব্যবহার করুন — তাতেও ২০! পর্যন্ত।

break, continue আর nested loop

লুপের মাঝপথে বেরিয়ে যেতে break (switch-এর মতোই), আর এই ঘুরের বাকিটা বাদ দিয়ে পরের ঘুরে যেতে continue. যেমন ১ থেকে ১০-এর মধ্যে ৩-এর গুণিতক বাদ দিয়ে ছাপা: if (i % 3 == 0) continue;. আর একটি লুপের ভেতরে আরেকটি লুপ — nested loop — বাইরেরটি প্রতিবার ঘুরলে ভেতরেরটি পুরোটা চলে, ঠিক ঘড়ির ঘণ্টা আর মিনিটের কাঁটার মতো। নকশা (pattern) ছাপার প্রশ্ন এভাবেই হয়:

int i, j;
for (i = 1; i <= 4; i++) {        // বাইরের লুপ: সারি
    for (j = 1; j <= i; j++)       // ভেতরের লুপ: i-সংখ্যক তারা
        printf("* ");
    printf("\n");
}
প্রত্যাশিত আউটপুট:
*
* *
* * *
* * * *

কৌশল: সারি নম্বর i হলে সেই সারিতে i-টি তারা। ভেতরের লুপের শর্ত j <= i বদলে j <= 5 - i করলে উল্টো ত্রিভুজ; তারার বদলে printf("%d ", j) দিলে 1, 1 2, 1 2 3 … সংখ্যার নকশা।

চালিয়ে দেখুন: নামতা, যোগফল আর মৌলিক সংখ্যা

#include <stdio.h>

int main()
{
    int i, n = 7, sum = 0, num = 29, isPrime = 1;

    for (i = 1; i <= 10; i++)
        printf("%d x %d = %d\n", n, i, n * i);

    for (i = 1; i <= 100; i++)
        sum = sum + i;
    printf("Sum of 1 to 100 = %d\n", sum);

    for (i = 2; i * i <= num; i++)
        if (num % i == 0) { isPrime = 0; break; }
    if (isPrime == 1) printf("%d is prime\n", num);
    else printf("%d is not prime\n", num);
    return 0;
}

তিনটি লুপ, তিনটি ক্লাসিক কাজ। প্রথমটি ৭-এর নামতা ছাপে (7 x 1 = 7 থেকে 7 x 10 = 70). দ্বিতীয়টি ১ থেকে ১০০-র যোগফল: 5050 — সূত্র n(n+1)/2 দিয়ে মিলিয়ে নিন। তৃতীয়টি মৌলিক সংখ্যা যাচাই: ২ থেকে শুরু করে কোনো সংখ্যা দিয়ে নিঃশেষে ভাগ গেলেই isPrime = 0 আর break — আর খোঁজার দরকার নেই। শর্ত i * i <= num কেন? কারণ ২৯-এর কোনো ভাজক থাকলে তার একটি অবশ্যই √২৯ (প্রায় ৫.৪)-এর সমান বা ছোট হতো — তাই শুধু ২, ৩, ৪, ৫ দেখলেই চলে। অনেক বইয়ে i <= num / 2 বা i < num লেখা থাকে; সেগুলোও সঠিক, শুধু বেশি ধাপ নেয়। num = 29-কে 91 করে চালান — 91 = 7 × 13, তাই উত্তর আসবে 91 is not prime. মনে রাখুন, 1 মৌলিক নয়; পূর্ণ প্রোগ্রামে আগে num < 2 পরীক্ষা করতে হয়।

৭ · পরীক্ষার ক্লাসিক প্রোগ্রাম — এক জায়গায়

বোর্ড পরীক্ষা, ভর্তি পরীক্ষা আর চাকরির লিখিত পরীক্ষায় কয়েকটি প্রোগ্রাম ঘুরেফিরে আসে। সবগুলোর পেছনে মাত্র কয়েকটি কৌশল: % দিয়ে ভাগ যায় কি না দেখা, % 10 আর / 10 দিয়ে অঙ্ক আলাদা করা, লুপে যোগফল (শুরু 0) আর গুণফল (শুরু 1) জমানো। আগের অংশগুলোতে যোগফল, বৃত্তের ক্ষেত্রফল, জোড়-বিজোড়, গ্রেড, factorial, নামতা, ১ থেকে n-এর যোগফল, মৌলিক সংখ্যা আর তারার নকশা দেখেছেন। বাকিগুলো এখানে।

তিনটি সংখ্যার মধ্যে বড়টি (&& দিয়ে)

#include <stdio.h>

int main()
{
    int a, b, c;
    printf("Enter three numbers: ");
    scanf("%d %d %d", &a, &b, &c);
    if (a >= b && a >= c)
        printf("Largest = %d\n", a);
    else if (b >= a && b >= c)
        printf("Largest = %d\n", b);
    else
        printf("Largest = %d\n", c);
    return 0;
}
নমুনা রান:
Enter three numbers: 12 45 30
Largest = 45

লিপ ইয়ার (অধিবর্ষ)

নিয়ম: ৪ দিয়ে ভাগ যায় কিন্তু ১০০ দিয়ে যায় না, অথবা ৪০০ দিয়ে ভাগ যায়। তাই ২০২৪ অধিবর্ষ, ১৯০০ নয়, ২০০০ অধিবর্ষ।

#include <stdio.h>

int main()
{
    int year;
    printf("Enter year: ");
    scanf("%d", &year);
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        printf("%d is a leap year\n", year);
    else
        printf("%d is not a leap year\n", year);
    return 0;
}
নমুনা রান (দুবার চালিয়ে):
Enter year: 2024
2024 is a leap year
Enter year: 1900
1900 is not a leap year

Fibonacci ধারা (প্রথম ১০টি পদ)

#include <stdio.h>

int main()
{
    int n = 10, a = 0, b = 1, next, i;
    for (i = 1; i <= n; i++) {
        printf("%d ", a);
        next = a + b;      // পরের পদ = আগের দুটির যোগফল
        a = b;
        b = next;
    }
    return 0;
}
প্রত্যাশিত আউটপুট:
0 1 1 2 3 5 8 13 21 34

কৌশলটি দুই হাতে দুটি সংখ্যা ধরে রাখার মতো: যোগ করে নতুনটি বানান, তারপর বাঁ হাতের সংখ্যা ফেলে দিয়ে সব এক ঘর এগিয়ে নিন। কিছু বই ধারাটি 1, 1, 2 … দিয়ে শুরু করে — প্রশ্নে যেভাবে চাওয়া, সেভাবে a আর b-র শুরুর মান দিন।

সংখ্যা উল্টানো আর অঙ্কের যোগফল (while লুপ)

#include <stdio.h>

int main()
{
    int n, digit, rev = 0, sum = 0;
    printf("Enter a number: ");
    scanf("%d", &n);
    while (n != 0) {
        digit = n % 10;            // শেষ অঙ্ক
        rev = rev * 10 + digit;    // উল্টো সংখ্যায় জোড়া
        sum = sum + digit;
        n = n / 10;                // শেষ অঙ্ক ফেলে দেওয়া
    }
    printf("Reverse = %d\n", rev);
    printf("Sum of digits = %d\n", sum);
    return 0;
}
নমুনা রান:
Enter a number: 1234
Reverse = 4321
Sum of digits = 10

এখানে while-ই স্বাভাবিক পছন্দ, কারণ সংখ্যায় কয়টি অঙ্ক তা আগে জানা নেই — “শূন্য না হওয়া পর্যন্ত” চলুক। dry-run: n = 1234 → digit 4, rev 4, n 123 → digit 3, rev 43, n 12 → digit 2, rev 432, n 1 → digit 1, rev 4321, n 0 → লুপ থামে। Palindrome (যেমন 121 উল্টালেও 121) যাচাইয়ের প্রশ্নও এই কোড থেকেই — শুধু শুরুর n একটি আলাদা ভ্যারিয়েবলে রেখে শেষে rev-এর সাথে মিলিয়ে দেখুন।

প্রোগ্রামমূল কৌশলকোথায় দেখবেন
দুটি সংখ্যার যোগফল, বৃত্তের ক্ষেত্রফলscanf-এ &, সঠিক format specifier, #define PIঅংশ ৩
জোড়-বিজোড়, গ্রেড, সপ্তাহের দিনn % 2 == 0, else-if ladder, switch + breakঅংশ ৫
বড়টি, লিপ ইয়ার&& আর || দিয়ে শর্ত জোড়াঅংশ ৫, ৭
১ থেকে n-এর যোগফল, factorial, নামতালুপে জমানো — যোগে শুরু 0, গুণে শুরু 1অংশ ৬
মৌলিক সংখ্যাভাজক খোঁজা, পেলে flag = 0 আর breakঅংশ ৬
Fibonacciদুটি আগের মান ধরে রেখে এগোনোঅংশ ৭
উল্টো সংখ্যা, অঙ্কের যোগফল, palindrome% 10 আর / 10, while লুপেঅংশ ৭
তারার নকশাnested loop: সারি i, তারা j <= iঅংশ ৬

৮ · সাধারণ ভুল আর compiler-এর error পড়া

ভুল তিন রকম। Syntax error — ভাষার ব্যাকরণ ভাঙা (সেমিকোলন নেই, বন্ধনী মেলেনি); compiler ধরে, প্রোগ্রাম তৈরিই হয় না। Runtime error — প্রোগ্রাম চলার সময় সমস্যা (শূন্য দিয়ে ভাগ, scanf-এ & নেই)। আর logical error — প্রোগ্রাম দিব্যি চলে, কিন্তু উত্তর ভুল (integer ভাগ, ভুল শর্ত)। শেষেরটিই সবচেয়ে বিপজ্জনক, কারণ কেউ সতর্ক করে না — dry-run আর জানা উত্তরের সাথে মিলিয়েই ধরতে হয়।

ভুলকী ঘটেঠিক রূপ
printf("Hi") — শেষে ; নেইSyntax error, প্রায়ই পরের লাইনের নম্বর দেখায়printf("Hi");
if (x = 5)তুলনা নয়, x-এ 5 বসায়; শর্ত সবসময় সত্যif (x == 5)
scanf("%d", n);ঠিকানার বদলে মান যায় — crash বা আবোলতাবোলscanf("%d", &n);
avg = total / 3; (total int)দশমিক অংশ হারায় — logical erroravg = total / 3.0;
for (i = 1; i <= 10; i++);শেষের ; লুপের শরীরকে খালি করে দেয়; নিচের লাইন একবার চলে; মুছে দিন
switch-এ break নেইনিচের case-গুলোও চলে (fall-through)প্রতিটি case-এর শেষে break;
int sum; তারপর সরাসরি যোগশুরুর আবর্জনা মানের সাথে যোগ হয়int sum = 0;

Compiler-এর বার্তা পড়তে শিখুন

gcc-র বার্তা প্রথমে ভয়ের মনে হয়, কিন্তু গঠন সবসময় এক: ফাইলের নাম : লাইন : কলাম : ধরন : বিবরণ. নিচে তিনটি সাধারণ বার্তা:

main.c:6:28: error: expected ';' before 'return'
main.c:5:11: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
main.c:7:13: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat=]
  • প্রথমটি (error): ৬ নম্বর লাইনের return-এর আগে ; চাই — অর্থাৎ আসল ভুল তার আগের লাইনের শেষে। compiler ভুলটি টের পায় পরের শব্দে গিয়ে।
  • দ্বিতীয়টি (warning): শর্তের ভেতরে assignment — প্রায় নিশ্চিত == লিখতে চেয়েছিলেন।
  • তৃতীয়টি: %d চায় int * (একটি ঠিকানা), পেয়েছে int — মানে scanf-এ & নেই।

দুটি অভ্যাস: সবসময় প্রথম error আগে ঠিক করুন — একটি ভুল থেকে পরে দশটি ভুয়া error আসতে পারে। আর warning-কে উপেক্ষা করবেন না; gcc-তে -Wall দিয়ে compile করলে ওপরের দ্বিতীয় আর তৃতীয় ভুল আগেই ধরা পড়ে।

পরীক্ষা ও ইন্টারভিউতে — এ ধরনের প্রশ্ন প্রায়ই আসে:

  • float-এর format specifier কোনটি? %f (int-এ %d, char-এ %c, double scanf-এ %lf).
  • printf("%d %d", 7/2, 7%2);-এর আউটপুট? 3 1 — integer ভাগে ভগ্নাংশ কাটা যায়, % দেয় ভাগশেষ।
  • while আর do-while-এর পার্থক্য? while আগে শর্ত দেখে (০ বারও চলতে পারে); do-while আগে চলে, পরে দেখে (অন্তত ১ বার)।
  • int i = 5; int a = i++; int b = ++i; হলে a, b, i? 5, 7, 7.
  • switch-এ break না দিলে? মিলে যাওয়া case থেকে নিচের সব case চলে — fall-through. সৃজনশীল প্রশ্নে এমন কোডের আউটপুট লিখতে বলা হয়।

আরও গভীরে: এই পর্ব HSC সিলেবাসের সীমা পর্যন্ত। প্রতিটি বিষয় অনেক বিস্তারে — ডেটা টাইপের ভেতরের bit, printf-scanf-এর সব ফাঁদ, লুপের নকশা আর undefined behaviour — জানতে দেখুন এই সাইটের পূর্ণ C প্রোগ্রামিং কোর্স; বিশেষ করে অপারেটর, if আর switch আর লুপ-এর পর্বগুলো। অ্যারে আর ফাংশন আসছে পর্ব ৪০-এ।

৯ · AI-এর যুগে — কোড লেখা সহজ, বোঝাটা আপনার

আজ যেকোনো AI চ্যাটবট এই পর্বের প্রতিটি প্রোগ্রাম কয়েক সেকেন্ডে লিখে দেয় — নির্ভুলভাবেই, বেশিরভাগ সময়। কিন্তু পরীক্ষার হলে AI নেই; খাতায় নিজের হাতে লিখতে হয়, আর আউটপুট বের করতে হয় মাথায় dry-run করে। চাকরির ইন্টারভিউতেও হোয়াইটবোর্ডে লিখতে বলা হয়। তাই AI-কে লেখক হিসেবে নয়, শিক্ষক আর অনুশীলনের সঙ্গী হিসেবে ব্যবহার করুন:

  • error বোঝাতে: compiler-এর বার্তা আর কোড দিয়ে জিজ্ঞেস করুন “কেন হলো” — শুধু “ঠিক করে দাও” নয়।
  • নতুন অনুশীলন বানাতে: “factorial-এর মতো আরও ৫টি প্রশ্ন দাও, উত্তর পরে দেখাবে” — নিজে লিখে তারপর মেলান।
  • আউটপুট-অনুমানের প্রশ্ন: AI-কে ছোট কোড দিয়ে “আউটপুট কী” প্রশ্ন বানাতে বলুন, নিজে dry-run করুন, তারপর অনলাইন compiler-এ চালিয়ে যাচাই করুন।

নিচের prompt-টি কপি করে নিজের কোড বসিয়ে ব্যবহার করুন। খেয়াল করুন, AI-কে সমাধান লিখে দিতে নিষেধ করা হয়েছে — যাতে ভাবনার কাজটি আপনিই করেন:

তুমি একজন ধৈর্যশীল C প্রোগ্রামিং শিক্ষক, আমি HSC/চাকরির পরীক্ষার জন্য প্রস্তুতি নিচ্ছি। নিচে আমার লেখা C কোড আর compiler-এর বার্তা দিলাম। ১. ভুলটি কোন লাইনে আর কেন হলো, সহজ বাংলায় বলো — কিন্তু পুরো সঠিক কোড লিখে দিও না, শুধু ইঙ্গিত দাও। ২. কোডটি standard C কি না দেখো (int main(), return 0, conio.h ছাড়া)। ৩. integer division, scanf-এ &, = বনাম ==, switch-এ break — এই ফাঁদগুলোর কোনোটি আছে কি না বলো। ৪. ইনপুট 5 দিলে প্রতিটি লুপের ঘুরে ভ্যারিয়েবলের মান কী হবে, একটি dry-run টেবিল আমাকে নিজে বানাতে বলো; পরে আমি পাঠালে মিলিয়ে দেখো। ৫. একই ধরনের আরও ৩টি অনুশীলনী প্রশ্ন দাও (উত্তর ছাড়া)। [এখানে কোড আর error বার্তা]

AI-এর লেখা কোড হাতে পেলে — যাচাইয়ের চেকলিস্ট

শেষ চেকটিই আসল পরীক্ষা। পড়ে বোঝা আর নিজে লিখতে পারা আলাদা দক্ষতা — ঠিক যেমন রিকশায় চড়ে শহর চেনা আর নিজে সাইকেল চালিয়ে পথ খুঁজে বের করা আলাদা।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলো C-র ইতিহাস আর নকশার সিদ্ধান্তের গল্প, যা পরীক্ষার বাইরেও কাজে লাগবে।

প্র ০১C আর Unix প্রায় একসাথে জন্মেছিল। একটি ভাষা আর একটি অপারেটিং সিস্টেম কীভাবে একে অপরকে বড় করল, আর “K&R” বইয়ের ভূমিকা কী?

১৯৬০-এর দশকের শেষে Bell Labs Multics নামের একটি বড় যৌথ অপারেটিং সিস্টেম প্রকল্প থেকে সরে আসে। সেই প্রকল্পে কাজ করা Ken Thompson ১৯৬৯ সালে একটি পুরোনো PDP-7 কম্পিউটারে নিজের জন্য ছোট একটি সিস্টেম লেখেন — পরে যার নাম হয় Unix. লেখা হয়েছিল assembly-তে, অর্থাৎ ওই একটি যন্ত্রের নিজস্ব ভাষায়। অন্য কম্পিউটারে নিতে হলে প্রায় পুরোটা আবার লিখতে হতো।

Thompson আগের BCPL ভাষা থেকে B নামে একটি ছোট ভাষা বানান। কিন্তু B-তে ডেটা টাইপ ছিল না — সব কিছুই একটি “শব্দ” (word). নতুন PDP-11 কম্পিউটার বাইট ধরে মেমরি ব্যবহার করত, আর অক্ষর, পূর্ণসংখ্যা, দশমিক আলাদা করে সামলানো দরকার হলো। Dennis Ritchie B-তে char, int-এর মতো টাইপ যোগ করেন; ১৯৭১-৭৩ সময়ে ভাষাটি দাঁড়িয়ে যায়, নাম হয় C, আর জন্মসাল হিসেবে সাধারণত ১৯৭২ বলা হয়। এই পর্বে যে typed ভ্যারিয়েবল শিখলেন, সেটিই ছিল C-র জন্মের মূল কারণ।

১৯৭৩ সালে Unix-এর kernel-এর বেশিরভাগ C-তে নতুন করে লেখা হয়। ফল হলো চমকপ্রদ: নতুন কোনো কম্পিউটারে Unix নিতে এখন শুধু সেই যন্ত্রের জন্য একটি C compiler আর অল্প কিছু assembly লাগে। এই সহজে এক যন্ত্র থেকে আরেক যন্ত্রে নেওয়ার গুণকে বলে portability. Unix বিশ্ববিদ্যালয়গুলোতে ছড়িয়ে পড়ল, আর সাথে C — যে Unix শিখত, সে C-ও শিখত।

১৯৭৮ সালে Brian Kernighan আর Ritchie লেখেন “The C Programming Language”. পাতলা, পরিষ্কার এই বই এক দশক ধরে ভাষাটির কার্যত মানদণ্ড ছিল — লেখকদের আদ্যক্ষর থেকে নাম “K&R”. প্রথম উদাহরণ হিসেবে “hello, world” প্রোগ্রামকে বিশ্বজোড়া প্রথা বানিয়েছে এই বইই। পরে ১৯৮৯ সালে ANSI আনুষ্ঠানিক মান (C89) প্রকাশ করে, তারপর C99, C11, C17 আর সবচেয়ে নতুন C23. ১৯৮৩ সালে Thompson আর Ritchie Unix-এর জন্য Turing Award পান।

মূল উপলব্ধি: C জনপ্রিয় হয়েছিল কোনো বিজ্ঞাপনে নয় — একটি বাস্তব, কাজের সিস্টেম (Unix) লিখতে গিয়ে তৈরি হয়েছিল বলে। একটি ভাষা টিকে থাকে যখন সে বড় কোনো সমস্যার সমাধানে নিজেকে প্রমাণ করে।

প্র ০২পঞ্চাশ বছরের পুরোনো ভাষা C আজও কেন Linux, মাইক্রোকন্ট্রোলার এমনকি Python-এর ভেতরে চলে?

১৯৯১ সালে ফিনল্যান্ডের ছাত্র Linus Torvalds যে Linux kernel লেখা শুরু করেন, তা মূলত C-তে। আজ সেই kernel চলে কোটি কোটি Android ফোন, বেশিরভাগ ওয়েব সার্ভার আর প্রায় সব সুপারকম্পিউটারে। সাম্প্রতিক সংস্করণগুলোতে কিছু অংশ (বিশেষত driver) Rust-এ লেখার সুযোগ যোগ হয়েছে, কিন্তু মূল অংশ এখনো C. Windows আর macOS-এর kernel-এর বড় অংশও C আর C++-এ লেখা।

দ্বিতীয় বড় ক্ষেত্র embedded system: ওয়াশিং মেশিন, মাইক্রোওয়েভ, গাড়ির ব্রেক নিয়ন্ত্রক, রাউটার, স্মার্ট মিটার। এসব চিপে মেমরি কয়েক কিলোবাইট থেকে কয়েক মেগাবাইট; বড় কোনো runtime বসানোর জায়গা নেই। প্রায় প্রতিটি নতুন চিপের সাথে নির্মাতা প্রথমেই দেয় একটি C compiler — কারণ C-র জন্য compiler বানানো তুলনামূলক সহজ, আর C প্রোগ্রাম চলতে প্রায় কিছুই লাগে না।

তৃতীয়টি অবাক করার মতো: Python-এর সবচেয়ে প্রচলিত interpreter — CPython, python.org থেকে যেটি নামান — নিজেই C-তে লেখা। আপনার Python প্রোগ্রামের প্রতিটি লাইন আসলে C-তে লেখা একটি প্রোগ্রাম চালায়। Python-এর NumPy-র মতো দ্রুত লাইব্রেরিগুলোর ভারী অংশও C-তে। তেমনি ফোনে ফোনে থাকা SQLite ডেটাবেস C-তে লেখা। প্রায় সব ভাষাই C-তে লেখা লাইব্রেরি ডাকতে পারে — C যেন প্রোগ্রামিং দুনিয়ার “সাধারণ ভাষা”।

কেন? C-র প্রোগ্রাম কতটুকু মেমরি নেবে, কত দ্রুত চলবে — তা আগে থেকে অনুমান করা যায়; পেছনে কোনো স্বয়ংক্রিয় মেমরি-পরিষ্কারক (garbage collector) হঠাৎ থামিয়ে দেয় না। হার্ডওয়্যারের ঠিকানায় সরাসরি লেখা যায়। আর কয়েক দশকের কোড, টুল আর অভিজ্ঞ প্রোগ্রামার — এগুলো বদলানোর খরচ বিশাল। তবে দামও আছে: মেমরি-সংক্রান্ত ভুল (সীমার বাইরে লেখা) বহু নিরাপত্তা-সমস্যার উৎস, তাই সাম্প্রতিক বছরগুলোতে বিভিন্ন সরকারি নিরাপত্তা সংস্থা নতুন প্রকল্পে Rust-এর মতো memory-safe ভাষা ব্যবহারের পরামর্শ দিচ্ছে।

মূল উপলব্ধি: C টিকে আছে কারণ সে সবচেয়ে নিচের স্তরে বসে — অন্য সব সফটওয়্যার তার ওপর দাঁড়িয়ে। নতুন ভাষা আসছে, কিন্তু নিচের স্তর বদলায় খুব ধীরে।

প্র ০৩int-এ 2147483647-এর সাথে 1 যোগ করলে C কী করবে? “undefined behaviour” কী, আর C কেন প্রোগ্রামারকে এতটা বিশ্বাস করে?

৪ বাইট (৩২ bit) int-এর সর্বোচ্চ মান 2,147,483,647. পর্ব ১৭-এ দেখেছেন, 2's complement-এ এর সাথে ১ যোগ করলে bit-নকশা ঘুরে হয়ে যায় সবচেয়ে ছোট ঋণাত্মক সংখ্যা −2,147,483,648 — বাইকের মিটারের মতো। বেশিরভাগ কম্পিউটারের হার্ডওয়্যার ঠিক এটাই করে। কিন্তু C standard বলে: signed int-এর overflow হলো undefined behaviour — অর্থাৎ ভাষার নিয়মে এর কোনো নির্দিষ্ট ফল নেই, যা খুশি ঘটতে পারে।

“যা খুশি” কথাটি আক্ষরিক। আধুনিক compiler ধরে নেয়, সঠিক প্রোগ্রামে overflow কখনো হবে না — আর সেই অনুমানে কোড ছেঁটে দ্রুত করে। যেমন if (x + 1 > x) শর্তটি compiler “সবসময় সত্য” ধরে পুরো পরীক্ষাটাই মুছে দিতে পারে, যদিও x সর্বোচ্চ মানে থাকলে হার্ডওয়্যারে ফল মিথ্যা হতো। অর্থাৎ overflow ধরার জন্য লেখা আপনার পরীক্ষাই উধাও হতে পারে। unsigned int-এ অবশ্য নিয়ম নির্দিষ্ট: সীমা পেরোলে আবার 0 থেকে ঘোরে।

কেন এমন নকশা? C-র মানদণ্ড তৈরির সময় লেখা ব্যাখ্যায় (ANSI C Rationale) “C-র মূল চেতনা” হিসেবে কয়েকটি কথা আছে — তার প্রথমটি “Trust the programmer” (প্রোগ্রামারকে বিশ্বাস করুন), আরেকটি “প্রোগ্রামারকে প্রয়োজনীয় কাজ করতে বাধা দেবেন না”। ১৯৭০-এর যন্ত্রগুলো ছিল খুব ধীর; প্রতিটি যোগের পর overflow পরীক্ষা মানে বাড়তি সময়। তা ছাড়া তখন সব যন্ত্র 2's complement ব্যবহার করত না — কোনো একটি ফল বেঁধে দিলে অন্য যন্ত্রে C ধীর হয়ে যেত। তাই দায়িত্ব দেওয়া হলো প্রোগ্রামারকে।

অন্য ভাষা অন্য পথ নিয়েছে: Java-তে overflow-এর ফল নির্দিষ্ট (ঘুরে যায়), Python-এর পূর্ণসংখ্যা প্রয়োজনমতো নিজে বড় হয় তাই overflow-ই হয় না, Rust ডিবাগ মোডে প্রোগ্রাম থামিয়ে দেয়। C-তে নিজেকে বাঁচানোর উপায়: যথেষ্ট বড় টাইপ (long long), হিসাবের আগে সীমা পরীক্ষা, আর gcc-র -fsanitize=undefined দিয়ে পরীক্ষা চালানো, যা চলার সময় এমন ভুল ধরিয়ে দেয়। এই পর্বের ১৩! উদাহরণটি এর সবচেয়ে সহজ রূপ।

মূল উপলব্ধি: C গতি দেয় নিরাপত্তার বিনিময়ে — নিয়ম ভাঙলে কেউ থামাবে না। তাই C-প্রোগ্রামারের প্রথম দক্ষতা হলো জানা, কোথায় ভাষা আপনাকে পাহারা দেয় না।

প্র ০৪if (x = 5) — একটি অক্ষরের ভুল কেন এত বিখ্যাত, আর কিছু ভাষা কেন এটি লেখাই নিষেধ করে দিয়েছে?

C-তে assignment নিজেও একটি expression, যার একটি মান আছে: x = 5-এর মান 5. আর C-র চোখে শূন্য ছাড়া সব সত্য। তাই if (x = 5) দুটি ক্ষতি করে — x-এর আগের মান মুছে 5 বসায়, আর শর্তকে চিরকাল সত্য করে দেয়। প্রোগ্রাম চলে, কোনো error নেই, শুধু সিদ্ধান্তগুলো ভুল। ঠিক এ কারণেই এটি বিপজ্জনক: সাধারণ চোখে = আর ==-এর পার্থক্য প্রায় অদৃশ্য।

এই ভুলের সবচেয়ে বিখ্যাত ঘটনা ইচ্ছাকৃত। ২০০৩ সালে কেউ একজন Linux kernel-এর সোর্স কোডের একটি মিরর সার্ভারে চুপিচুপি দুই লাইন ঢুকিয়েছিল, যার ভেতরে ছিল current->uid = 0 — দেখতে তুলনার মতো, আসলে assignment. Linux-এ uid 0 মানে সর্বোচ্চ ক্ষমতার root ব্যবহারকারী; একটি বিশেষ ধরনের অনুরোধ পাঠালেই যে কেউ root হয়ে যেত। assignment-এর মান 0, তাই শর্তটি মিথ্যা হয়ে কোনো সন্দেহজনক আচরণও দেখাত না। কোড-পরিবর্তনের রেকর্ডে অমিল দেখে ডেভেলপাররা দ্রুত এটি ধরে ফেলেন, আর মূল kernel-এ তা কখনো যায়নি। কিন্তু ঘটনাটি দেখিয়ে দেয়, একটি = চিহ্ন কত বড় দরজা খুলতে পারে।

প্রতিকার নানা রকম। gcc-তে -Wall দিলে “suggest parentheses around assignment used as truth value” সতর্কতা আসে। কেউ কেউ লেখেন if (5 == x) — “Yoda condition” — যাতে ভুল করে = দিলে 5 = x হয়ে compile error আসে। আর নতুন ভাষাগুলো সমস্যাটি নকশা থেকেই সরিয়েছে: Java আর C#-এ if-এর শর্ত অবশ্যই boolean হতে হয়, তাই int-এ if (x = 5) compile হয় না। Python-এ শর্তের ভেতরে = সরাসরি syntax error; ৩.৮ সংস্করণে assignment-সহ শর্তের দরকার মেটাতে ইচ্ছা করেই আলাদা চেহারার := অপারেটর আনা হয়েছে। Swift-এ assignment কোনো মানই ফেরত দেয় না।

মূল উপলব্ধি: ভাষার নকশা মানুষের ভুলের সম্ভাবনাকে বাড়ায় বা কমায়। C নমনীয়তা বেছে নিয়েছিল; পরের ভাষাগুলো সেই অভিজ্ঞতা থেকে শিখে ভুলটিকে অসম্ভব করেছে। C-তে আপনার পাহারাদার হলো compiler warning — সেটি চালু রাখুন।

প্র ০৫HSC-তে প্রথম প্রোগ্রামিং ভাষা হিসেবে C কেন? Python দিয়ে শুরু করলে কী লাভ, কী ক্ষতি?

C-র পক্ষে যুক্তি: C ছোট ভাষা — হাতে গোনা keyword, অল্প কিছু নিয়ম, যা একটি অধ্যায়ে ধরানো যায়। টাইপ ঘোষণা, &, integer ভাগ — এগুলো শিক্ষার্থীকে দেখায় কম্পিউটার আসলে কীভাবে মেমরিতে মান রাখে; এই কোর্সের বাইনারি, মেমরি আর CPU-র পর্বগুলোর সাথে সরাসরি যোগ তৈরি হয়। compile করার ধাপ শেখায় source code আর চালানো যায় এমন প্রোগ্রাম আলাদা জিনিস। C-র লেখার ধরন C++, Java, C#, JavaScript-এ প্রায় একই, তাই পরের ভাষা সহজ হয়। আর পরীক্ষার দিক থেকে C-র প্রোগ্রাম ছোট আর নির্দিষ্ট — খাতায় লেখা, আউটপুট অনুমান আর মূল্যায়ন সহজ।

C-র বিপক্ষে: নতুনদের জন্য C কঠোর। scanf-এর &, format specifier, সেমিকোলন — আসল সমস্যা সমাধানের আগেই এসবে আটকে যেতে হয়। ভুল করলে C প্রায়ই সতর্ক না করে ভুল উত্তর দেয় বা crash করে, আর error-বার্তা ইংরেজিতে, কঠিন ভাষায়। অনেকে এখানেই প্রোগ্রামিং “আমার জন্য নয়” ভেবে ছেড়ে দেন।

Python-এর পক্ষে: লেখা পড়তে প্রায় ইংরেজির মতো; print(7 / 2) সরাসরি 3.5 দেয়; টাইপ ঘোষণা লাগে না। ফলে শিক্ষার্থী শুরু থেকেই সমস্যা সমাধানে মন দিতে পারেন। ডেটা বিশ্লেষণ, AI আর অটোমেশনে Python-এর ব্যবহার বিশাল, তাই চাকরির বাজারেও কাজে লাগে। অনেক বিশ্ববিদ্যালয় প্রথম ভাষা হিসেবে Python নিয়েছে। বিপক্ষে: সহজ বলেই মেমরি, টাইপ আর গতির প্রশ্নগুলো আড়ালে থাকে — পরে নিচের স্তরের কাজে গেলে সেগুলো নতুন করে শিখতে হয়।

একটি মাঝামাঝি উদাহরণ: Harvard-এর জনপ্রিয় কোর্স CS50 শুরু করে Scratch দিয়ে, তারপর কয়েক সপ্তাহ C — মেমরি আর নিচের স্তর বোঝাতে — আর তারপর Python, যাতে শিক্ষার্থীরা নিজেরাই দেখেন একই কাজ Python-এ কত ছোট হয়। অর্থাৎ প্রশ্নটি “কোনটি” নয়, “কোন ক্রমে আর কেন”।

মূল উপলব্ধি: ভাষা একটি হাতিয়ার; আসল শেখা হলো ভ্যারিয়েবল, শর্ত, লুপ আর dry-run করে ভাবা — যা সব ভাষায় একই। C দিয়ে শুরু করলে যন্ত্রকে চেনেন, Python দিয়ে দ্রুত ফল পান; দুটোই শিখলে দুই সুবিধাই আপনার।

অনুশীলন

খাতা-কলম নিন। আগে নিজে dry-run করুন, তারপর উত্তর খুলুন — আর সম্ভব হলে অনলাইন compiler-এ চালিয়ে মিলিয়ে নিন।

  1. আউটপুট বলুন: int a = 17, b = 5; float c = a / b; printf("%d %d %.1f %.1f", a / b, a % b, c, (float)a / b);

    আউটপুট: 3 2 3.0 3.4. 17 / 5 integer ভাগে 3; ভাগশেষ 17 % 5 = 2; c-তে int ভাগের ফল 3 ঢুকে 3.0 হয়েছে; শুধু cast করা হিসাবটি 17.0 / 5 = 3.4 দেয়।

  2. ভুল খুঁজুন: নিচের কোডে চারটি ভুল আছে — খুঁজে ঠিক করুন।
    int n, sum; · scanf("%d", n); · for (i = 1; i <= n; i++); · sum = sum + i

    (১) sum-এ শুরুর মান নেই → int n, i, sum = 0; (i ঘোষণাও নেই)। (২) scanf-এ & নেই → &n. (৩) for-এর পরে ; লুপের শরীর খালি করে দিয়েছে — মুছে দিন। (৪) sum = sum + i-এর শেষে ; নেই — syntax error. লক্ষ করুন, (৪) ছাড়া বাকি তিনটি compiler হয়তো আটকাবে না, শুধু warning দেবে বা কিছুই বলবে না — তাই এগুলোই বেশি বিপজ্জনক।

  3. নিজে লিখুন: একটি অক্ষর (char) ইনপুট নিয়ে switch দিয়ে বলুন সেটি vowel (a, e, i, o, u — ছোট বা বড় হাতের) কি না। একটি case-এর জন্য একাধিক মান কীভাবে মেলাবেন?

    এখানে fall-through-ই কাজে লাগে — একাধিক case পরপর লিখে একটিই কাজ:

    char ch;
    scanf(" %c", &ch);
    switch (ch) {
        case 'a': case 'e': case 'i': case 'o': case 'u':
        case 'A': case 'E': case 'I': case 'O': case 'U':
            printf("%c is a vowel\n", ch);
            break;
        default:
            printf("%c is not a vowel\n", ch);
    }

    " %c"-এর সামনের space আগের Enter-এর মতো ফাঁকা অক্ষর বাদ দেয় — char পড়ার একটি পরিচিত ফাঁদ। ইনপুট E দিলে আউটপুট E is a vowel.

  4. লুপ গুনে দেখুন: নিচের প্রতিটি লুপের শরীর কতবার চলবে, আর শেষে i কত? (ক) for (i = 0; i < 10; i += 3) (খ) i = 5; while (i > 0) i -= 2; (গ) i = 1; do { i *= 2; } while (i < 1); (ঘ) for (i = 10; i < 5; i++)

    (ক) i = 0, 3, 6, 9 → ৪ বার; শেষে i = 12. (খ) i = 5 → 3 → 1 → −1: ৩ বার; শেষে i = −1. (গ) do-while, তাই শর্ত মিথ্যা হলেও ১ বার; i = 2. (ঘ) শুরুতেই 10 < 5 মিথ্যা → ০ বার; i = 10. (খ)-তে i > 0-এর বদলে i != 0 লিখলে কী হতো ভাবুন — i কখনো ঠিক 0 হয় না, তাই infinite loop.

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি C প্রোগ্রাম লেখা থেকে ফল পাওয়া পর্যন্ত ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. সমস্যার অ্যালগরিদম বা ফ্লোচার্ট তৈরি করুন
  2. editor-এ কোড লিখে .c ফাইল হিসেবে সেভ করুন
  3. compiler দিয়ে compile করুন
  4. error থাকলে প্রথম error থেকে ঠিক করে আবার compile করুন
  5. তৈরি হওয়া প্রোগ্রাম চালিয়ে ইনপুট দিন
  6. আউটপুট dry-run বা জানা উত্তরের সাথে মিলিয়ে দেখুন

C-তে printf দিয়ে একটি float ভ্যারিয়েবলের মান ছাপতে কোন format specifier ব্যবহার করা হয়?

  • %d
  • %f
  • %c
  • %s

C-তে printf("%d %d", 7 / 2, 7 % 2); চালালে আউটপুট কী হবে?

  • 3.5 1
  • 1 3
  • 3 1
  • 4 1

শর্ত শুরু থেকেই মিথ্যা হলে C-র কোন লুপের শরীর তবুও একবার চলে?

  • do-while
  • while
  • for
  • তিনটিই

int i = 5; int a = i++; int b = ++i; — এরপর a, b আর i-এর মান কত?

  • a = 6, b = 7, i = 7
  • a = 5, b = 6, i = 6
  • a = 5, b = 5, i = 7
  • a = 5, b = 7, i = 7

C-র switch statement-এ কোনো case-এর শেষে break না দিলে কী ঘটে?

  • compile error হয়
  • মিলে যাওয়া case-এর পরের case-গুলোও চলে
  • switch আবার প্রথম থেকে চলে
  • শুধু default অংশটি চলে

C-তে নিচের কোনটি বৈধ identifier (ভ্যারিয়েবলের নাম)?

  • 2nd_roll
  • float
  • total_marks
  • my marks

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. গঠন: #include <stdio.h> → int main() → { statement; ... return 0; }. প্রতিটি statement-এর শেষে ;, নামের নিয়ম মেনে identifier.
  2. টাইপ আর specifier: int–%d, float–%f, double–%lf, char–%c. scanf-এ ভ্যারিয়েবলের আগে & (ঠিকানা)।
  3. অপারেটর: 7/2 = 3, 7%2 = 1; দশমিক চাইলে (float)a / b. = মান বসায়, == তুলনা করে। i++ আগে দেয় পরে বাড়ায়, ++i আগে বাড়ায়।
  4. সিদ্ধান্ত: ladder-এ প্রথম সত্য শর্তটিই চলে; switch-এ প্রতিটি case-এর শেষে break, পরিসরের জন্য else-if.
  5. লুপ: for (গণনা জানা), while (আগে শর্ত), do-while (অন্তত একবার)। যোগফল শুরু 0, গুণফল শুরু 1 — আর প্রতিটি লুপ খাতায় dry-run করে যাচাই।

পরের পর্বে: ৫০ জন শিক্ষার্থীর নম্বর রাখতে ৫০টি ভ্যারিয়েবল? না — পর্ব ৪০-এ দেখব অ্যারে, আর একই কাজ বারবার লেখার বদলে ফাংশন: বড় সমস্যাকে ছোট টুকরোয় ভেঙে সমাধান।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান