প্রোগ্রামিং বই
প্রিয় শিক্ষার্থীবৃন্দ,
তোমাদের জানাই আন্তরিক অভিনন্দন ও শুভেচ্ছা। বর্তমান যুগ তথ্য ও যোগাযোগ প্রযুক্তির যুগ। এজন্য বর্তমান সরকার যুগোপযোগী শিক্ষার আলোকে শিক্ষা ব্যবস্থায় নতুন বিষয় “তথ্য ও যোগাযোগ প্রযুক্তি” সংযুক্তি করেছেন তাদের দুরদৃষ্টিতা ও আন্তরিকতার জন্য ধন্যবাদ।
শুরুর আগে
কম্পিউটার তো আসলে গণনা করার যন্ত্র, তাই
না? যদিও আমরা এটি দিয়ে গান শুনি, ভিডিও দেখি, গেমস
খেলি, আরও নানা কাজ করি। আসলে শেষ পর্যন্ত কম্পিউটার বোঝে শূন্য (0) আর
একের (1) হিসাব। তাই
ব্যবহারকারী (user) যা-ই করুক না কেন, কম্পিউটার
কিন্তু সব কাজ গণনার মাধ্যমেই করে। কম্পিউটারের ব্যবহার এত ব্যাপক হওয়ার পেছনে অন্যতম কারণ হচ্ছে
নানা রকম সফটওয়্যার দিয়ে নানা ধরনের কাজ করা যায় কম্পিউটারে। এসব সফটওয়্যার তৈরি করতে হয়
প্রোগ্রাম লিখে অর্থাৎ কী হলে কী করবে এটি প্রোগ্রামের সাহায্যে কম্পিউটারকে
বোঝাতে হয়।
একসময় কিন্তু কেবল 0 আর 1 ব্যবহার
করেই কম্পিউটারের প্রোগ্রাম লিখতে হতো। কারণ কম্পিউটার তো 0, 1 ছাড়া আর কিছু বোঝে না, আর
কম্পিউটারকে দিয়ে কোনো কাজ করাতে চাইলে তো তার ভাষাতেই কাজের নির্দেশ দিতে হবে। 0, 1 ব্যবহার
করে যে প্রোগ্রামিং করা হতো, তার জন্য যে ভাষা ব্যবহৃত হতো, তাকে
বলা হয় মেশিন ল্যাঙ্গুয়েজ। তারপর এল অ্যাসেম্বলি ল্যাঙ্গুয়েজ। এতে প্রোগ্রামাররা কিছু ইনস্ট্রাকশন
যেমন ADD (যোগ), MUL (গুণ) ইত্যাদি ব্যবহারের সুযোগ পেল। আর এই ভাষাকে 0, 1-এর
ভাষায় নিয়ে কাজ করাবার দায়িত্ব পড়ল অ্যাসেম্বলারের ওপর, প্রোগ্রামারদের
সে বিষয়ে ভাবতে হতো না। কিন্তু
মানুষের চাহিদার তো শেষ নেই। নতুন নতুন চাহিদার ফলে নতুন নতুন জিনিসের উদ্ভব হয়। একসময় দেখা গেল যে অ্যাসেম্বলি
ল্যাঙ্গুয়েজ দিয়েও কাজ করা ঝামেলা হয়ে যাচ্ছে। তাই বড় বড় প্রোগ্রাম লিখার জন্য
আরও সহজ ও উন্নত নানা রকম প্রোগ্রামিং ভাষা তৈরি হলো। যেমন - ফরট্রান (Fortran), বেসিক
(Basic), প্যাসকেল (Pascal), সি (C)। তবে এখানেই শেষ নয়, এরপর
এল আরও অনেক ল্যাঙ্গুয়েজ, যার মধ্যে অন্যতম হচ্ছে, সি
প্লাস প্লাস (C++), ভিজ্যুয়াল বেসিক (Visual Basic), জাভা
(Java), সি শার্প (C#), পার্ল (Perl), পিএইচপি
(PHP), পাইথন (Python), রুবি (Ruby)। এখনো
কম্পিউটার বিজ্ঞানীরা নিত্যনতুন প্রোগ্রামিং ভাষা তৈরি করে যাচ্ছেন। প্রোগ্রামাররা এসব ভাষা ব্যবহার করে
প্রোগ্রাম লেখেন আর প্রতিটি ভাষার রয়েছে আলাদা কম্পাইলার, যার
কাজ হচ্ছে ওই প্রোগ্রামকে কম্পিউটারের বোধগম্য ভাষায় রূপান্তর করা, তাই
এটি নিয়ে প্রোগ্রামারদের ভাবতে হয় না।
প্রোগ্রাম লিখার সময় প্রোগ্রামারকে
তিনটি প্রধান কাজ করতে হয়। প্রথমে তার বুঝতে হয় যে সে আসলে কী করতে যাচ্ছে, মানে
তার প্রোগ্রামটি আসলে কী কাজ করবে। তারপর চিন্তাভাবনা করে এবং যুক্তি (logic)
ব্যবহার করে অ্যালগরিদম
দাঁড় করাতে হয়। মানে, লজিকগুলো
ধাপে ধাপে সাজাতে হয়। এর
পরের কাজটি হচ্ছে অ্যালগরিদমটাকে কোনো একটি প্রোগ্রামিং ভাষায় রূপান্তর করা, যাকে
আমরা বলি কোডিং করা। একেক
ধরনের কাজের জন্য একেক ল্যাঙ্গুয়েজ বেশি উপযোগী।
এই বইতে আমরা প্রোগ্রামিংয়ের মৌলিক
কিছু জিনিস শেখার চেষ্টা করব এবং প্রোগ্রামগুলো আমরা লিখব সি ল্যাঙ্গুয়েজ ব্যবহার
করে। আমি ধরে নিচ্ছি, তোমরা
কম্পিউটার ব্যবহার করে অভ্যস্ত এবং প্রোগ্রামিং জিনিসটার সঙ্গে সম্পূর্ণ অপরিচিত। আর সি ল্যাঙ্গুয়েজ ব্যবহার করার
পেছনে কারণ হচ্ছে, এটি বেশ পুরোনো হলেও অত্যন্ত
শক্তিশালী ও জনপ্রিয় ল্যাঙ্গুয়েজ। প্রোগ্রামিংয়ের মৌলিক জিনিসগুলো বোঝার জন্য সি ভাষা অত্যন্ত
সহায়ক। আর
জনপ্রিয় সব প্রোগ্রামিং প্রতিযোগিতায় যে অল্প কয়েকটি ল্যাঙ্গুয়েজ ব্যবহার করা
যায়, তার মধ্যে সি অন্যতম। আমরা অবশ্য সি ল্যাঙ্গুয়েজের পুরোটা এখানে শিখব না, কেবল
মৌলিক বিষয়গুলো নিয়ে কাজ করতে যা দরকার সেটি দেখব। এই বইটি পড়ার পরে তোমরা কেবল সি-এর
জন্য কোন বই পড়তে পারো অথবা অন্য কোনো ভাষা (যেমন–
সি প্লাস প্লাস, জাভা
কিংবা পাইথন) শেখা শুরু করে দিতে পারো। বইয়ের পরিশিষ্ট অংশে আমি কিছু বইয়ের নাম দিয়েছি, যা
তোমাদের কাজে লাগবে।
বইটি পড়তে তোমাদের তিনটি জিনিস
লাগবে, কম্পিউটার (ইন্টারনেট সংযোগ থাকলে ভালো হয়), সি
ল্যাঙ্গুয়েজের কম্পাইলার এবং যথেষ্ট সময়। তাড়াহুড়ো না করে দুই থেকে তিন মাস সময় নিয়ে বইটি পড়লে
ভালো হয়। প্রোগ্রামিং
শেখার জন্য কেবল পড়াই যথেষ্ট নয়, পাশাপাশি কোডিং করতে হবে। বইয়ের প্রতিটি উদাহরণ নিজে নিজে
কোড করে কম্পিউটারে চালিয়ে দেখতে হবে। যখনই আমি কোনো প্রশ্ন করব, সেটি নিয়ে চিন্তা করতে হবে। তার জন্য যদি দু-তিন ঘণ্টা বা
দু-তিন দিন সময় লাগে লাগুক, কোনো ক্ষতি নেই, বরং
দীর্ঘ সময় কোনো সমস্যার সমাধান নিয়ে চিন্তা করার অভ্যাসটি খুব জরুরি। কোনো অধ্যায় পুরোপুরি বোঝার আগে
পরের অধ্যায় পড়া শুরু করা যাবে না। আবার কোনো অংশ যদি তোমার কাছে খুব সহজ মনে হয়, সেই
অংশ ঠিকভাবে না পড়ে এবং প্রোগ্রামগুলো না করে পরের অংশে চলে যেয়ো না কিন্তু। সাধারণ পড়ালিখার সঙ্গে প্রোগ্রামিং
শেখার অনেক পার্থক্য। এখানে
পড়ার সঙ্গে সঙ্গে কাজ করাও জরুরি। আর এই বই পড়েই কিন্তু তুমি প্রোগ্রামার হয়ে যাবে না, বইটি
পড়ে তুমি প্রোগ্রামার হওয়া শুরু করবে।
এবার আসা যাক, কম্পাইলার
পাবে কোথায়? সি-এর জন্য বেশ কিছু কম্পাইলার আছে। তুমি যদি লিনাক্স কিংবা ম্যাক
ব্যবহারকারী হও, তবে সবচেয়ে ভালো হচ্ছে gcc। অধিকাংশ
লিনাক্সেই এটি আগে থেকে ইনস্টল করা থাকে। তোমার কম্পিউটারে না থাকলে এটি ইনস্টল করে নিতে হবে। আর উইন্ডোজ ব্যবহার করলে তুমি Codeblocks (http://www.codeblocks.org/) ব্যবহার করতে পারো। এটি একটি ফ্রি ও ওপেন সোর্স IDE (Integrated Development Environment) এবং ম্যাক আর লিনাক্সেও চলে। এমনিতে সাধারণ কোনো টেক্সট এডিটর
(যেমন: নোটপ্যাড, জিএডিট, কেরাইট)
ব্যবহার করে কোড লিখে সেটি কম্পাইলার দিয়ে কম্পাইল করে রান করা যায়। তবে অধিকাংশ আইডিই (IDE) গুলোতেই
নিজস্ব টেক্সট এডিটর ও কম্পাইলার থাকে। প্রোগ্রাম রান করার ব্যবস্থাও থাকে। এ ছাড়াও নানা ধরনের টুলস্ থাকে।
Codeblocksটা
সরাসরি তুমি http://www.codeblocks.org
সাইট থেকে ডাউনলোড ও ইনস্টল
করতে পারো। Downloads পেইজে Binaries-এ
গেলে উইন্ডোজের জন্য তুমি দুটি অপশন দেখবে: codeblocks-10.05-setup.exe
ও codeblocks-10.05mingw-setup.exe। তুমি দ্বিতীয়টি ডাউনলোড করবে (74.0 MB)। আর
ইনস্টল করার কাজটি অন্য যেকোনো সফটওয়্যার বা গেমসের মতোই। যারা উবুন্টু ব্যবহার করো, তারা
Ubuntu Software Center (Applications >
Ubuntu Software Center) থেকে
এটি ডাউনলোড করতে পারো।
প্রোগ্রামিং চর্চার বিষয়। ইন্টারনেটে বেশ কিছু ওয়েবসাইট আছে, যেখানে
প্রচুর সমস্যা দেওয়া আছে যেগুলো প্রোগ্রামের সাহায্যে সমাধান করতে হয়। সব জায়গাতেই তুমি সি ল্যাঙ্গুয়েজে
প্রোগ্রামিং করতে পারবে। এর
মধ্যে কিছু কিছু ওয়েবসাইট আবার নিয়মিত প্রোগ্রামিং প্রতিযোগিতারও আয়োজন করে। এসব প্রতিযোগিতায় অংশগ্রহণ
নিঃসন্দেহে তোমার প্রোগ্রামিং-দক্ষতা বৃদ্ধি করবে আর সেই সঙ্গে বিশ্বের নানা দেশের
প্রোগ্রামারদের সঙ্গে মেশারও সুযোগ করে দেবে। অবশ্য প্রোগ্রামিং প্রতিযোগিতায়
ভালো করতে হলে কেবল প্রোগ্রামিং জানলেই চলবে না,
গাণিতিক দক্ষতাও যথেষ্ট
গুরুত্বপূর্ণ। পরিশিষ্ট
অংশে প্রোগ্রামিং প্রতিযোগিতা নিয়ে আলাপ করব।
বইয়ের প্রতিটি প্রোগ্রামের নিচে
আমি একটি নম্বর দিয়েছি। প্রোগ্রামের
নম্বর যদি ২.৫ হয়, তার মানে হচ্ছে এটি দ্বিতীয়
অধ্যায়ের পাঁচ নম্বর প্রোগ্রাম।
এটি কিন্তু কোনো গল্পের বই নয়। তাই বিছানায় শুয়ে-বসে পড়া যাবে
না। বইটি পড়ার সময় কম্পিউটার চালু
রাখতে হবে এবং প্রতিটি উদাহরণ সঙ্গে সঙ্গে প্রোগ্রাম লিখে দেখতে হবে, কোনো
সমস্যা সমাধান করতে দিলে তখনই সেটি সমাধানের চেষ্টা করতে হবে। মনে রাখবে, যত
বেশি প্রোগ্রামিং তত বেশি আনন্দ।
আশা করছি, তুমি
ধৈর্য নিয়ে বাকি অধ্যায়গুলো পড়বে এবং সবগুলো প্রোগ্রাম কম্পিউটারে চালিয়ে
দেখবে। তোমার
জন্য শুভ কামনা।
পরবর্তি অধ্যায়
পরবর্তি অধ্যায়
[প্রোগ্রামিং
বইঃ অধ্যায় দুই] ডাটা টাইপ, ইনপুট ও আউটপুট।
এ অধ্যায়ে আমরা কিছু ছোট ছোট
প্রোগ্রাম লিখব। সবগুলো
প্রোগ্রাম অবশ্যই কম্পিউটারে চালিয়ে দেখবে এবং একটু পরিবর্তন করে কম্পাইল ও রান
করার চেষ্টা করবে।
আমাদের প্রথম প্রোগ্রামটি হবে দুটি
সংখ্যা যোগ করার প্রোগ্রাম। এখন কথা হচ্ছে, সংখ্যাগুলো তো কম্পিউটারের মেমোরিতে
রাখতে হবে, সেই জটিল কাজটি কীভাবে করব? চিন্তা নেই! সব প্রোগ্রামিং
ল্যাঙ্গুয়েজে ভেরিয়েবল বলে একটি জিনিস আছে যেটি কোন নির্দিষ্ট মান ধারণ করার জন্য
ব্যবহার করা হয়। ভেরিয়েবলের
একটি নাম দিতে হয়, তারপর ভেরিয়েবল = কোনো মান লিখে
দিলে ভেরিয়েবলের ভেতর সেটি ঢুকে যায়। এটির সঙ্গে গাণিতিক সমীকরণের কিন্তু কোনো সম্পর্ক নেই। চলো,
প্রোগ্রামটি লিখে রান করাই, তারপর
ব্যাখ্যা করা যাবে।
#include <stdio.h>
int main()
{
int a;
int b;
int sum;
a = 50;
b = 60;
sum = a + b;
printf("Sum is %d", sum);
return 0;
}
প্রোগ্রাম: ২.১
প্রোগ্রামটি রান করাও, তুমি
স্ক্রিনে দেখবে: Sum is 110।
এখানে a, b, sum তিনটি
ভেরিয়েবল (variable) আলাদা সংখ্যা ধারণ করে। প্রথমে আমাদের বলে দিতে হবে যে a,
b, sum নামে তিনটি ভেরিয়েবল আছে। এবং এগুলোতে কী ধরনের ডাটা থাকবে
সেটিও বলে দিতে হবে। int a; দিয়ে আমরা কম্পাইলারকে বলছি a নামে
একটি ভেরিয়েবল এই প্রোগ্রামে আছে যেটি একটি পূর্ণসংখ্যা (integer)-এর
মান ধারণ করার জন্য ব্যবহার করা হবে। এই কাজটিকে বলে ভেরিয়েবল ডিক্লারেশন। আর int
হচ্ছে ডাটা টাইপ, যেটি
দেখে সি-এর কম্পাইলার বুঝবে যে এতে ইন্টিজার টাইপ ডাটা থাকবে। আরও বেশ কিছু ডাটা টাইপ আছে, সেগুলো
আমরা আস্তে আস্তে দেখব। আমরা
চাইলে একই টাইপের ভেরিয়েবলগুলো ডিক্লেয়ার করার সময় আলাদা লাইনে না লিখে একসঙ্গে
কমা দিয়েও লিখতে পারতাম, যেমন: int a, b, sum;। আর লক্ষ করো যে ভেরিয়েবল ডিক্লারেশনের শেষে সেমিকোলন ব্যবহার করতে
হয়।
এরপর আমি দুটি স্টেটমেন্ট লিখেছি:
a = 50;
b = 60;
এখানে a-এর
মান 50 আর b-এর মান 60 বলে
দিলাম (assign করলাম), যতক্ষণ না এটি আমরা পরিবর্তন করছি, কম্পাইলার
a-এর মান 50 আর b-এর মান 60 ধরবে।
পরের স্টেটমেন্ট হচ্ছে: sum = a + b;। এতে বোঝায়, sum-এর মান হবে a + b-এর
সমান, অর্থাৎ a ও b-এর যোগফল যে সংখ্যাটি হবে সেটি আমরা
sum নামের ভেরিয়েবলে রেখে দিলাম (বা assign
করলাম)।
এবারে যোগফলটি মনিটরে দেখাতে হবে, তাই
আমরা printf ফাংশন ব্যবহার করব।
printf("Sum is %d", sum);
এখানে দেখো printf ফাংশনের
ভেতরে দুটি অংশ। প্রথম
অংশে "Sum is %d" দিয়ে বোঝানো হয়েছে স্ক্রিনে প্রিন্ট করতে হবে Sum is এবং
তার পরে একটি ইন্টিজার ভেরিয়েবলের মান যেটি %d-এর জায়গায় বসবে। তারপর কমা দিয়ে আমরা sum লিখে
বুঝিয়ে দিয়েছি যে %d-তে sum-এর মান প্রিন্ট করতে হবে। ইন্টিজারের জন্য যেমন %d ব্যবহার
করলাম, অন্য ধরনের ভেরিয়েবলের জন্য অন্য কিছু লিখতে হবে, যেটি
আমরা ব্যবহার করতে করতে শিখব। খুব ভালো হতো যদি আমি এখন একটি চার্ট লিখে দিতাম যে সি
ল্যাঙ্গুয়েজে কী কী ডাটা টাইপ আছে, সেগুলো কী দিয়ে লেখে এবং প্রিন্ট
করার জন্য কী করতে হবে আর তোমরা সেই চার্ট মুখস্থ করে ফেলতে। কিন্তু শুধু শুধু মুখস্থ করার কোনো
দরকার নেই, মুখস্থ করার প্রবণতা চিন্তাশক্তি কমায় আর প্রোগ্রামারদের জন্য
চিন্তা করার ক্ষমতা খুবই গুরুত্বপূর্ণ।
আমরা ওপরের প্রোগ্রামটি চাইলে
এভাবেও লিখতে পারতাম:
#include <stdio.h>
int main()
{
int a, b, sum;
a = 50;
b = 60;
sum = a + b;
printf("Sum is %d", sum);
return 0;
}
প্রোগ্রাম: ২.২
আবার ভেরিয়েবল ডিক্লেয়ার করার
সময় একই সঙ্গে অ্যাসাইনও করা যায়:
#include <stdio.h>
int main()
{
int a = 50, b = 60, sum;
sum = a + b;
printf("Sum is %d", sum);
return 0;
}
প্রোগ্রাম: ২.৩
এখন তোমাদের জন্য একটি প্রশ্ন। নিচের প্রোগ্রামটির আউটপুট কী হবে?
#include <stdio.h>
int main()
{
int x, y;
x = 1;
y = x;
x = 2;
printf("%d", y);
return 0;
}
প্রোগ্রাম: ২.৪
কী মনে হয়? আউটপুট
1 নাকি 2? আউটপুট হবে 1, কারণ
প্রথমে কম্পাইলার দেখবে, x-এর মান 1 অ্যাসাইন
করা হয়েছে (x = 1;)। তারপর x-এর
মানটি আবার y-এ অ্যাসাইন করা হয়েছে (y =
x;)। এখন y-এর মান 1। তারপর
আবার x-এর মান 2 অ্যাসাইন করা হয়েছে। কিন্তু তাতে y-এর
মানের কোনো পরিবর্তন হবে না। প্রোগ্রামিংয়ে y = x; আসলে কোনো সমীকরণ না যে এটি সবসময়
সত্য হবে। '=' চিহ্ন দিয়ে একটি ভেরিয়েবলে
নির্দিষ্ট কোনো মান রাখা হয়।
এবারে নিচের প্রোগ্রামটি দেখো:
#include <stdio.h>
int main()
{
int a = 50, b = 60, sum;
sum = a + b;
printf("%d + %d = %d", a, b,
sum);
return 0;
}
প্রোগ্রাম: ২.৫
প্রোগ্রামটি মনিটরে কী প্রিন্ট করে? চালিয়ে
দেখো। printf("%d + %d = %d", a, b, sum); না লিখে printf("%d + %d = %d", b, a, sum); লিখে প্রোগ্রামটি আবার চালাও। এখন জিনিসটি চিন্তা করে বুঝে নাও।
লেখাপড়া করার সময় আমাদের মনে নানা
বিষয়ে নানা প্রশ্ন আসে, যার উত্তর আমরা বইতে খুঁজি, শিক্ষককে
জিজ্ঞাসা করি, ইন্টারনেটে খুঁজি বা চিন্তা করে
যুক্তি দাঁড় করিয়ে উত্তরটি বের করি। আমাদের দুর্ভাগ্য যে বেশিরভাগ ছেলেমেয়েই শেষ কাজটি করে না, কারণ
নিজে নিজে চিন্তা করতে একটু সময় লাগে ও পরিশ্রম হয়, সেই
সময় আর শ্রম তারা দিতে চায় না। আর আমাদের অভিভাবক, শিক্ষক ও শিক্ষাব্যবস্থা চিন্তা
করার জন্য কোনো পুরস্কার দেয় না, বরং মুখস্থ করার জন্যই পুরস্কৃত করে।
যা-হোক, প্রোগ্রামিংয়ের
ব্যাপারে যখনই মনে কোনো প্রশ্ন আসবে, সঙ্গে সঙ্গে একটি প্রোগ্রাম লিখে
ফেলবে। দেখো
তোমার কম্পাইলার কী বলে। ধরা
যাক, আমরা যদি int টাইপের ভেরিয়েবলে দশমিক যুক্ত
সংখ্যা (বাস্তব সংখ্যা বা real number) ব্যবহার করতাম, তাহলে
কী হতো?
#include <stdio.h>
int main()
{
int a = 50.45, b = 60, sum;
sum = a + b;
printf("%d + %d = %d", a, b,
sum);
return 0;
}
প্রোগ্রাম: ২.৬
এখানে a-এর
মান 50.45 ব্যবহার করলাম। এবারে প্রোগ্রাম চালাও, দেখো কী হয়। আবার মনে যদি প্রশ্ন আসে যে, main ফাংশনের
শেষ লাইনে return 0; না লিখলে কী হয়? তাহলে return 0; ছাড়া
প্রোগ্রাম চালিয়ে দেখো কী হয়।
আউটপুট হবে: 50 + 60 = 110।
সি কম্পাইলার a-এর
মান 50 ধরেছে, যদিও আমরা 50.45 অ্যাসাইন
করেছি। এই
ব্যাপারটিকে বলে টাইপ কাস্ট (type cast)। বাস্তব সংখ্যা রাখার জন্য সি ভাষায়
double নামের ডাটা টাইপ রয়েছে। টাইপ কাস্ট করে double
সংখ্যাটিকে int-এ
নেওয়া হয়েছে, এটি অটোমেটিক হয়। আবার কম্পাইলারকে বলেও দেওয়া যায়:
int a = (int) 50.45।
int a = 50.99; এখানে
a-এর মান হবে 50। int a = -50.9; লিখলে
a-এর মান হয় -50। এক কথায় বললে double থেকে
int-এ টাইপ কাস্ট করলে দশমিকের পরের অংশটি বাদ পড়ে যাবে।
আরেকটি কথা। যেই ভেরিয়েবলকে টাইপ কাস্ট করা
হচ্ছে, তার মান কিন্তু পরিবর্তন হয় না। টাইপ কাস্ট করা মানটি একটি
ভেরিয়েবলে রাখা যায়। নিচের
প্রোগ্রামটি কম্পিউটারে চালালেই বুঝতে পারবে।
#include <stdio.h>
int main()
{
int n;
double x;
x = 10.5;
n = (int)x;
printf("Value of n is %d\n",
n);
printf("Value of x is %lf\n",
x);
return 0;
}
প্রোগ্রাম: ২.৭
প্রোগ্রামের আউটপুট দেখো। x-এর
মান কিন্তু পরিবর্তন হয়নি। আর বুঝতেই পারছ যে বাস্তব সংখ্যা রাখার জন্য সি-তে যে double টাইপের
ভেরিয়েবল ব্যবহার করা হয়, তা প্রিন্ট করার সময় %lf (l এখানে
ইংরেজি ছোট হাতের L) ব্যবহার করতে হয়।
int ডাটা
টাইপে তো কেবল পূর্ণ সংখ্যা রাখা যায়। কিন্তু সেটি কী যেকোনো পূর্ণসংখ্যা?
উত্তরের জন্য একটি
প্রোগ্রাম লিখি:
#include <stdio.h>
int main()
{
int a;
a = 1000;
printf("Value of a is %d",
a);
a = -21000;
printf("Value of a is %d",
a);
a = 10000000;
printf("Value of a is %d",
a);
a = -10000000;
printf("Value of a is %d",
a);
a = 100020004000503;
printf("Value of a is %d",
a);
a = -4325987632;
printf("Value of a is %d",
a);
return 0;
}
প্রোগ্রাম: ২.৮
এখানে আমরা a-তে
বিভিন্ন সংখ্যা অ্যাসাইন করলাম। সব মান কি ঠিকঠাক আসছে? আসেনি। কেন আসেনি সেটি ব্যাখ্যা করার আগে
একটি কথা বলে নিই। পরপর
এতগুলো printf-এর কারণে তোমার কম্পিউটারের স্ক্রিনে নিশ্চয়ই দেখতে একটু
অস্বস্তিকর লাগছে। প্রতিটি
printf তোমরা এভাবে লিখতে পারো: printf("Value
of a is %d\n", a);। এখন printf ফাংশনে
""-এর ভেতর \n লিখলে কী হয় সেটি আমি বলব না। প্রোগ্রামটি চালালেই বুঝতে পারবে।
a-এর
সবগুলো মান কিন্তু ঠিকভাবে দেখা যায়নি, যেসব মান -2147483648 থেকে
2147483647 পর্যন্ত কেবল সেগুলোই ঠিকঠাক প্রিন্ট হবে, কারণ
এই রেঞ্জের বাইরের সংখ্যা int টাইপের ভেরিয়েবলে রাখা যায় না। এটি হলো int টাইপের
সংখ্যার সীমা। সি-তে
int টাইপের ডাটার জন্য মেমোরিতে চার বাইট (byte) জায়গা
ব্যবহৃত হয়। চার
বাইট মানে বত্রিশ বিট (1 byte = 8 bit)। প্রতি বিটে দুটি জিনিস রাখা যায়, 0 আর 1। দুই
বিটে রাখা যায় চারটি সংখ্যা (00, 01, 10, 11)। তাহলে 32 বিটে
রাখা যাবে: 2^32 টা সংখ্যা অর্থাৎ 4294967296টি সংখ্যা। এখন অর্ধেক ধনাত্মক আর অর্ধেক
ঋণাত্মক যদি রাখি, তাহলে -2147483648 থেকে
-1 পর্যন্ত মোট 2147483648 সংখ্যা আবার 0 থেকে
2147483647 পর্যন্ত মোট 2147483648টি সংখ্যা, সর্বমোট
4294967296টি সংখ্যা। আশা করি, হিসাবটা বুঝতে পেরেছ।
এখন আমরা যোগ করার প্রোগ্রামটি লিখব
যেটি সব বাস্তব সংখ্যা (real number) যোগ করতে পারবে। তোমাদের মনে করিয়ে দিই, পূর্ণসংখ্যা
হচ্ছে, ... -3, -2, -1, 0, 1, 2, 3 ... ইত্যাদি। আর বাস্তব সংখ্যা হচ্ছে -5, -3, -2.43, 0, 0.49, 2.92 ইত্যাদি (সংখ্যারেখার ওপর সব সংখ্যাই কিন্তু বাস্তব সংখ্যা)।
#include <stdio.h>
int main()
{
double a, b, sum;
a = 9.5;
b = 8.743;
sum = a + b;
printf("Sum is: %lf\n", sum);
printf("Sum is: %0.2lf\n",
sum);
return 0;
}
প্রোগ্রাম: ২.৯
প্রোগ্রামটি কম্পাইল এবং রান করো। আউটপুট হবে নিচের দুই লাইন:
Sum is: 18.243000
Sum is: 18.24
%lf ব্যবহার
করায় প্রথম লাইনে দশমিকের পরে ছয় ঘর পর্যন্ত প্রিন্ট হয়েছে। আবার দ্বিতীয় লাইনে দশমিকের পরে
দুই ঘর পর্যন্ত প্রিন্ট হয়েছে, কারণ %0.2lf লিখেছি
(তিন ঘর পর্যন্ত প্রিন্ট করতে চাইলে %0.3lf
লিখতাম, আবার
দশমিক অংশ প্রিন্ট করতে না চাইলে %0.0lf)। double টাইপের
ডাটার জন্য 64 বিট ব্যবহৃত হয় এবং 1.7E-308
(1.7 x 10-308) থেকে
1.7E+308 (1.7 x 10308) পর্যন্ত ডাটা রাখা যায়। বিস্তারিত হিসাব বুঝতে হলে
কম্পিউটার বিজ্ঞানসংক্রান্ত আরও কিছু জ্ঞানবুদ্ধির দরকার, তাই
আমি আর এখন সেদিকে যাচ্ছি না।
এখন আমরা আমাদের প্রোগ্রামে এমন
ব্যবস্থা রাখতে চাই, যাতে কোন দুটি সংখ্যা যোগ করতে হবে
সেটি আমরা কোডের ভেতর লিখব না, ব্যবহারকারীর কাছ থেকে ইনপুট আকারে
জেনে নেব। ব্যবহারকারীর
(মানে যে প্রোগ্রামটি ব্যবহার করছে) কাছ থেকে ইনপুট নেওয়ার জন্য আমরা scanf ফাংশন
ব্যবহার করব (সি-তে আরও ফাংশন আছে এই কাজের জন্য)। তাহলে দেরি না করে প্রোগ্রাম লিখে
ফেলি:
#include <stdio.h>
int main()
{
int a, b, sum;
scanf("%d", &a);
scanf("%d", &b);
sum = a + b;
printf("Sum is: %d\n",
sum);
return 0;
}
প্রোগ্রাম: ২.১০
প্রোগ্রামটি রান করলে দেখবে ফাঁকা
স্ক্রিন (blank screen) আসে। তখন তুমি একটি সংখ্যা লিখবে, তারপর স্পেস (space) বা
এন্টার (enter) দিয়ে আরেকটি সংখ্যা লিখবে। তারপর আবার এন্টার চাপলে যোগফল দেখতে পাবে।
তোমরা নিশ্চয়ই scanf ফাংশনের
ব্যবহার শিখে ফেলেছ। scanf("%d",
&a); এখানে ডবল কোটেশনের ভেতরে %d দিয়ে
scanf-কে বলে দেওয়া হচ্ছে যে একটি ইন্টিজার বা int টাইপের
ভেরিয়েবলের মান পড়তে হবে (ব্যবহারকারী কিবোর্ড থেকে ইনপুট দেবে)। আর দেখো a-এর
আগে এমপারসেন্ড (&) চিহ্ন ব্যবহার করা হয়েছে, &a দিয়ে
বোঝানো হয়েছে যে সংখ্যাটি ইনপুট দেওয়া হবে সেটি a
ভেরিয়েবলের মাঝে অ্যাসাইন
হবে। তোমরা যখন সি আরেকটু ভালোভাবে শিখবে, তখন &a-এর
প্রকৃত অর্থ বুঝতে পারবে, আপাতত আমরা ব্যবহারের দিকেই মনোযোগ
দিই। a এবং b-এর
মান একটি scanf ফাংশন দিয়েও নেওয়া যেত এভাবে: scanf("%d
%d", &a, &b);। ভেরিয়েবলের আগে & চিহ্ন না দিলে কী সমস্যা? নিচের
প্রোগ্রামটি রান করার চেষ্টা করো, কিছু একটি এরর পাবে। এই মুহূর্তে এররটা ব্যাখ্যা করছি না, কারণ
ব্যাখ্যাটা একটু জটিল আর এখন বোঝাতে গেলে তোমরা ভুল বুঝতে পারো এবং পরে আমাকে
গালমন্দ করবে।
#include <stdio.h>
int main()
{
int a, b, sum;
scanf("%d", &a);
scanf("%d", b);
sum = a + b;
printf("Sum is: %d\n",
sum);
return 0;
}
প্রোগ্রাম: ২.১১
এখন আমরা যদি ইনপুট হিসেবে ইন্টিজার
না নিয়ে ডবল টাইপের ডাটা নিতে চাইতাম তাহলে কী করতে হতো? scanf-এ %d-এর
বদলে %lf ব্যবহার করলেই চলত। তোমরা প্রোগ্রামটি লিখে ফেলো এবং দেখো ঠিকঠাক রান হয় কি না। তারপরে বাকি অংশ পড়া শুরু করো।
আসলে ঠিকঠাক রান হবে না, কারণ
ডাটা টাইপও পরিবর্তন করতে হবে। মানে int না লিখে double লিখতে
হবে। প্রোগ্রামটি ঠিক করে আবার চালাও।
বইতে যখনই আমি কোনো প্রোগ্রাম লেখতে
বলব সেটি যত সহজ কিংবা কঠিনই মনে হোক না কেন, সেটি কম্পিউটারে লিখে কম্পাইল ও রান
করতে হবে। এ
কাজ না করে সামনে আগানো যাবে না। মনে রাখবে, গাড়ি চালানো শেখার জন্য যেমন গাড়ি
চালানোর কোনো বিকল্প নেই, সাঁতার শেখার জন্য যেমন সাঁতার
কাটার বিকল্প নেই, তেমনই প্রোগ্রামিং শেখার জন্য
প্রোগ্রামিং করার কোনো বিকল্প নেই, শুধু বই পড়ে প্রোগ্রামার হওয়া
যায় না।
এবারে আমরা আরেক ধরনের ডাটা টাইপ
দেখব, সেটি হচ্ছে char (character) টাইপ। তো এই character টাইপের
চরিত্র হচ্ছে একে মেমোরিতে রাখার জন্য মাত্র এক বাইট জায়গার দরকার হয়। সাধারণত যেকোনো অক্ষর বা চিহ্ন
রাখার জন্য এই টাইপের ডাটা ব্যবহার করা হয়। তবে সেই অক্ষরটা ইংরেজি বর্ণমালার অক্ষর হতে হবে, অন্য
ভাষার অক্ষর char টাইপের ভেরিয়েবলে রাখা যাবে না। নিচের প্রোগ্রামটি কম্পিউটারে লিখে
রান করাও:
#include <stdio.h>
int main()
{
char ch;
printf("Enter the first letter of
your name: ");
scanf("%c", &ch);
printf("The first letter of your name
is: %c\n", ch);
return 0;
}
প্রোগ্রাম: ২.১২
কোড দেখে বুঝতেই পারছ, char টাইপের
জন্য printf এবং scanf ফাংশনের ভেতরে %c ব্যবহার
করতে হয়। আরেকটি
ফাংশন আছে getchar, এটি দিয়েও char টাইপের ডাটা রিড করা যায়। নিচের প্রোগ্রামটি দেখো:
#include <stdio.h>
int main()
{
char ch;
printf("Enter the first letter of
your name: ");
ch = getchar();
printf("The first letter of your name
is: %c\n", ch);
return 0;
}
প্রোগ্রাম: ২.১৩
এটি রান করাও। আগের প্রোগ্রামটির মতো একই কাজ করবে। getchar ফাংশন
একটি অক্ষর পড়ে সেটি ch ভেরিয়েবলের ভেতরে অ্যাসাইন করে দিল। আর সরাসরি কোনো কিছু char টাইপ
ভেরিয়েবলে রাখতে চাইলে যেই অক্ষর বা চিহ্ন রাখবে তার দুই পাশে সিঙ্গেল কোটেশন
চিহ্ন দেবে। যেমন:
char c = 'A';
এখন নিচের প্রোগ্রামটি দেখো:
#include <stdio.h>
int main()
{
int num1, num2;
printf("Please enter a number:
");
scanf("%d", &num1);
printf("Please enter another number:
");
scanf("%d", &num2);
printf("%d + %d = %d\n", num1,
num2, num1+num2);
printf("%d - %d = %d\n", num1,
num2, num1-num2);
printf("%d * %d = %d\n", num1,
num2, num1*num2);
printf("%d / %d = %d\n", num1, num2,
num1/num2);
return 0;
}
প্রোগ্রাম: ২.১৪
এটি কম্পাইল ও রান করাও। এটি দেখে নিশ্চয়ই বুঝতে পারছ
বিয়োগ, গুণ ও ভাগের কাজ কীভাবে করতে হয়। এবারে তোমাদের কাজ হচ্ছে চারটি। এক,
num1 ও num2-এর
মধ্যেকার যোগ, বিয়োগ, গুণ, ভাগের
কাজটি printf ফাংশনের ভেতরে না করে আগে করা এবং মানটি অন্য একটি ভেরিয়েবলে রেখে
দেওয়া। এর
জন্য একটি প্রোগ্রাম লিখে ফেলো। দ্বিতীয় কাজ হচ্ছে প্রোগ্রামটি ডবল টাইপের ভেরিয়েবল ব্যবহার করে
করো। তৃতীয় কাজ হচ্ছে, num2-এর
মান 0 দিয়ে দেখো কী হয়। চতুর্থ কাজটি হচ্ছে printf
ফাংশনের ভেতরে ডবল কোটেশনের
ভেতরে যেই +, -, *, / চিহ্ন আছে সেগুলো সরাসরি ব্যবহার না করে একটি char টাইপ
ভেরিয়েবলে রেখে তারপর ব্যবহার করা। চারটি কাজ ঠিকমতো করার পরে নিচের প্রোগ্রামটি দেখো:
#include <stdio.h>
int main()
{
int num1, num2, value;
char sign;
printf("Please enter a number:
");
scanf("%d", &num1);
printf("Please enter another number:
");
scanf("%d", &num2);
value = num1 + num2;
sign = '+';
printf("%d %c %d = %d\n", num1,
sign, num2, value);
value = num1 - num2;
sign = '-';
printf("%d %c %d = %d\n", num1,
sign, num2, value);
value = num1 * num2;
sign = '*';
printf("%d %c %d = %d\n", num1,
sign, num2, value);
value = num1 / num2;
sign = '/';
printf("%d %c %d = %d\n", num1,
sign, num2, value);
return 0;
}
প্রোগ্রাম: ২.১৫
প্রোগ্রামটি দেখলেই বুঝতে পারবে কী
কাজ করে। তবে
শুধু দেখে বুঝলেই হবে না। কোড
করে কম্পাইল ও রান করো।
সি ল্যাঙ্গুয়েজে আরও বেশ কিছু ডাটা
টাইপ রয়েছে। ইনপুট
ও আউটপুটের জন্যও রয়েছে নানা পদ্ধতি, যা তোমরা আস্তে আস্তে শিখবে (সব
হয়তো এ বইয়ে থাকবে না, সি-এর অন্য বই পড়লে জানতে পারবে)। আপাতত যা শিখেছ, তা
দিয়েই তোমরা অনেক প্রোগ্রাম লিখে ফেলতে পারবে।
এখন একটি মজার এবং দরকারি জিনিস বলে
রাখি। প্রোগ্রামের কোডের ভেতরে তুমি নিজের
ভাষাও ব্যবহার করতে পারো। এটিকে
বলে কমেন্ট (comment) করা। কম্পাইলার কমেন্টগুলোকে প্রোগ্রামের
অংশ ধরবে না। এক
লাইনের কমেন্ট হলে // চিহ্ন দিয়ে কমেন্ট শুরু করতে পারো। আর একাধিক লাইন থাকলে /* দিয়ে শুরু
এবং */ দিয়ে শেষ করতে হবে। নিচের প্রোগ্রামটি কিন্তু ঠিকঠাক কম্পাইল ও রান হবে।
#include <stdio.h>
int main()
{
// test program - comment 1
printf("Hello ");
/* We have printed Hello,
now we shall print World.
Note that this is a multi-line comment
*/
printf("World"); // printed
world
return 0;
}
প্রোগ্রাম: ২.১৬
এবারে একটি প্রশ্ন, (যেটি সি-এর টেক্সট বইয়ে এই চ্যাপ্টারের শুরুতেই বলে দিত), ভেরিয়েবলগুলোর নামকরণের নিয়মকানুন কী? ভেরিয়েবলের নাম এক বা একাধিক অক্ষরের হতে পারে, অক্ষরগুলো হতে পারে a থেকে z, A থেকে Z, 0 থেকে 9 এবং _ (আন্ডারস্কোর বা আন্ডারবার)। তবে একাধিক অক্ষরের ক্ষেত্রে প্রথম অক্ষরটা অঙ্ক
(ডিজিট) হতে পারবে না। তুমি একটি প্রোগ্রামে int 7d; লিখে দেখো কম্পাইলার কী বলে। আর ভেরিয়েবলের নামগুলো অর্থপূর্ণ হলে ভালো হয়। যেমন, যোগফল রাখার জন্য ভেরিয়েবলের নাম sum হলেই ভালো, যদিও y নাম দিলেও প্রোগ্রাম চলে। অর্থপূর্ণ নাম দিলে বুঝতে সুবিধা হয়, ভেরিয়েবলটা কী উদ্দেশ্যে ব্যবহার করা হয়েছে।
[প্রোগ্রামিং
বইঃ অধ্যায় তিন] কন্ডিশনাল লজিক।
তোমরা অনেকেই হয়তো জানো যে 'চাচা
চৌধুরীর বুদ্ধি কম্পিউটারের চেয়েও প্রখর'! এটি শুনে প্রথম প্রথম চাচা চৌধুরীর
ওপর ভক্তি-শ্রদ্ধা অনেক বেড়ে গেলেও একটু চিন্তা করলেই তোমরা বুঝতে পারবে যে আসলে
তোমাদের সবার বুদ্ধি কম্পিউটারের চেয়ে প্রখর। আসলে কম্পিউটারের তো কোনো বুদ্ধিই
নেই। প্রোগ্রামাররা যেভাবে প্রোগ্রাম
লিখে দেয় কম্পিউটার সেভাবে কাজ করে। এখন আমরা প্রোগ্রামিংয়ের সহজ অথচ খুব গুরুত্বপূর্ণ একটি বিষয়
শিখব। সেটি হচ্ছে কন্ডিশনাল লজিক। কোন শর্তে কী করতে হবে সেটি
প্রোগ্রাম লিখে কম্পিউটারকে বোঝাতে হবে। কথা না বাড়িয়ে আমরা প্রোগ্রাম লেখা শুরু করে দিই। তোমরা কিন্তু অবশ্যই প্রতিটি
প্রোগ্রাম কম্পিউটারে চালিয়ে দেখবে।
#include <stdio.h>
int main()
{
int n;
n = 10;
if(n >= 0) {
printf("The number is
positive\n");
}
else {
printf("The number is
negative\n");
}
return 0;
}
প্রোগ্রাম: ৩.১
ওপরের প্রোগ্রামটির কাজ কী? n-এর
বিভিন্ন মান (যেমন: 0, -10, -2, 5, 988 ইত্যাদি) বসিয়ে তোমরা প্রোগ্রামটি
চালাও। দেখা
যাচ্ছে যে এর কাজ হচ্ছে n ধনাত্মক (positive) না
ঋণাত্মক (negative) সেটি নির্ণয় করা। কোন সংখ্যা ধনাত্মক হতে গেলে একটি শর্ত পূরণ করতে হয়। সেটি হচ্ছে তাকে শূন্যের সমান বা
তার চেয়ে বড় হতে হয়। তাহলে
আমাদের লজিকটি দাঁড়াচ্ছে এ রকম যে, 'n যদি শূন্যের সমান বা বড় হয়, তবে nধনাত্মক, না
হলে n ঋণাত্মক'। এই ব্যাপারটি সি ল্যাঙ্গুয়েজে
প্রকাশ করতে হয় if এবং তার সঙ্গে else ব্যবহার
করে। if-এর
ভেতর একটি শর্ত (কন্ডিশন) লিখে দিতে হয় যা সত্যি হলেই কেবল তার ভেতরের অংশের কাজ
হয় (মানে if-এর পর যে দ্বিতীয় বন্ধনী { } ব্যবহার করা হয়েছে তার ভেতরের সব
কাজ)। আর কন্ডিশনটা লিখতে হয় প্রথম
বন্ধনীর ভেতরে। if-এর ভেতরে যেই কন্ডিশনটা আছে সেটি
যদি মিথ্যা হয়, তবে else-এর ভেতরের (দ্বিতীয় বন্ধনীর ভেতরে)
অংশের কাজ হয়। সব
প্রোগ্রামিং ল্যাঙ্গুয়েজেই এটি আছে, তবে লিখার ধরন হয়তো আলাদা।
এখন আমাদের দেখতে হবে, কন্ডিশনগুলো
কীভাবে লিখতে হবে? তোমরা এতক্ষণে জেনে গেছ যে 'বড়
কিংবা সমান' এই তুলনা করার জন্য
>= চিহ্ণ ব্যবহার করা হয়। 'ছোট
কিংবা সমান'-এর জন্য ব্যবহার করে
<= চিহ্ন। দুটি সংখ্যা একটি আরেকটির সমান কি
না সেটি পরীক্ষার জন্য ব্যবহার করে == চিহ্ন (লক্ষ করো এখানে দুটি সমান চিহ্ন আছে। শুরুর দিকে অনেকেই সমান কি না
পরীক্ষার জন্য ভুল করে = (একটি সমান চিহ্ন যা দিয়ে আসলে কোনো ভেরিয়েবলে কোনোকিছু
অ্যাসাইন করা হয়) ব্যবহার করে বিপদে পড়ে যায়)। দুটি সংখ্যা পরস্পর অসমান কি না, এটি
পরীক্ষার জন্য != চিহ্ন ব্যবহার করে। আর ছোট কিংবা বড় পরীক্ষার জন্য
< আর > চিহ্ন
ব্যবহার করতে হয়। আরও
ব্যাপার-স্যাপার আছে। একবারে
সব না শিখে চলো আস্তে আস্তে প্রোগ্রাম লিখে শেখা যাক। এখানে ইন্ডেন্টেশনের ব্যাপারটিও
কিন্তু খেয়াল কোরো। if কিংবা else-এর
ভেতরের ব্লকের সব লাইন কিন্তু if বা else
যেখানে শুরু, তার
চার ঘর (চারটি স্পেস) ডান থেকে শুরু হয়েছে।
আমরা ওপরের প্রোগ্রামটি এভাবেও
লিখতে পারতাম:
#include <stdio.h>
int main()
{
int n;
n = 10;
if(n < 0) {
printf("The number is
negative\n");
}
else {
printf("The number is
positive\n");
}
return 0;
}
প্রোগ্রাম: ৩.২
এখানে আমরা প্রথমে পরীক্ষা করেছি যে
n শূন্যের চেয়ে ছোট কি না। যদি ছোট হয়, তবে n
নেগেটিভ; আর
সেটি না হলে (সেটি না হওয়া মানে n অবশ্যই শূন্যের সমান বা বড়) n পজিটিভ।
তোমাদের মধ্যে যারা একটু খুঁতখুঁতে
স্বভাবের, তারা নিশ্চয়ই ভাবছ যে শূন্য তো আসলে পজিটিভ বা নেগেটিভ কোনোটাই না। শূন্যের চেয়ে বড় সব সংখ্যা হচ্ছে
পজিটিভ আর ছোট সব সংখ্যা হচ্ছে নেগেটিভ। কম্পিউটারকে সেটি বোঝাতে গেলে আমরা নিচের প্রোগ্রামটি
লিখতে পারি:
#include <stdio.h>
int main()
{
int n = 10;
if(n < 0) {
printf("The number is
negative\n");
}
else if (n > 0) {
printf("The number is
positive\n");
}
else if (n == 0) {
printf("The number is
zero!\n");
}
return 0;
}
প্রোগ্রাম: ৩.৩
প্রোগ্রামটি একটু ব্যাখ্যা করা যাক:
if(n < 0): এখানে
আমরা প্রথমে পরীক্ষা করেছি n শূন্যের চেয়ে ছোট কি না । ছোট হলে তো কথাই নেই। আমরা বলে দিচ্ছি যে সংখ্যাটি
নেগেটিভ। else if(n > 0): আর যদি ছোট না হয়, তবে n শূন্যের
চেয়ে বড় কি না সেটি পরীক্ষা করেছি if(n
> 0)। এই
শর্ত সত্যি হলে সংখ্যাটি পজিটিভ।
else if(n == 0): আর n > 0ও যদি সত্যি না হয় তবে কোন শর্তটি
বাদ রইল? দুটি সমান কি না সেটি পরীক্ষা করা। তাহলে আমরা পরীক্ষা করছি যে n শূন্যের
সমান কি না এবং সমান হলে বলে দিচ্ছি যে এটি শূন্য।
দুটি সংখ্যা তুলনা করার সময়
প্রথমটা যদি দ্বিতীয়টির চেয়ে বড় না হয়, ছোটও না হয়, তবে
তারা অবশ্যই সমান। তাই
তৃতীয় কন্ডিশনটা আসলে আমাদের দরকার নেই। আমরা প্রথম দুটি কন্ডিশন মিথ্যা হলেই বলে দিতে পারি যে n-এর
মান শূন্য।
#include <stdio.h>
int main()
{
int n = 10;
if(n < 0) {
printf("The number is
negative\n");
}
else if (n > 0) {
printf("The number is
positive\n");
}
else {
printf("The number is
zero!\n");
}
return 0;
}
প্রোগ্রাম: ৩.৪
আবার সব সময় যে if ব্যবহার
করলেই সঙ্গে else কিংবা else if ব্যবহার
করতে হবে, এমন কোনো কথা নেই। নিচের প্রোগ্রামটি দেখো:
#include <stdio.h>
int main()
{
int number = 12;
if(number > 10) {
printf("The number is greater
than ten\n");
}
return 0;
}
প্রোগ্রাম: ৩.৫
এখানে কেবল দেখা হচ্ছে যে সংখ্যাটির
মান কি দশের চেয়ে বড় কি না।
নিচের প্রোগ্রামটি দেখে বলো তো
আউটপুট কী হবে?
#include <stdio.h>
int main()
{
int n = 10;
if (n < 30) {
printf("n is less than
30.\n");
}
else if(n < 50) {
printf("n is less than
50.\n");
}
return 0;
}
প্রোগ্রাম: ৩.৬
আউটপুট হবে: n is less than 30. যদিও else if(n < 50) এটিও সত্য কিন্তু যেহেতু if (n < 30) সত্য
হয়ে গেছে, তাই এর সঙ্গে বাকি যত else
if কিংবা else থাকবে, সেগুলো
আর পরীক্ষা করা হবে না। এখন
তোমরা নিশ্চয়ই নিচের প্রোগ্রামটির আউটপুট বলতে পারবে।
#include <stdio.h>
int main()
{
int n = 10;
if (n < 30) {
printf("n is less than
30.\n");
}
if(n < 50) {
printf("n is less than
50.\n");
}
return 0;
}
প্রোগ্রাম: ৩.৭
এখন আমরা আরেকটি প্রোগ্রাম লিখব। কোনো সংখ্যা জোড় না বেজোড় সেটি
নির্ণয় করার প্রোগ্রাম। কোনো
সংখ্যা জোড় কি না সেটি বোঝার উপায় হচ্ছে সংখ্যাটিকে 2দিয়ে
ভাগ করা। যদি
ভাগশেষ শূন্য হয়, তবে সংখ্যাটি জোড়; আর
ভাগশেষ শূন্য না হয়ে এক হলে সেটি বেজোড়। সি ল্যাঙ্গুয়েজে ভাগশেষ বের করার জন্য মডুলাস অপারেটর (modulus operator) আছে, যেটাকে '%' চিহ্ন
দিয়ে প্রকাশ করা হয়। তাহলে
আর চিন্তা নেই।
শুরুতে একটি সংখ্যা নেব: int number;
এবারে number-এর
জন্য একটি মান ঠিক করি: number = 5;
এখন numberকে 2
দিয়ে ভাগ করলে যে ভাগশেষ
পাব সেটি বের করি: remainder = number % 2;
এখন if-এর সাহায্যে remainder-এর
মান পরীক্ষা করে আমরা সিদ্ধান্তে পৌঁছে যেতে পারি। remainder-এর
কেবল দুটি মানই সম্ভব– 0 আর 1। পুরো প্রোগ্রামটি লিখে ফেলি:
#include <stdio.h>
int main()
{
int number, remainder;
number = 5;
remainder = number % 2;
if(remainder == 0) {
printf("The number is
even\n");
}
else {
printf("The number is
odd\n");
}
return 0;
}
প্রোগ্রাম: ৩.৮
প্রোগ্রামটি remainder ভেরিয়েবল
ব্যবহার না করেও লেখা যায়:
#include <stdio.h>
int main()
{
int
number = 9;
if(number % 2 == 0) {
printf("The number is
even\n");
}
else {
printf("The number is
odd\n");
}
return 0;
}
প্রোগ্রাম: ৩.৯
আচ্ছা, আমাদের
যদি কেবল জোড় সংখ্যা নির্ণয় করতে হতো, তাহলে আমরা কী করতাম? else ব্লকটা
বাদ দিয়ে দিতাম।
তোমাদের জন্য এখন একটি ছোট্ট
পরীক্ষা। মডুলাস
অপারেটর ব্যবহার না করে ভাগশেষ বের করতে পারবে? একবার করে গুণ, ভাগ
ও বিয়োগ (*, /, -) ব্যবহার করে কিন্তু কাজটি করা যায়। তোমরা সেটি করার চেষ্টা করতে পারো।
এবার আরেকটি প্রোগ্রাম দেখা যাক। কোনো একটি অক্ষর ছোট হাতের (small letter বা
lower case letter) নাকি বড় হাতের (capital letter বা
upper case letter), সেটি বের করতে হবে। এর জন্য সবচেয়ে সহজ সমাধানটা হতে
পারে এই রকম যে আমরা একটি character টাইপের ভেরিয়েবলের ভেতরে অক্ষরটা
রাখতে পারি। তারপর
একে একে সেটিকে 26টি lower
case letter এবং 26টি upper case letter-এর সঙ্গে তুলনা করে দেখতে পারি। যখনই মিলে যাবে, তখনই
বলে দেওয়া যায়, অক্ষরটা কোন ধরনের।
char ch = 'p';
if (ch == 'a')
{
printf("%c is lower case\n",
ch);
}
else if (ch == 'A')
{
printf("%c is upper case\n",
ch);
}
else if (ch == 'b')
{
printf("%c is lower case\n",
ch);
}
else if (ch == 'B')
{
printf("%c is upper case\n",
ch);
}
else if (ch == 'c')
{
printf("%c is lower case\n",
ch);
}
else if (ch == 'C')
{
printf("%c is upper case\n",
ch);
}
… এভাবে
চলবে।
কিন্তু এই সমস্যার সমাধান করার জন্য
এত কোড লিখার কোনো দরকার নেই। এটি সহজে করার জন্য আমাদের জানতে হবে এন্ড অপারেটরের (AND operator) ব্যবহার। সি ল্যাঙ্গুয়েজে একে '&&' চিহ্ন
দিয়ে প্রকাশ করা হয়। নিচের
কোডটি দেখলেই তোমরা এর কাজ বুঝে যাবে।
#include <stdio.h>
int main()
{
char ch = 'W';
if(ch >= 'a' && ch <= 'z')
{
printf("%c is lower case\n",
ch);
}
if(ch >= 'A' && ch <= 'Z')
{
printf("%c is upper case\n",
ch);
}
return 0;
}
প্রোগ্রাম: ৩.১০
'&&'-এর
বাঁ পাশে একটি কন্ডিশন এবং ডান পাশে একটি কন্ডিশন থাকবে, এবং
দুটি কন্ডিশন সত্য হলেই সম্পূর্ণ কন্ডিশনটা সত্য হবে। ch >= 'a' && ch <= 'z' এটি পুরোটা একটি কন্ডিশন। এখন
&&-এর বাঁ দিকে একটি কন্ডিশন
আছে ch >= 'a' আর ডানদিকে আরেকটি কন্ডিশন ch
<= 'z'। দুটি
কন্ডিশনই যদি সত্য হয়, তবে পুরো কন্ডিশনটা সত্য হবে। এখন কম্পিউটার প্রতিটি অক্ষর বোঝার
জন্য যেই কোড ব্যবহার করে তাতে a-এর চেয়ে b-এর
মান এক বেশি, b-এর চেয়ে c-এর মান এক বেশি, c-এর
চেয়ে d-এর মান এক বেশি … এরকম। তাই কোনো অক্ষর lower case হলে
সেটি অবশ্যই 'a'-এর সমান কিংবা বড় হতে হবে। আবার সেটি 'z'-এর
সমান কিংবা ছোট হতে হবে। একইভাবে
A-এর চেয়ে B-এর মান এক বেশি, B-এর
চেয়ে C-এর মান এক বেশি … এরকম। তাই কোনো ক্যারেক্টারের মান 'A' থেকে
'Z'-এর মধ্যে হলে আমরা বলতে পারি যে সেটি upper case। 'A'-এর সমান কিংবা বড় হতে হবে এবং 'Z'-এর
সমান কিংবা ছোট হতে হবে। আরেকটি
ব্যাপার। দ্বিতীয়
if-এর আগে else ব্যবহার করা উচিত। তাহলে কম্পাইলার প্রথম if-এর
ভেতরের শর্ত সত্য হলে আর পরের if-এর কন্ডিশন পরীক্ষা করবে না। তাতে সময় বাঁচবে।
#include <stdio.h>
int main()
{
char ch = 'k';
if(ch >= 'a' && ch <= 'z')
{
printf("%c is lower case\n",
ch);
}
else if(ch >= 'A' && ch <=
'Z') {
printf("%c is upper case\n",
ch);
}
return 0;
}
প্রোগ্রাম: ৩.১১
আশা করি, তোমরা
'&&'-এর ব্যবহার বুঝে গেছ।
এখন আরেকটি অপারেটরের ব্যবহার দেখব। সেটি হচ্ছে অর (OR)। একে
প্রকাশ করা হয় '||' চিহ্ন দিয়ে (পরপর দুটি |)। '&&'-এর ক্ষেত্রে যেমন দুই পাশের শর্ত
সত্য হলেই সম্পূর্ণ শর্ত সত্য হয়,
'||'-এর ক্ষেত্রে যেকোনো এক
পাশের শর্ত সত্য হলেই সম্পূর্ণ শর্ত সত্য হয়।
নিচের প্রোগ্রামটির আউটপুট কী হবে? কোড
দেখে বলতে না পারলে প্রোগ্রামটি চালাও।
#include <stdio.h>
int main()
{
int num = 5;
if(num >= 1 || num <= 10) {
printf("yes\n");
}
else {
printf("no\n");
}
return 0;
}
প্রোগ্রাম: ৩.১২
এটির আউটপুট হবে yes। এখন num-এর
মান 50 করে দাও। আউটপুট
কী হবে?
এবারেও আউটপুট yesই
হবে। কারণ num-এর
মান 50 হলে, প্রথম শর্তটি সত্য হবে (num >= 1) আর
দ্বিতীয় শর্তটি (n <= 10) মিথ্যা হবে। তবে আমরা যেহেতু দুটি শর্তের মাঝে '||' ব্যবহার
করেছি, তাই যেকোনো একটি শর্ত সত্য হলেই সম্পূর্ণ শর্তটি সত্য হবে। এখন আরও একটি সমস্যা। কোনো অক্ষর vowel নাকি
consonant, সেটি নির্ণয় করতে হবে। আমরা জানি, vowelগুলো হচ্ছে a, e, i, o, u। এখন কোনো ক্যারেক্টার এই পাঁচটির মধ্যে পড়ে কি না সেটি নির্ণয়
করার জন্য যদি আমরা এমন শর্ত দিই: ch
>= 'a' && ch <= 'u' তাহলে কিন্তু হবে না। কারণ তাহলে a থেকে u পর্যন্ত
সব অক্ষরের জন্যই শর্তটি সত্যি হবে কিন্তু আমাদের দরকার নির্দিষ্ট কিছু অক্ষর। তাই শর্তটি আমরা এভাবে লিখতে পারি:
if(ch == 'a' || ch == 'e' || ch == 'i' || ch
== 'o' || ch == 'u') {
printf("%c is vowel\n",
ch);
}
else {
printf("%c is consonant\n",
ch);
}
তাহলে এবার সম্পূর্ণ প্রোগ্রামটি
তোমরা লিখে ফেলতে পারো।
#include
int main()
{
int m, n, p ;
printf("Type the multiplier");
scanf("%d", &m);
printf("Type how many times you want to multiply");
scanf("%d", &n);
p = 1;
while(p <= n) {
printf("%d X %d = %d\n", m, p, m*p);
p ++;
}
return 0;
}
int main()
{
int m, n, p ;
printf("Type the multiplier");
scanf("%d", &m);
printf("Type how many times you want to multiply");
scanf("%d", &n);
p = 1;
while(p <= n) {
printf("%d X %d = %d\n", m, p, m*p);
p ++;
}
return 0;
}
[প্রোগ্রামিং
বইঃ অধ্যায় পাঁচ] একটুখানি গণিত।
এই অধ্যায়ে আমরা প্রোগ্রামিংয়ের নতুন কিছু শিখব না। এখন পর্যন্ত আমরা যতটুকু
প্রোগ্রামিং শিখেছি, তা দিয়েই কিছু সহজ-সরল গাণিতিক
সমস্যার সমাধান করব।
১) x + y = 15, x – y = 5 হলে x ও y-এর মান কত?
সমীকরণদুটি যোগ করলে পাই 2x = 20, বা x = 10। আবার বিয়োগ করলে পাই, 2y = 10, বা y = 5। এখন একটি প্রোগ্রাম লিখতে হবে যেখানে x + y ও x – y-এর মান দেওয়া থাকবে, x ও y-এর মান বের করতে হবে। আমি প্রোগ্রামটি একটু পরে লিখে দেব। এর মধ্যে তুমি নিজে লিখার চেষ্টা করো। সহজ প্রোগ্রাম।
২) 4x + 5y = 14, 5x + 6y = 17 হলে x ও y-এর মান কত?
সমীকরণদুটিকে আমরা এভাবে লিখতে পারি:
a1x + b1y = c1, a2x + b2y = c2। তোমরা বিভিন্নভাবে এর সমাধান করতে পার। এর মধ্যে দুটি জনপ্রিয় উপায় হচ্ছে প্রতিস্থাপন (substitution) ও নির্ণায়কের (determinant) সাহায্যে সমাধান। পদ্ধতিগুলো জানা না থাকলে ক্লাস এইট বা নাইনের গণিত বই দেখো। সমাধান করলে দেখবে,
x = (b2c1 – b1c2) / (a1b2 – a2b1) এবং y = (a1c2 – a2c1) / (a1b2 – a2b1)। এখন a1, a2, b1, b2, c1, c2-এর জায়গায় নির্দিষ্ট মান বসিয়ে দিলেই x ও y-এর মান পেয়ে যাবে।
এই ধরনের সমীকরণ সমাধানের জন্যও আমরা একটি প্রোগ্রাম লিখব, যার ইনপুট হবে a1, a2, b1, b2, c1, c2 এবং আউটপুট হবে x ও y-এর মান। এটিও সহজ প্রোগ্রাম। নিজে চেষ্টা করো।
আশা করি, তোমরা দুটি সমস্যারই সমাধান নিজে করে ফেলতে পারবে। এখন আমি প্রথম সমস্যার কোড দিচ্ছি:
১) x + y = 15, x – y = 5 হলে x ও y-এর মান কত?
সমীকরণদুটি যোগ করলে পাই 2x = 20, বা x = 10। আবার বিয়োগ করলে পাই, 2y = 10, বা y = 5। এখন একটি প্রোগ্রাম লিখতে হবে যেখানে x + y ও x – y-এর মান দেওয়া থাকবে, x ও y-এর মান বের করতে হবে। আমি প্রোগ্রামটি একটু পরে লিখে দেব। এর মধ্যে তুমি নিজে লিখার চেষ্টা করো। সহজ প্রোগ্রাম।
২) 4x + 5y = 14, 5x + 6y = 17 হলে x ও y-এর মান কত?
সমীকরণদুটিকে আমরা এভাবে লিখতে পারি:
a1x + b1y = c1, a2x + b2y = c2। তোমরা বিভিন্নভাবে এর সমাধান করতে পার। এর মধ্যে দুটি জনপ্রিয় উপায় হচ্ছে প্রতিস্থাপন (substitution) ও নির্ণায়কের (determinant) সাহায্যে সমাধান। পদ্ধতিগুলো জানা না থাকলে ক্লাস এইট বা নাইনের গণিত বই দেখো। সমাধান করলে দেখবে,
x = (b2c1 – b1c2) / (a1b2 – a2b1) এবং y = (a1c2 – a2c1) / (a1b2 – a2b1)। এখন a1, a2, b1, b2, c1, c2-এর জায়গায় নির্দিষ্ট মান বসিয়ে দিলেই x ও y-এর মান পেয়ে যাবে।
এই ধরনের সমীকরণ সমাধানের জন্যও আমরা একটি প্রোগ্রাম লিখব, যার ইনপুট হবে a1, a2, b1, b2, c1, c2 এবং আউটপুট হবে x ও y-এর মান। এটিও সহজ প্রোগ্রাম। নিজে চেষ্টা করো।
আশা করি, তোমরা দুটি সমস্যারই সমাধান নিজে করে ফেলতে পারবে। এখন আমি প্রথম সমস্যার কোড দিচ্ছি:
#include <stdio.h>
int main()
{
double x, y, x_plus_y, x_minus_y;
printf("Enter the value of x + y:
");
scanf("%lf",
&x_plus_y);
printf("Enter the value of x - y:
");
scanf("%lf",
&x_minus_y);
x = (x_plus_y + x_minus_y) / 2;
y = (x_plus_y - x_minus_y) / 2;
printf("x = %0.2lf, y =
%0.2lf\n", x, y);
return 0;
}
প্রোগ্রাম: ৫.১
সমাধান খুবই সহজ। তবে লক্ষ করো যে আমি ভেরিয়েবলের ডাটা টাইপ int ব্যবহার না করে double ব্যবহার করেছি।
এবারে দ্বিতীয় সমস্যার কোড:
#include <stdio.h>
int main()
{
double a1, a2, b1, b2, c1, c2, x, y;
printf("a1 = ");
scanf("%lf", &a1);
printf("a2 = ");
scanf("%lf", &a2);
printf("b1 = ");
scanf("%lf", &b1);
printf("b2 = ");
scanf("%lf", &b2);
printf("c1 = ");
scanf("%lf", &c1);
printf("c2 = ");
scanf("%lf", &c2);
x = (b2 * c1 - b1 * c2) / (a1 * b2 - a2 *
b1);
y = (a1 * c2 - a2 * c1) / (a1 * b2 - a2 *
b1);
printf("x = %0.2lf, y =
%0.2lf\n", x, y);
return 0;
}
প্রোগ্রাম: ৫.২
এটিও সহজ প্রোগ্রাম! তবে তোমরা দেখো (a1 * b2 - a2 * b1)-এর মান আমি দুবার বের করেছি (x-এর মান বের করার সময়, আবার y-এর মান বের করার সময়)। কাজটি একবারেই করা যেত এবং একবারে করলেই ভালো, তাহলে আমাদের প্রোগ্রাম দুটি গুণ ও একটি বিয়োগের কাজ কম করবে। আবার (a1 * b2 - a2 * b1)-এর মান যদি শূন্য হয়, তাহলে একটি ঝামেলা হয়ে যাচ্ছে, কারণ কোনো কিছুকে তো শূন্য দিয়ে ভাগ করা যায় না। তাই ওই মানটি শূন্য হলে আসলে সমীকরণের কোনো সমাধান নেই। এবার প্রোগ্রামটি আরও ভালোভাবে লিখে ফেলি।
#include <stdio.h>
int main()
{
double a1, a2, b1, b2, c1, c2, d, x,
y;
printf("a1 = ");
scanf("%lf", &a1);
printf("a2 = ");
scanf("%lf", &a2);
printf("b1 = ");
scanf("%lf", &b1);
printf("b2 = ");
scanf("%lf", &b2);
printf("c1 = ");
scanf("%lf", &c1);
printf("c2 = ");
scanf("%lf", &c2);
d = a1 * b2 - a2 * b1;
if ((int) d == 0) {
printf("Value of x and y can not
be determined.\n");
}
else {
x = (b2 * c1 - b1 * c2) / d;
y = (a1 * c2 - a2 * c1) / d;
printf("x = %0.2lf, y =
%0.2lf\n", x, y);
}
return 0;
}
প্রোগ্রাম: ৫.৩
এখানে একটি ব্যাপার খেয়াল করো। আমি if-এর ভেতর লিখেছি (int) d == 0। এখানে আমি প্রথমে d (যা একটি double টাইপের ভেরিয়েবল)-কে ইন্টিজারে টাইপ কাস্ট করে তারপর তার মানটি 0-এর সমান কি না তা পরীক্ষা করেছি। পরীক্ষাটা এভাবেও করা যেত: if (d == 0.0) তবে এতে মাঝে মাঝে ঝামেলা হয়, ফ্লোটিং পয়েন্ট-সংক্রান্ত হিসাব-নিকাশের জন্য। তোমরা কম্পিউটার আর্কিটেকচার নিয়ে লেখাপড়া করলে বিষয়টা বুঝতে পারবে।
তোমাদের মনে একটি প্রশ্ন আসতে পারে যে এই সহজ সমস্যাগুলো প্রোগ্রামিং করে সমাধান করে কী লাভ? আসলে একবার প্রোগ্রাম লিখে ফেলার পরে কিন্তু আর সমাধান করতে হয় না। তারপর শুধু ইনপুট দেবে, প্রোগ্রামটি নিজেই সমস্যার সমাধান করে তোমাকে আউটপুট দেবে।
৩) আমি যদি তোমাকে দশ হাজার টাকা ঋণ দিই 35% সুদে এবং টাকাটা পাঁচ বছর সময়ের মধ্যে তোমাকে সুদে-আসলে পরিশোধ করতে বলি, তাহলে পাঁচ বছরে মোট কত টাকা তোমার দিতে হবে এবং প্রতি মাসে কত টাকা দিতে হবে? ঋণটা যদি জটিল কিছু না হয়, তাহলে তোমার মোট পরিশোধ করতে হবে 10000 + 10000 * 35 / 100 টাকা। এই সহজ-সরল ঋণের জন্য একটি প্রোগ্রাম লিখে ফেলা যাক:
#include <stdio.h>
int main()
{
double loan_amount, interest_rate,
number_of_years, total_amount, monthly_amount;
printf("Enter the loan amount:
");
scanf("%lf",
&loan_amount);
printf("Enter the interest rate:
");
scanf("%lf",
&interest_rate);
printf("Number of years:
");
scanf("%lf",
&number_of_years);
total_amount = loan_amount + loan_amount *
interest_rate / 100.00;
monthly_amount = total_amount /
(number_of_years * 12);
printf("Total amount: %0.2lf\n",
total_amount);
printf("Monthly amount:
%0.2lf\n", monthly_amount);
return 0;
}
প্রোগ্রাম: ৫.৪
আমাদের ফর্মুলাতে একটু সমস্যা আছে। আসলে 35% সুদ দিতে হলে সেটা বাৎসরিক সুদ হবে। অর্থাৎ প্রতি বছর মোট ঋণের উপর 35% সুদ দেওয়া লাগবে। তাহলে দেখা যাচ্ছে পাঁচ বছরে তোমার মোট পরিশোধ করতে হবে 10000 + 10000 * 35 * 5 / 100 টাকা। এখন এই ফর্মুলা অনুযায়ী প্রোগ্রাম লিখে ফেলো।
তবে বাস্তবে ঋণের হিসাব-নিকাশ কিন্তু এত সরল নয়। তুমি ব্যাংক থেকে ঋণ নিতে গেলেই সেটি টের পাবে।
৪) পদার্থবিজ্ঞানের একটি সমস্যার সমাধান করা যাক।
কোনো বস্তু u আদিবেগে (initial velocity) এবং a ত্বরণে (acceleration) যাত্রা শুরু করল (ত্বরণের মান সব সময় a থাকবে, বাড়বে বা কমবে না)। t সময় পরে এর বেগ যদি v হয় তাহলে 2t সময়ে বস্তুটি কত দূরত্ব অতিক্রম করবে? (সমস্যাটি দিয়েছেন শাহরিয়ার মঞ্জুর, এটি ভ্যালাডলিড অনলাইন জাজের 10071 নম্বর সমস্যা)।
2t সময়ে অতিক্রান্ত দূরত্ব হবে v x 2t। এটি প্রমাণ করে ফেলো। তারপর আবার পড়া শুরু করো। নবম-দশম শ্রেণীর পদার্থবিজ্ঞান বইতে তোমরা দুটি সূত্র পাবে:
v = u + at
s = ut + 0.5 at^2 (এখানে s হচ্ছে t সময়ে অতিক্রান্ত দূরত্ব)।
তাহলে 2t সময় পরে অতিক্রান্ত দূরত্ব হবে
u x 2t + 0.5 x a x (2t)^2 = u x 2t + 0.5 x a x 4t^2 = u x 2t + a x 2t^2 = 2t (u + at) = 2tv
এখন, তোমাদেরকে একটি প্রোগ্রাম লিখতে হবে, যেখানে v ও t-এর মান ইনপুট হিসেবে দেওয়া হবে, 2t সময়ে অতিক্রান্ত দূরত্ব নির্ণয় করতে হবে। প্রোগ্রামটি নিজে নিজে লিখে ফেলো।
৫) 1 + 2 + 3 + … + 998 + 999 + 1000 এই ধারার সমষ্টি কত?
তোমরা যারা ধারার যোগফলের সূত্র জানো, তারা চট করে বলে দিতে পারবে, এই ধারাটির যোগফল হচ্ছে 1000 x 1001 / 2। তাহলে এর জন্য একটি প্রোগ্রাম লিখে ফেলা যাক, যেখানে শেষ পদের মান হবে ইনপুট আর আউটপুট হবে যোগফল।
#include <stdio.h>
int main()
{
int n, sum;
scanf("%d", &n);
sum = (n * (n + 1)) / 2;
printf("Summation is %d\n",
sum);
return 0;
}
প্রোগ্রাম: ৫.৫
ধারার যোগফল নির্ণয়ের সূত্র জানা না থাকলে আমরা লুপ ব্যবহার করে প্রোগ্রামটি লিখতে পারি।
#include <stdio.h>
int main()
{
int i, n, sum;
scanf("%d", &n);
for(i = 1, sum = 0; i <= n; i++) {
sum = sum + i;
}
printf("Summation is %d\n",
sum);
return 0;
}
প্রোগ্রাম: ৫.৬
সুতরাং ধারার সমস্যা নিয়ে আর চিন্তা নেই। তুমি যদি একটি পদের মান তার আগের পদের চেয়ে কত করে বাড়ছে, সেটি বের করতে পারো, তাহলেই লুপ ব্যবহার করে যোগফল বের করে ফেলতে পারবে। তবে সূত্র বের করতে পারলে লুপ ব্যবহার না করাই ভালো। কারণ প্রথম প্রোগ্রামটি দেখো (যেখানে সূত্র ব্যবহার করেছি)। সেখানে একটি যোগ, একটি গুণ আর একটি ভাগ করতে হয়েছে, n-এর মান যত বড়ই হোক না কেন। আর দ্বিতীয় প্রোগ্রামে (যেখানে লুপ ব্যবহার করেছি) n-এর মান যত, ততবার যোগ করতে হয়েছে, আবার সেই যোগফলটি sum ভেরিয়েবলে রাখতে হয়েছে (ভেরিয়েবলে কোনো মান রাখতেও কিন্তু একটু সময় লাগে)।
এখন তোমাদের একটি সহজ প্রোগ্রাম লিখতে হবে। প্রথম n সংখ্যক ধনাত্মক বেজোড় সংখ্যার যোগফল নির্ণয়ের প্রোগ্রাম। n-এর মান হবে ইনপুট, আর যোগফল হবে আউটপুট।
৬) আমাদের এবারকার প্রোগ্রামটি হবে তাপমাত্রাকে সেলসিয়াস (Celsius) থেকে ফারেনহাইটে (Farenheit) রূপান্তর করার প্রোগ্রাম।
সেলসিয়াসকে ফারেনহাইটে রূপান্তরের সূত্র হচ্ছে: °F = (°C × 1.8) + 32।
#include <stdio.h>
int main()
{
double celsius, farenheit;
printf("Enter the temperature in
celsius: ");
scanf("%lf", &celsius);
farenheit = 1.8 * celsius + 32;
printf("Temperature in farenheit is:
%lf\n", farenheit);
return 0;
}
প্রোগ্রাম: ৫.৭
এখন তোমাদের কাজ হচ্ছে ফারেনহাইট থেকে সেলসিয়াসে রূপান্তরের প্রোগ্রাম লেখা।
৭) এখন আমরা দুটি সংখ্যার গসাগু (GCD → Greatest Common Divisor বা HCF → Highest Common Factor) ও লসাগু (LCM → Least Common Multiple) নির্ণয় করার জন্য প্রোগ্রাম লিখব।
দুটি সংখ্যার গসাগু হচ্ছে যেসব সংখ্যা দিয়ে ওই দুটি সংখ্যা নিঃশেষে বিভাজ্য হয়, তাদের মধ্যে সবচেয়ে বড় সংখ্যা। তাহলে আমরা যেটি করব, দুটি সংখ্যা a ও b নেব। তারপর এদের মধ্যে যেটি ছোট, সেই মানটি আবার x ভেরিয়েবলে রাখব। গসাগু এর মান x-এর চেয়ে বড় হওয়া সম্ভব নয় (5 ও 10-এর গসাগু-এর মান নিশ্চয়ই 5-এর চেয়ে বড় হবে না)। এখন a ও b, x দিয়ে নিঃশেষে বিভাজ্য হয় কি না (a % x == 0 এবং b % x == 0) সেটি পরীক্ষা করব। যদি হয় তবে আমরা গসাগু পেয়ে গেছি। যদি a ও b উভয়েই নিঃশেষে বিভাজ্য না হয়, তখন x-এর মান এক কমিয়ে পরীক্ষা করব। যতক্ষণ না আমরা গসাগু পাচ্ছি x-এর মান কমাতেই থাকব। একসময় আমরা গসাগু পাবই, কারণ x-এর মান যখন 1 হবে, তখন তো x দিয়ে a ও b দুটি সংখ্যাই নিঃশেষে বিভাজ্য। তোমরা কি প্রোগ্রামটি নিজে লিখার চেষ্টা করবে? না পারলে আমার কোড দেখো:
#include <stdio.h>
int main()
{
int a, b, x, gcd;
scanf("%d %d", &a,
&b);
if (a < b) {
x = a;
}
else {
x = b;
}
for(; x >= 1; x--) {
if (a % x == 0 && b % x == 0)
{
gcd = x;
break;
}
}
printf("GCD is %d\n", gcd);
return 0;
}
প্রোগ্রাম: ৫.৮
প্রোগ্রামে দেখো gcd পাওয়ার সঙ্গে সঙ্গে লুপ থেকে বের হয়ে যেতে হবে (আমি break ব্যবহার করেছি এই জন্য)। break ব্যবহার না করলে কী হবে সেটি পরীক্ষা করে দেখো।
তবে গসাগু বের করার জন্য আমি যেই পদ্ধতি ব্যবহার করেছি সেটি খুব সহজ পদ্ধতি হলেও ইফিশিয়েন্ট (efficient) নয়। যেমন, সংখ্যা দুটি খুব বড় হলে এবং সহমৌলিক (co-prime) হলে লুপটি কিন্তু অনেকবার ঘুরবে। কারণ সহমৌলিক হলে গসাগু হবে 1। তোমরা নিশ্চয়ই জানো যে, দুটি সংখ্যার মধ্যে 1 ছাড়া আর কোনো সাধারণ উৎপাদক না থাকলে সংখ্যা দুটি সহমৌলিক।
গসাগু বের করার জন্য ইউক্লিডের একটি চমৎকার পদ্ধতি আছে। ইউক্লিড ভাগশেষ উপপাদ্যের (division algorithm) সাহায্যে গসাগু বের করার উপায় দেখিয়েছেন। এই পদ্ধতিতে খুব সহজে গসাগু বের করা যায় এবং প্রোগ্রামটিও বেশ ইফিশিয়েন্ট হয়। এর জন্য দুটি জিনিস জানা লাগবে:
a ও 0-এর গসাগু-এর মান a।
a ও b-এর গসাগু = b ও a % b-এর গসাগু।
তাহলে প্রোগ্রামে যেটি করতে হবে, একটি লুপের সাহায্যে a-এর মান b আর b-এর মান a%b বসিয়ে যেতে হবে, যতক্ষণ না b-এর মান শূন্য হয়। b-এর মান শূন্য হলেই বুঝে যাব যে গসাগু হচ্ছে a (এটা কিন্তু প্রোগ্রাম শুরুর সময় a-এর মান না, b-এর মান যখন শূন্য হবে সেই সময় a-এর মান)।
#include <stdio.h>
int main()
{
int a, b, t, x, gcd;
scanf("%d %d", &a,
&b);
if (a == 0) gcd = b;
else if (b == 0) gcd = a;
else {
while (b != 0) {
t = b;
b = a % b;
a = t;
}
gcd = a;
}
printf("GCD is %d\n", gcd);
return 0;
}
প্রোগ্রাম: ৫.৯
এই প্রোগ্রামটি আরও ইফিশিয়েন্ট করার চেষ্টা করো।
এবার লসাগু বের করার প্রোগ্রাম। তোমরা নিশ্চয়ই স্কুলে শিখেছ, কীভাবে লসাগু বের করতে হয়। সেই পদ্ধতি অবলম্বন করে প্রোগ্রাম লিখে ফেলো। আর যারা সেই পদ্ধতি জানো না, তাদের জন্য একটি সূত্র বলে দিচ্ছি। আশা করি, লসাগু বের করার প্রোগ্রাম লিখতে আর সমস্যা হবে না।
দুটি সংখ্যার লসাগু x দুটি সংখ্যার গসাগু = সংখ্যা দুটির গুণফল।
পরের অধ্যায়
[প্রোগ্রামিং
বইঃ অধ্যায় ছয়] অ্যারে।
এতক্ষণে তোমাদের প্রোগ্রামিং জ্ঞান-বুদ্ধি একটু বেড়েছে। চলো,
এবার তাহলে কিছু জনসেবামূলক
কর্মকাণ্ড করা যাক। আমরা
স্কুলের প্রিয় গণিত শিক্ষকের জন্য পরীক্ষার ফলাফল বের করার প্রোগ্রাম লিখে দেব। ওই স্কুলে প্রথম সাময়িক, দ্বিতীয়
সাময়িক ও বার্ষিক এই তিনটি পরীক্ষাই 100 নম্বরের হয়। তারপর বার্ষিক পরীক্ষার 50%, দ্বিতীয়
সাময়িক পরীক্ষার 25% ও প্রথম সাময়িক পরীক্ষার 25% নিয়ে
চূড়ান্ত ফলাফল প্রকাশ করা হয়। তাহলে আমাদের প্রোগ্রামের ইনপুট হচ্ছে ওই তিনটি পরীক্ষার নম্বর। আমাদেরকে চূড়ান্ত ফলাফল দেখাতে হবে। এটি কোনো ব্যাপারই নয়:
#include <stdio.h>
int main()
{
int ft_marks, st_marks, final_marks;
double total_marks;
ft_marks = 80;
st_marks = 74;
final_marks = 97;
total_marks = ft_marks / 4.0 + st_marks /
4.0 + final_marks / 2.0;
printf("%0.0lf\n",
total_marks);
return 0;
}
প্রোগ্রাম: ৬.১
প্রোগ্রামটির আউটপুট 87। (কিন্তু আমি যদি total_marks = ft_marks / 4.0 + st_marks / 4.0 + final_marks / 2.0; না লিখে এভাবে লিখতাম total_marks = ft_marks / 4 + st_marks / 4 + final_marks / 2; তাহলে আউটপুট আসে 86। কারণ কী? কম্পিউটারের মাথা খারাপ নাকি আমার?)
আমরা কিন্তু আমাদের প্রিয় শিক্ষকের তেমন কোনো উপকার করতে পারলাম না। কারণ তাঁর ক্লাসে মোট ছাত্রছাত্রীর সংখ্যা চল্লিশ। তাহলে স্যারকে চল্লিশবার প্রোগ্রামটি চালাতে হবে! কিন্তু এটি তো কোনো কাজের কথা হলো না। আমাদের উচিত, সবার চূড়ান্ত ফলাফল একটি প্রোগ্রামের মাধ্যমে নির্ণয় করা। তেমন কোনো কঠিন কাজ নয় এটি। আমরা এমন একটি প্রোগ্রাম লেখা শুরু করে দিতে পারি:
#include
int main()
{
int ft_marks_1, st_marks_1, final_marks_1, ft_marks_2, st_marks_2, final_marks_2, ft_marks_3, st_marks_3, final_marks_3,
তোমরা নিশ্চয়ই বুঝতে পারছ, আমি কী করতে যাচ্ছি? বলো তো এভাবে প্রোগ্রামটি লিখতে গেলে মোট কয়টি ভেরিয়েবলের দরকার? 160টি। স্যারের কষ্ট কমাতে গিয়ে আমাদের কষ্ট এত বাড়ানোর কোনো মানে হয় না। কিন্তু এধরনের প্রোগ্রাম তো আমাদের প্রায়ই লিখতে হবে। চিন্তা নেই! প্রায় সব প্রোগ্রামিং ল্যাংগুয়েজেই অ্যারে (Array) নামে একটি চমৎকার জিনিস আছে। এতে একই ধরনের অনেকগুলো ভেরিয়েবল একসঙ্গে রাখা যায়। ভেরিয়েবলের যেমন নাম রাখি, অ্যারের বেলাতেও তেমন একটি নাম দিতে হয়। Cতেও অ্যারে আছে।
ভেরিয়েবলের যেমন একটি ডাটা টাইপ থাকে, অ্যারেরও থাকে। অ্যারেটি যে ডাটা টাইপের হবে তাতে কেবল সেই রকম ডাটাই রাখা যাবে। যেমন char টাইপের অ্যারেতে কেবল char টাইপের জিনিস থাকবে।
অ্যারেতে কয়টি উপাদান থাকবে সেটি শুরুতেই বলে দিতে হয়।
int ara[10]; এভাবে আমরা একটি অ্যারে ডিক্লেয়ার করতে পারি, যার নাম হচ্ছে ara, যেটিতে কেবল ইন্টিজার টাইপের ডাটা থাকবে আর এই অ্যারেতে মোট দশটি সংখ্যা রাখা যাবে। প্রথমটি হচ্ছে ara[0] (হ্যাঁ, ara[1] না কিন্তু), দ্বিতীয়টি ara[1], তৃতীয়টি ara[2], এভাবে দশম সংখ্যাটি হচ্ছে ara[9]। অর্থাৎ, ara[i] হচ্ছে i+1তম উপাদান।
এবারে চলো অ্যারে নিয়ে একটু খেলাধুলা করা যাক। প্রতিটি প্রোগ্রাম কিন্তু অবশ্যই কম্পিউটারে চালিয়ে দেখবে।
#include <stdio.h>
int main()
{
int ara[5] = {10, 20, 30, 40, 50};
printf("First element: %d\n",
ara[0]);
printf("Third element: %d\n",
ara[2]);
return 0;
}
প্রোগ্রাম: ৬.২
আউটপুট ঠিকঠাক দেখতে পাচ্ছ?
আরেকটি প্রোগ্রাম:
#include <stdio.h>
int main()
{
int ara[5] = {6, 7, 4, 6, 9};
printf("%d\n", ara[-1]);
printf("%d\n", ara[5]);
printf("%d\n", ara[100]);
return 0;
}
প্রোগ্রাম: ৬.৩
এটির জন্য কী আউটপুট আসা উচিত? আমি জানি না এবং এটি জানা সম্ভব নয়। যেকোনো ধরনের সংখ্যা আসতে পারে। এগুলোকে গারবেজ (garbage) বলে। কারণ আসলে তো ওই অ্যারেতে -1, 5, 100 এই ইনডেক্স বলতে কিছু নেই। অ্যারেটির দৈর্ঘ্যই হচ্ছে 5 সুতরাং ইনডেক্স হবে 0 থেকে 4।
এখন কোনো অ্যারের সব উপাদান যদি একসঙ্গে দেখাতে চাই, তাহলে উপায় কী? উপায় হচ্ছে প্রথম উপাদান (ara[0]), দ্বিতীয় উপাদান (ara[1]), তৃতীয় উপাদান (ara[2]) … এভাবে একে একে সবগুলো প্রিন্ট করা। আর তার জন্য অবশ্যই আমরা লুপের সাহায্য নেব।
#include <stdio.h>
int main()
{
int ara[10] = {10, 20, 30, 40, 50, 60, 70,
80, 90, 100};
int i;
for(i = 0; i < 10; i++) {
printf("%d th element is:
%d\n", i+1, ara[i]);
}
return 0;
}
প্রোগ্রাম: ৬.৪
আর যদি শেষ উপাদান থেকে প্রথম উপাদান পর্যন্ত দেখাতে হতো? কোনো সমস্যা নেই, শুধু লুপে এ indexটি 9 থেকে 0 পর্যন্ত আনলেই চলবে। এখন তোমরা প্রোগ্রামটি লিখে ফেলো।
এবারে একটি ছোট সমস্যা। কোনো একটি অ্যারেতে দশটি উপাদান আছে, সেগুলো বিপরীত ক্রমে রাখতে হবে। অর্থাৎ দশম উপাদানটি হবে প্রথম উপাদান, প্রথমটি হবে দশম, দ্বিতীয়টি হবে নবম, নবমটি হবে দ্বিতীয়.. এই রকম। তার জন্য আমরা যেটি করতে পারি, আরেকটি অ্যারের সাহায্য নিতে পারি। দ্বিতীয় অ্যারেটিতে প্রথম অ্যারের উপাদানগুলো বিপরীত ক্রমে রাখবো। তারপর দ্বিতীয় অ্যারেটি প্রথম অ্যারেতে কপি করে ফেলব।
#include <stdio.h>
int main()
{
int ara[] = {10, 20, 30, 40, 50, 60, 70,
80, 90, 100};
int ara2[10];
int i, j;
for(i = 0, j = 9; i < 10; i++, j--)
{
ara2[j] = ara[i];
}
for(i = 0; i < 10; i++) {
ara[i] = ara2[i];
}
for(i = 0; i < 10; i++) {
printf("%d\n", ara[i]);
}
return 0;
}
প্রোগ্রাম: ৬.৫
এখানে লক্ষ করো যে প্রথম অ্যারেটির ক্ষেত্রে আমি তৃতীয় বন্ধনীর ভেতর অ্যারের উপাদান সংখ্যা বলে দিইনি, কারণ সি-এর কম্পাইলার দ্বিতীয় বন্ধনীর ভেতর সংখ্যাগুলো দেখেই বুঝে নিতে পারে যে araতে দশটি উপাদান আছে। দ্বিতীয় অ্যারে অর্থাৎ ara2তে এখন কোনো কিছু নেই। তাই শুরুতেই বলে দিতে হবে যে তাতে কয়টি উপাদান থাকবে। তাহলে কম্পাইলার সেই অনুসারে কম্পিউটারের মেমোরির মধ্যে অ্যারের জন্য জায়গা করে নেবে।
প্রোগ্রামটি ভালোভাবেই কাজ করছে। কিন্তু তোমরা একটু চিন্তাভাবনা করলেই বুঝতে পারবে যে দ্বিতীয় অ্যারেটি ব্যবহার করার কোনো দরকার ছিল না। আমরা একটি বহুল প্রচলিত পদ্ধতিতেই কাজটি করতে পারতাম।
int temp;
temp = ara[9];
ara[9] = ara[0];
ara[0] = temp;
প্রথম ও দশম উপাদান অদলবদল হয়ে গেল। তারপর
temp = ara[8];
ara[8] = ara[1];
ara[1] = temp;
দ্বিতীয় ও নবম উপাদান অদলবদল হয়ে গেল। তাহলে চলো প্রোগ্রামটি লিখে ফেলি:
#include <stdio.h>
int main()
{
int ara[] = {10, 20, 30, 40, 50, 60, 70,
80, 90, 100};
int i, j, temp;
for(i = 0, j = 9; i < 10; i++, j--)
{
temp = ara[j];
ara[j] = ara[i];
ara[i] = temp;
}
for(i = 0; i < 10; i++) {
printf("%d\n", ara[i]);
}
return 0;
}
প্রোগ্রাম: ৬.৬
প্রোগ্রামটি চালাও। কী দেখলে? আউটপুট কি এরকম?
10
20
30
40
50
60
70
80
90
100
তারমানে কাজ হয়নি! আসলে আমি একটি ছোট্ট ভুল করেছি, সেটি তোমরা খুঁজে বের করো। এ ধরনের ভুলকে বলে বাগ (bug), তখন প্রোগ্রাম ঠিকমতো রান করে কিন্তু সঠিক আউটপুট দেয় না। আমার কোডে বাগ আছে, তোমরা ডিবাগ (debug) করো (মানে বাগটি বের করে ঠিক করো)।
এখন চলো আমাদের আগের সমস্যায় ফিরে যাই। আমরা এখন প্রথম সাময়িক পরীক্ষায় সবার গণিতের নম্বর একটি অ্যারেতে রাখব, দ্বিতীয় সাময়িক পরীক্ষার নম্বর আরেকটি অ্যারেতে, বার্ষিক পরীক্ষার নম্বরের জন্য আরও একটি এবং রেজাল্টের জন্যও একটি অ্যারে ব্যবহার করব।
int ft_marks[40], st_marks[40], final_marks[40];
double total_marks[40];
যার রোল নম্বর 1 তার নম্বরগুলো থাকবে অ্যারের প্রথম ঘরে (মানে index 0 হবে)। এখন বলো তো total_marks[34]-এ কার সর্বমোট নম্বর আছে? যার রোল নম্বর 35। তাহলে কারও রোল নম্বর n হলে তার সর্বমোট নম্বর হচ্ছে total_marks[n-1]।
এখন প্রোগ্রামটি লিখে ফেলা যাক:
#include <stdio.h>
int main()
{
int ft_marks[40] = {83, 86, 97, 95, 93,
95, 86, 52, 49, 41, 42, 47, 90, 59, 63, 86, 40, 46, 92, 56, 51, 48, 67, 49, 42,
90, 42, 83, 47, 95, 69, 82, 82, 58, 69, 67, 53, 56, 71, 62},
st_marks[40] = {86, 97, 95, 93, 95, 86,
52, 49, 41, 42, 47, 90, 59, 63, 86, 40, 46, 92, 56, 51, 48, 67, 49, 42, 90, 42,
83, 47, 95, 69, 82, 82, 58, 69, 67, 53, 56, 71, 62, 49},
final_marks[40] = {87, 64, 91, 43, 89, 66,
58, 73, 99, 81, 100, 64, 55, 69, 85, 81, 80, 67, 88, 71, 62, 78, 58, 66, 98,
75, 86, 90, 80, 85, 100, 64, 55, 69, 85, 81, 80, 67, 88, 71};
int i;
double total_marks[40];
for(i = 0; i < 40; i++) {
total_marks[i] = ft_marks[i] / 4.0 +
st_marks[i] / 4.0 + final_marks[i] / 2.0;
}
for(i = 1; i <= 40; i++) {
printf("Roll NO: %d\tTotal Marks:
%0.0lf\n", i, total_marks[i-1]);
}
return 0;
}
প্রোগ্রাম: ৬.৭
রান করে দেখো, কী সুন্দর আউটপুট! printf ফাংশনের ভেতরে দেখো এক জায়গায় আমি \t লিখেছি, এতে ট্যাব (Tab) প্রিন্ট হবে (কিবোর্ডের বাঁ দিকে দেখো)। রোল নং প্রিন্ট করার পরে একটি ট্যাব দিয়ে টোটাল মার্কস প্রিন্ট করলে দেখতে একটু ভালো লাগে এই জন্য \t ব্যবহার করেছি, এমনিতে কোনো দরকার নেই।
কিন্তু এত সুন্দর প্রোগ্রাম দেখে তোমার শিক্ষক কোথায় তোমাকে একটু চটপটি খাওয়াবেন না উল্টা আরেকটি আবদার করে বসলেন। কোন নম্বর কতজন পেয়েছে সেটি উনি দেখতে চান। মানে 50 কতজন পেল, 51 কতজন পেল … এই রকম আর কি। বাকি অংশ পড়ার আগে প্রোগ্রামটি তোমরা নিজে নিজে লিখার চেষ্টা করো। এখন ইচ্ছা না করলে বইটি পড়া বন্ধ করে দাও এবং পরে কোনো একসময় চেষ্টা করবে।
আশা করি, তোমাদের মধ্যে কেউ কেউ প্রোগ্রামটি লিখে ফেলেছ। যদি কমপক্ষে এক ঘণ্টা চেষ্টার পরেও লিখতে না পারো তাহলে এখন আমরা সমাধানের চেষ্টা করতে পারি। শুরুতেই একটি ব্যাপার খেয়াল করো যে কেউ কিন্তু 50-এর নিচে নম্বর পায়নি। তাই 50 থেকে 100 পর্যন্ত কোন নম্বর কতজন পেল সেটি বের করলেই চলবে। আমার মাথায় প্রথমেই যে সমাধান আসছে সেটি হলো total_marks অ্যারেতে প্রথমে দেখব, কয়টি 50 আছে, তারপর আবার দেখব কয়টি 51 আছে … এভাবে 100 পর্যন্ত দেখব। মানে 50 থেকে 100 পর্যন্ত সব সংখ্যার জন্য total_marks অ্যারেতে সংখ্যাগুলো চেক করব।
for(marks = 50; marks <= 100; marks++) { লুপের সাহায্যে প্রথমে marks-এর মান 50, তারপরে 51, এভাবে এক এক করে বাড়াব 100 পর্যন্ত।
count = 0; ধরে নিচ্ছি শূন্য জন 'marks' নম্বর পেয়েছে। marks-এর সব কটি মানের জন্যই প্রথমে আমরা এই কাজটি করব। এবারে total_marks অ্যারেতে দেখব যে কোনো নম্বর যদি marks-এর সমান হয়, তবে count-এর মান এক বাড়িয়ে দেব। তাহলে কোনো একটি নম্বর (marks) যতবার অ্যারেতে আছে, count-এর মান তত হবে।
for(i = 0; i < 40; i++) {
if(total_marks[i] == marks) {
count++;
}
}
printf("Marks: %d Count: %d\n", marks, count); এখানে আমরা প্রতিটি marks এবং সেটি কতবার আছে (count) তা প্রিন্ট করে দিচ্ছি।
}
তাহলে পুরো প্রোগ্রাম লিখে ফেলি:
#include <stdio.h>
int main()
{
int marks, i, count;
int total_marks[] = {86, 78, 94, 68, 92,
78, 64, 62, 72, 61, 72, 66, 65, 65, 80, 72, 62, 68, 81, 62, 56, 68, 58, 56, 82,
70, 74, 78, 76, 84, 88, 73, 62, 66, 76, 70, 67, 65, 77, 63};
for(marks = 50; marks <= 100; marks++)
{
count = 0;
for(i = 0; i < 40; i++) {
if(total_marks[i] == marks) {
count++;
}
}
printf("Marks: %d Count: %d\n",
marks, count);
}
return 0;
}
প্রোগ্রাম: ৬.৮
তেমন কঠিন কিছু নয়। নেস্টেড ফর লুপ ব্যবহার করে সহজ-সরল সমাধান করে ফেললাম। আচ্ছা বলো তো if-এর ভেতর যে শর্তটি আমরা পরীক্ষা করছি (total_marks[i] == marks) এই কাজটি প্রোগ্রামে কতবার হয়? বাইরের লুপটি ঘুরবে 51 বার এবং প্রতিবারের জন্য ভেতরের লুপটি ঘুরবে 40 বার। তাহলে মোট 51 x 40 = 2040 বার।
ওপরের প্রোগ্রামটি আমরা এখন একটু অন্যভাবে লিখার চেষ্টা করব। নিচের প্রোগ্রামটি চটপট টাইপ করে ফেলো এবং রান করো:
#include <stdio.h>
int main()
{
int i;
int total_marks[] = {86, 78, 94, 68, 92,
78, 64, 62, 72, 61, 72, 66, 65, 65, 80, 72, 62, 68, 81, 62, 56, 68, 58, 56, 82,
70, 74, 78, 76, 84, 88, 73, 62, 66, 76, 70, 67, 65, 77, 63};
int marks_count[101];
for(i = 0; i < 101; i++) {
marks_count[i] = 0;
}
for(i = 0; i < 40; i++) {
marks_count[total_marks[i]]++;
}
for(i = 50; i <= 100; i++) {
printf("Marks: %d Count:
%d\n", i, marks_count[i]);
}
return 0;
}
প্রোগ্রাম: ৬.৯
এখানে আমি যেটি করেছি, একটি অতিরিক্ত অ্যারে ব্যবহার করেছি। marks_count একটি ইন্টিজার টাইপের অ্যারে এবং marks_count[n] দিয়ে আমরা বুঝব n সংখ্যাটি কতবার total_marks-এর মধ্যে আছে। নম্বর যেহেতু 0 থেকে 100-এর মধ্যে হতে পারে তাই আমরা ওই অ্যারেতে মোট 101টি সংখ্যা রাখার ব্যবস্থা করলাম। int marks_count[101];
শুরুতে যেহেতু কিছুই জানি না, তাই ধরে নিই, সব সংখ্যা শূন্য বার আছে। তাই marks_count অ্যারের সব ঘরে 0 বসিয়ে দিই:
for(i = 0; i < 101; i++) { marks_count[i] = 0; } এখন total_marks অ্যারের প্রতিটি সংখ্যার জন্য marks_count অ্যারের ওই ঘরের মান এক বাড়িয়ে দিই। for(i = 0; i < 40; i++) { marks_count[total_marks[i]]++; } বুঝতে সমস্যা হচ্ছে নাকি? একটু চিন্তা করো। যখন i-এর মান 0, তখন total_marks[i] হচ্ছে total_marks[0], অর্থাৎ 86। এখন আমাদের দরকার হচ্ছে marks_count অ্যারের ওই ঘরটার (মানে marks_count[86]) মান এক বাড়িয়ে দেওয়া। শুরুতে ছিল শূন্য, এখন হবে এক। আমরা কিন্তু সে কাজটিই করেছি marks_count[total_marks[i]]-এর মান এক বাড়িয়ে দিয়েছি marks_count[total_marks[i]]++; আসলে ব্যাপারটি এইভাবেও লেখা যেত: t_m = total_marks[i]; marks_count[t_m]++; এখনো যারা মাথা চুলকাচ্ছ তারা নিচের প্রোগ্রামটি কম্পিউটারে রান করাও। এখানে প্রতিবার marks_count[total_marks[i]]++; করার পরে marks_count অ্যারেটি আমরা এক লাইনে প্রিন্ট করেছি।
#include <stdio.h>
int main()
{
int
i, j;
int total_marks[] = {6, 7, 4, 6, 9, 7, 6,
2, 4, 3, 4, 1};
int marks_count[11];
for(i = 0; i < 11; i++) {
marks_count[i] = 0;
}
for(i = 0; i < 12; i++) {
marks_count[total_marks[i]]++;
for(j = 0; j <= 10; j++) {
printf("%d ",
marks_count[j]);
}
printf("\n");
}
return 0;
}
প্রোগ্রাম: ৬.১০
No comments