অ্যারে, স্ট্রিং ও ফাংশন
সি প্রোগ্রামিং: অ্যারে (Array) ও স্ট্রিং (String) এর ব্যবহার। একমাত্রিক অ্যারে, স্ট্রিং ফাংশন (strlen, strcpy) এবং ইউজার ডিফাইন্ড ফাংশনের ধারণা।
অধ্যায় ৫: প্রোগ্রামিং ভাষা - অ্যারে, স্ট্রিং ও ফাংশন
- লেকচার ১৩: অ্যারে, স্ট্রিং ও ফাংশন
- ভেরিয়েবল বনাম অ্যারে: একটি গল্প
- অ্যারে (Array) কী?
- অ্যারে ডিক্লেয়ারেশন ও ইনডেক্সিং
- অ্যারেতে মান রাখা ও প্রদর্শন
- উদাহরণ: ৫টি সংখ্যার গড় নির্ণয়
- স্ট্রিং (String) কী?
- নাল ক্যারেক্টার (Null Character)
- স্ট্রিং হ্যান্ডলিং ফাংশন (string.h)
- ফাংশন (Function) কী?
- ফাংশনের প্রকারভেদ
- ফাংশনের গঠন (Structure)
- ফাংশন ব্যবহারের উদাহরণ
- ফাংশন ব্যবহারের সুবিধা
- একনজরে সম্পর্ক
- নিজে চেষ্টা করো
- সারসংক্ষেপ
লেকচার ১৩: অ্যারে, স্ট্রিং ও ফাংশন - ডেটা স্ট্রাকচার ও মডুলার প্রোগ্রামিং
লেকচার ১৩-তে আমরা প্রোগ্রামিংয়ের দুটি অত্যন্ত শক্তিশালী হাতিয়ার—অ্যারে (Array) এবং ফাংশন (Function)—সম্পর্কে জেনেছি। চিন্তা করে দেখো, একটি ক্লাসে যদি ৫০ জন ছাত্র থাকে এবং তাদের প্রত্যেকের রোল নম্বর বা মার্কস সংরক্ষণ করার জন্য আমাদের ৫০টি আলাদা ভেরিয়েবল (mark1, mark2, ..., mark50) ডিক্লেয়ার করতে হয়, তবে সেটি কতটা বিরক্তিকর ও সময়সাপেক্ষ হবে! প্রোগ্রামিংয়ে এই ধরণের সমস্যা সমাধানের জন্যই অ্যারের উৎপত্তি।
আবার, একটি বড় প্রোগ্রাম লেখার সময় যদি একই কাজ (যেমন যোগ করা বা গড়ে বের করা) বারবার করতে হয়, তবে বারবার একই কোড না লিখে আমরা সেই কোডটিকে একটি আলাদা ব্লকে রেখে দিতে পারি, যাকে ফাংশন বলা হয়। এই অধ্যায়ে আমরা অ্যারে এবং ফাংশন ব্যবহার করে কীভাবে ডেটা ম্যানেজমেন্ট এবং মডুলার প্রোগ্রামিং (Modular Programming) করা যায়, তা বিস্তারিত শিখব। বোর্ড পরীক্ষায় এই অংশ থেকে লিনিয়ার সার্চ, ম্যাক্সিমাম ভ্যালু নির্ণয় এবং স্ট্রিং ম্যানিপুলেশন সংক্রান্ত প্রশ্ন প্রায়ই আসে।
অ্যারে (Array): ডেটার সুশৃঙ্খল বিন্যাস
সহজ কথায়, অ্যারে হলো একই ধরণের অনেকগুলো ভেরিয়েবলের একটি প্যাকেট বা সমষ্টি। যখন আমাদের একই ডেটা টাইপের (যেমন শুধুই পূর্ণসংখ্যা বা শুধুই ভগ্নাংশ) অনেকগুলো মান নিয়ে কাজ করতে হয়, তখন আমরা অ্যারে ব্যবহার করি।
সংজ্ঞা (Definition): একই ধরণের (Data Type) একাধিক ডেটা বা উপাদানকে যখন একটি সাধারণ নাম এবং ইনডেক্স (Index) নম্বরের মাধ্যমে মেমোরিতে পাশাপাশি সংরক্ষণ করা হয়, তখন তাকে অ্যারে (Array) বলে।
অ্যারের বৈশিষ্ট্য ও মেমোরি বিন্যাস
অ্যারের প্রধান বৈশিষ্ট্য হলো এটি মেমোরিতে পরপর (Contiguous) জায়গা দখল করে। অর্থাৎ, অ্যারের প্রথম উপাদানটি মেমোরির যে ঠিকানায় থাকে, দ্বিতীয়টি ঠিক তার পরের ঠিকানায় থাকে।
উপরের চিত্রটি লক্ষ্য করো। এখানে marks নামের একটি ৫ সাইজের ইনটিজার অ্যারে দেখানো হয়েছে।
- ইনডেক্স (Index): অ্যারের প্রতিটি উপাদানের অবস্থান নির্দেশক সংখ্যা। এটি সবসময় ০ (শূণ্য) থেকে শুরু হয় এবং শেষ হয় (N-1) এ (যেখানে N হলো অ্যারের মোট সাইজ)।
- মেমোরি অ্যাড্রেস: যদি marks[0] এর অ্যাড্রেস ১০০০ হয় এবং ইনটিজার ২ বাইট জায়গা নেয়, তবে marks[1] এর অ্যাড্রেস হবে ১০০২।
গুরুত্বপূর্ণ (Important):
- অ্যারের সাইজ স্থির (Fixed Size)। প্রোগ্রাম রান করার সময় এটি বাড়ানো বা কমানো যায় না (একে Static Memory Allocation বলে)।
- ইনডেক্স নেগেটিভ হতে পারে না।
- অ্যারের ইনডেক্সিং ০ থেকে শুরু হয়, তাই ১০ সাইজের অ্যারের শেষ ইনডেক্স হবে ৯।
অ্যারের মেমোরি সাইজ নির্ণয়
পরীক্ষায় প্রায়ই MCQ-তে অ্যারের মোট মেমোরি সাইজ বের করতে বলা হয়। এর সূত্রটি হলো:
$$Total\_Memory = Array\_Size \times Size\_of\_Data\_Type$$
যেমন: int A[10]; (ধরি, int = ২ বাইট)
তাহলে, মোট মেমোরি = $10 \times 2 = 20$ Bytes.
অ্যারে সম্পর্কিত গুরুত্বপূর্ণ প্রোগ্রাম (Exam Focus)
লেকচারে তোমরা অ্যারের যোগফল ও গড় নির্ণয় দেখেছ। কিন্তু সৃজনশীল প্রশ্নে (CQ) সবচেয়ে বেশি আসে সর্বোচ্চ/সর্বনিম্ন সংখ্যা নির্ণয় এবং লিনিয়ার সার্চ। নিচে এই দুটি প্রোগ্রামের পূর্ণাঙ্গ কোড ও ব্যাখ্যা দেওয়া হলো।
১. অ্যারে থেকে বৃহত্তম সংখ্যা (Maximum) নির্ণয়
লজিক: আমরা প্রথমে অ্যারের ১ম সংখ্যাটিকে (arr[0]) ধরে নিব যে এটিই সবচেয়ে বড় (max)। এরপর লুপ চালিয়ে বাকি সংখ্যাগুলোর সাথে max-এর তুলনা করব। যদি কোনো সংখ্যা max-এর চেয়ে বড় হয়, তবে তাকেই নতুন max হিসেবে আপডেট করব।
উদাহরণ (Example): Maximum Value Finding
#include <stdio.h>
int main() {
int arr[5] = {10, 45, 20, 85, 30};
int max = arr[0]; // ১ম সংখ্যাকে বড় ধরে নিলাম
int i;
for(i = 1; i < 5; i++) {
if(arr[i] > max) { // যদি বর্তমান সংখ্যা max এর চেয়ে বড় হয়
max = arr[i]; // তবে max আপডেট হবে
}
}
printf("Maximum Value is: %d", max);
return 0;
}
আউটপুট: Maximum Value is: 85
২. লিনিয়ার সার্চ (Linear Search)
লজিক: অ্যারের শুরু থেকে শেষ পর্যন্ত প্রতিটি উপাদান চেক করে দেখা যে সেটি আমাদের কাঙ্ক্ষিত সংখ্যার (Target Value) সমান কিনা। যদি পাওয়া যায় তবে লুপ ব্রেক করে বের হয়ে আসব।
উদাহরণ (Example): Linear Search
#include <stdio.h>
int main() {
int arr[5] = {10, 45, 20, 85, 30};
int target = 20; // আমরা ২০ খুঁজছি
int i, found = 0; // found একটি ফ্ল্যাগ ভেরিয়েবল
for(i = 0; i < 5; i++) {
if(arr[i] == target) {
printf("Found at index: %d\n", i);
found = 1; // পাওয়া গেছে
break; // লুপ থেকে বের হয়ে যাও
}
}
if(found == 0) {
printf("Not Found");
}
return 0;
}
আউটপুট: Found at index: 2
স্ট্রিং (String): ক্যারেক্টার অ্যারে
সি প্রোগ্রামিংয়ে আলাদা কোনো "String" ডেটা টাইপ নেই। ক্যারেক্টার টাইপের অ্যারে (char array) ব্যবহার করে স্ট্রিং তৈরি করা হয়। স্ট্রিং হলো একগুচ্ছ ক্যারেক্টারের সমষ্টি যা ডাবল কোটেশন (" ") এর মধ্যে থাকে।
নাল ক্যারেক্টার (Null Character): স্ট্রিংয়ের শেষে সর্বদা একটি বিশেষ ক্যারেক্টার '\0' (ব্যাকস্ল্যাশ জিরো) থাকে, একে নাল ক্যারেক্টার বলে। এটি কম্পাইলারকে নির্দেশ দেয় যে স্ট্রিংটি এখানে শেষ হয়েছে।
স্ট্রিং ইনপুট: scanf বনাম gets
এটি শিক্ষার্থীদের একটি সাধারণ ভুলের জায়গা।
- scanf("%s", str); : এটি স্পেস (Space) পেলে ইনপুট নেওয়া বন্ধ করে দেয়। তাই "Rahim Uddin" ইনপুট দিলে এটি শুধু "Rahim" গ্রহণ করবে।
- gets(str); : এটি স্পেসসহ পুরো লাইন ইনপুট নিতে পারে। (আধুনিক কম্পাইলারে fgets ব্যবহার করতে বলা হয়, তবে HSC সিলেবাসে gets বৈধ)।
পরীক্ষার টিপস (Exam Tip):
যদি প্রশ্ন আসে "BANGLADESH" শব্দটি মেমোরিতে রাখতে কত বাইট জায়গা লাগবে?
উত্তর: ১০টি অক্ষর + ১টি নাল ক্যারেক্টার (\0) = ১১ বাইট। সবসময় ১ যোগ করতে হবে।
স্ট্রিং লাইব্রেরি ফাংশন (string.h)
স্ট্রিং ম্যানিপুলেশনের জন্য সি ভাষায় <string.h> হেডার ফাইলে কিছু বিল্ট-ইন ফাংশন আছে। এগুলো ব্যবহার করলে লুপ চালিয়ে কাজ করতে হয় না।
| ফাংশন | কাজ | উদাহরণ |
|---|---|---|
strlen(s) |
স্ট্রিংয়ের দৈর্ঘ্য নির্ণয় করে (নাল ক্যারেক্টার বাদে)। | len = strlen(str); |
strcpy(des, src) |
একটি স্ট্রিং কপি করে অন্যটিতে রাখে। | strcpy(str2, str1); |
strcat(s1, s2) |
দুটি স্ট্রিং জোড়া লাগায় (Concatenation)। | strcat(s1, s2); |
strcmp(s1, s2) |
দুটি স্ট্রিং তুলনা করে। সমান হলে ০ রিটার্ন করে। | if(strcmp(s1, s2)==0) |
ফাংশন (Function): মডুলার প্রোগ্রামিং
ফাংশন হলো একটি বড় প্রোগ্রামের ক্ষুদ্র অংশ যা একটি নির্দিষ্ট কাজ সম্পাদন করে। জুসার মেশিনে যেমন ফল দিলে জুস বের হয়, তেমনি ফাংশনে ইনপুট (প্যারামিটার) দিলে প্রসেস হয়ে আউটপুট (রিটার্ন ভ্যালু) পাওয়া যায়।
সংজ্ঞা (Definition): ফাংশন হলো কিছু নির্দেশাবলি বা কোডের সমষ্টি যা একটি নির্দিষ্ট কাজ সম্পন্ন করার জন্য তৈরি করা হয় এবং প্রয়োজনে মূল প্রোগ্রাম থেকে কল (Call) করা যায়।
ফাংশনের প্রকারভেদ
- লাইব্রেরি ফাংশন (Library Function): আগে থেকেই তৈরি করা, যেমন
printf(),scanf(),sqrt()। - ইউজার ডিফাইন্ড ফাংশন (User-Defined Function): ব্যবহারকারী নিজের প্রয়োজনমতো তৈরি করে।
ফাংশনের গঠন ও কলিং প্রসেস
একটি ইউজার ডিফাইন্ড ফাংশনের প্রধান ৩টি অংশ থাকে:
1. ফাংশন প্রোটোটাইপ (Prototype): ফাংশনের নাম ও প্যারামিটার ঘোষণা (সেমিকোলন থাকে)।
2. ফাংশন ডেফিনিশন (Definition): মূল কোড বা বডি।
3. ফাংশন কল (Call): ব্যবহার করার নির্দেশ।
উদাহরণ: দুটি সংখ্যার যোগফল নির্ণয়ের ফাংশন
#include <stdio.h>
// 1. Function Prototype
int add(int a, int b);
int main() {
int result;
// 3. Function Call
result = add(10, 20);
printf("Sum is: %d", result);
return 0;
}
// 2. Function Definition
int add(int a, int b) {
int sum = a + b;
return sum; // Return Value
}
লোকাল বনাম গ্লোবাল ভেরিয়েবল
- লোকাল ভেরিয়েবল: কোনো ফাংশনের ভেতরে ডিক্লেয়ার করা ভেরিয়েবল। এটি শুধু ওই ফাংশনেই কাজ করে।
- গ্লোবাল ভেরিয়েবল: সব ফাংশনের বাইরে (উপরে) ডিক্লেয়ার করা হয়। এটি পুরো প্রোগ্রামের যেকোনো জায়গা থেকে ব্যবহার করা যায়।
পরীক্ষার প্রস্তুতি ও টিপস
সৃজনশীল প্রশ্নের টিপস (CQ Tips):
- উদ্দীপকে যদি "তালিকা", "সিরিজ" বা "অনেকগুলো ডেটা" নিয়ে কাজ করার কথা বলা হয়, তবে বুঝবে এটি অ্যারের প্রশ্ন।
- যদি বলা হয় "একই কাজ বারবার করার জন্য একটি সাব-প্রোগ্রাম তৈরি করো", তবে সেটি ফাংশন বা সাব-রুটিন নির্দেশ করছে।
- কোড লেখার সময় অ্যারের সাইজ এবং লুপের লিমিট ঠিক আছে কিনা খেয়াল রাখবে (যেমন: সাইজ ৫ হলে লুপ চলবে ০ থেকে ৪ পর্যন্ত)।
সংক্ষিপ্ত সারাংশ (Quick Revision):
- Array: সমজাতীয় ডেটার সমষ্টি, ইনডেক্স ০ থেকে শুরু।
- String: ক্যারেক্টার অ্যারে, শেষে \0 থাকে।
- Function: কোড পুনরায় ব্যবহার (Code Reusability) নিশ্চিত করে।
- Header Files: স্ট্রিং ফাংশনের জন্য <string.h> এবং গাণিতিক ফাংশনের জন্য <math.h> ব্যবহার করতে হয়।
পরিভাষা (Glossary)
| পরিভাষা (Term) | সংজ্ঞা (Definition) |
|---|---|
| Array Index | অ্যারের প্রতিটি উপাদানের অবস্থান নির্দেশক সংখ্যা, যা ০ থেকে শুরু হয়। |
| Null Character | স্ট্রিং-এর সমাপ্তি নির্দেশক বিশেষ ক্যারেক্টার (\0)। |
| Prototype | কম্পাইলারকে ফাংশনের নাম ও প্যারামিটার সম্পর্কে আগাম তথ্য দেওয়ার ঘোষণা। |
| Argument | ফাংশন কল করার সময় যে মান পাঠানো হয় (Actual Parameter)। |
| Parameter | ফাংশন ডেফিনিশনে যে ভেরিয়েবল মান গ্রহণ করে (Formal Parameter)। |
| Buffer Overflow | অ্যারের নির্ধারিত সাইজের চেয়ে বেশি ডেটা রাখার চেষ্টা করলে যে এরর হয়। |