প্রোগ্রামাররা বিভিন্ন সময় যখন প্রোগ্রাম লেখে, তখন দেখা যায়, একই কাজ একাধিকবার করতে হচ্ছে। এ কাজগুলো একসঙ্গে একটি ফাংশনের মধ্যে লেখা যায়। তখন কেবল সেই ফাংশনটি কল করলেই চলে, ভেতরের কাজগুলো আবার নতুন করে লিখতে হয় না। এমনকি, ফাংশনটি ভেতরে কীভাবে কাজ করছে, সেটি না জানলেও ফাংশনটি ব্যবহার করতে সমস্যা হয় না।
ইতিমধ্যে printf() ও scanf() ফাংশনের ব্যবহার দেখানো হয়েছে। এখন স্ক্রিনে প্রিন্ট করার জন্য অনেক কাজ করতে হয় বা কোড লিখতে হয়। সেগুলো printf() ফাংশনের ভেতরে বলা আছে। কিন্তু সি প্রোগ্রামাররা সরাসরি printf() ফাংশন ব্যবহার করে, printf()-এর ভেতরে যে কোড লেখা আছে, সেটি যদি বারবার লিখতে হতো, তাহলে প্রোগ্রামারদের কষ্টও বেড়ে যেত, কোডের আকারও বেড়ে যেত। তেমিন scanf() ফাংশনের বেলাতেও ব্যাপারটি সত্য। ফাংশনটি কীভাবে ব্যবহার করতে হবে, সি প্রোগ্রামারদের এটুকু জানাই যথেষ্ট। এই ফাংশন দুটো ব্যবহার করার জন্য stdio.h নামক হেডার ফাইলটি ইনক্লুড করতে হয়। একটি হেডার ফাইল ইনক্লুড করলে ওই হেডার ফাইলের ভেতরে যেসব ফাংশন তৈরি করে দেওয়া থাকে, সেগুলো ব্যবহার করা যায়। সি প্রোগ্রামিং ভাষায় এরকম অনেক হেডার ফাইল তৈরি করে দেওয়া আছে। এগুলোকে লাইব্রেরিও বলে। এছাড়া প্রয়োজন হলে প্রোগ্রামার নতুন হেডার ফাইল তৈরি করে নেয়।
একটি ফাংশন ব্যবহার করতে হলে তিনটি জিনিস জানতে হয়। ফাংশনটি কী কাজ করে, ফাংশনের ভেতরে কী কী ডেটা পাঠাতে হবে, আর ফাংশনটি কী ডেটা রিটার্ন করে। যেমন- math.h হেডার ফাইলে একটি ফাংশন আছে যার কাজ হচ্ছে বর্গমূল বের করা। ফাংশনটির প্রোটোটাইপ হচ্ছে- double sqrt(double arg); এখানে প্রথম double হচ্ছে ফাংশনটির রিটার্ন টাইপ, অর্থাৎ ফাংশনটি কী টাইপের ডেটা রিটার্ন করে। ফাংশন যদি কোনো ডেটা রিটার্ন না করে, তখন রিটার্ন টাইপ হয় void। তারপরে sqrt হচ্ছে ফাংশনের নাম। এরপর প্রথম বন্ধনীর ভেতরে double arg লেখা, যার অর্থ হচ্ছে ফাংশনটি ইনপুট হিসেবে একটি double টাইপের ডেটা গ্রহণ করে- একে বলা হয় ফাংশনের প্যারামিটার (parameter)। আর ফাংশনটি যখন ব্যবহার করা হয়, তখন প্যারামিটারের জায়গায় যে ডেটা পাঠানো হয়, তাকে বলা হয় আর্গুমেন্ট (argument)। নিচের উদাহরণে ফাংশনটির ব্যবহার দেখানো হলো।
উদাহরণ ২১
#include <stdio.h>
#include <math.h>
int main()
{
double num, root;
scanf ("%f", &num);
root = sqrt(num);
printf ("Square root of %lf is %lf\n", num, root);
return 0;
}
প্রোগ্রামঃ 5.28
main() ফাংশনের শেষে কেন return 0; স্টেটমেন্টটি লেখা হয়?
সি ল্যাঙ্গুয়েজে লেখা সব প্রোগ্রাম রান করলে কোডের ভেতরে main() ফাংশন থেকে প্রোগ্রামটি চলা শুরু হয়। main() ফাংশন যদি এভাবে ডিক্লেয়ার করা হয়- int main() তাহলে কম্পাইলার ধরে নেয় যে ফাংশনটি যখন এক্সিকিউশন শেষ হবে তখন সে একটি ইন্টিজার রিটার্ন করবে। তাই ফাংশনের শেষে কোনো একটি ইন্টিজার রিটার্ন করতে হবে। প্রচলিত নিয়মে 0 রিটার্ন করা হয়, প্রোগ্রামটি ঠিকভাবে কোনো সমস্যা ছাড়াই চলেছে সেটা বোঝানোর জন্য। তাই 0-ই যে রিটার্ন করতে হবে এমন কোনো কথা নেই। চাইলে যেকোনো ইন্টিজার-ই রিটার্ন করা যায়।
উদাহরণ ২২
#include <stdio.h>
#include <math.h>
int main()
{
double num, p, x, y;
scanf ("%f %f", &x, &y);
p = pow (x, y);
printf ("%lf to the power %lf is: %lf\n", x, y, p);
return 0;
}
প্রোগ্রামঃ 5.29
math.h হেডার ফাইলে এরকম অনেক গাণিতিক ফাংশন তৈরি করে দেওয়া আছে।
একটি স্ট্রিংয়ের দৈর্ঘ্য, অর্থাৎ স্ট্রিংয়ে মোট কয়টি ক্যারেক্টার আছে, সেটি বের করার জন্য ইতিমধ্যে একটি প্রোগ্রাম লিখে দেখানো হয়েছে। কাজটি চাইলে একটি লাইব্রেরি ফাংশন ব্যবহার করে করা যায়, যার নাম হচ্ছে strlen। ফাংশনটি ইনপুট হিসেবে একটি স্ট্রিং নিবে এবং তার দৈর্ঘ্য রিটার্ন করবে। এই ফাংশনটি রয়েছে string.h হেডার ফাইলে।
উদাহরণ ২৩
#include <stdio.h>
#include <string.h>
int main()
{
char name[80];
int length;
scanf ("%s", &name);
length = strlen (name);
printf ("%s has %d characters.\n", name, length);
return 0;
}
প্রোগ্রামঃ 5.30
দুটি স্ট্রিং সমান নাকি বড়-ছোট, সেটি বের করার জন্য strcmp নামক একটি লাইব্রেরি ফাংশন আছে। যার কাজ হচ্ছে স্ট্রিং তুলনা করে সমান হলে 0 রিটার্ন করা, প্রথমটি বড় হলে 1 রিটার্ন করা আর প্রথমটি ছোট হলে -1 রিটার্ন করা।
উল্লেখ্য, এখানে বড় ছোট মানে দৈর্ঘ্য বড়-ছোট নয়, বরং লেক্সিকোগ্রাফিক্যালি (lexicographically) বড়-ছোট কি না তা বোঝানো হয়েছে। এর মানে হচ্ছে ডিকশনারি বা আভিধানিক ক্রমে সাজালে যে স্ট্রিংটি আগে আসবে তাকে ছোট আর যেটি পরে আসবে তাকে বড় বলে বিবেচনা করা হবে।
উদাহরণ ২৪
#include <stdio.h>
#include <string.h>
int main()
{
char s1 [80], s2[80];
int value;
scanf ("%s %s", &s1, &s2);
value = strcmp (s1, s2);
if (value == 0)
{
printf ("%s and %s are equal.\n", s1, s2);
}
else if (value > 0)
{
printf ("%s is greater than %s.\n", s1, s2);
}
else
{
printf ("%s is smaller than %s.\n", s1, s2);
}
return 0;
}
প্রোগ্রামঃ 5.31
এতক্ষণ বিভিন্ন লাইব্রেরি ফাংশনের ব্যবহার দেখানো হলো। সি প্রোগ্রামিং ভাষা এরকম শত শত লাইব্রেরি ফাংশন আছে। কম্পাইলারের সঙ্গে দেওয়া ডকুমেন্টেশন কিংবা ইন্টারনেট ঘেঁটে সেই লাইব্রেরি ফাংশনগুলো সম্পর্কে জানা যাবে। এখন দেখানো হবে কীভাবে নতুন ফাংশন তৈরি করতে হয়।
উদাহরণ ২৫
#include <stdio.h>
float celsius_to_fahrenheit (float celsius);
int main()
{
float celsius, fahrenheit;
scanf ("%f", &celsius);
fahrenheit = celsius_to_fahrenheit (celsius);
printf ("Fahrenheit = %f\n", fahrenheit);
return 0;
}
float celsius_to_fahrenheit (float celsius)
{
return (celsius * 9 / 5) + 32;
}
প্রোগ্রামঃ 5.31
উপরের প্রোগ্রামে celsius_to_fahrenheit() নামে ফাংশন তৈরি করা হয়েছে। ফাংশনটি একটি সংখ্যা প্যারামিটার হিসেবে নেয় যেটি ডিগ্রি সেলসিয়াস এককে একটি তাপমাত্রা নির্দেশ করে এবং সংখ্যাটি ডিগ্রি ফারেনহাইট এককে রূপান্তর করে রিটার্ন করে। main() ফাংশন লেখার আগে ফাংশনটির প্রোটোটাইপ লেখা হয়েছে-
float celsius_to_fahrenheit (float celsius);
তারপর main() ফাংশনের পরে ফাংশনটি ইমপ্লিমেন্ট করা হয়েছে। main() ফাংশন থেকে যখন celsius_to_fahrenheit() ফাংশনটি কল (call) করা হচ্ছে, তখন প্রোগ্রাম এই ফাংশনের ভেতরে ঢুকে যাচ্ছে এবং ফাংশন থেকে যখন রিটার্ন করা হচ্ছে, তখন আবার main() ফাংশনের ভেতরে ফেরত আসছে।
উদাহরণ ২৬
বইতে ইতিমধ্যে নামতা প্রিন্ট করার প্রোগ্রাম দেখানো হয়েছে। এখন প্রোগ্রামটি পুনরায় লেখা হবে, তবে ফাংশন ব্যবহার করে।
#include <stdio.h>
void print_multiplication_table (int n);
int main()
{
int num;
scanf ("%d", &num);
print_multiplication_table (num);
return 0;
}
void print_multiplication_table (int n)
{
int i;
printf ("Multiplcation table for %d -\n", n);
for (i = 1; i <= 10; i = i + 1) {
printf ("%d x %d = %d\n", n, i, n * i);
}
}
প্রোগ্রামঃ 5.32
উদাহরণ ২৭
1 থেকে 100 পযন্ত প্রতিটি সংখ্যার জন্য সংখ্যাটি 3 দ্বারা বিভাজ্য হলে Fizz প্রিন্ট করতে হবে, 5 দ্বারা বিভাজ্য হলে Buzz প্রিন্ট করতে হবে, আর সংখ্যাটি যদি 3 ও 5 উভয় সংখ্যা দ্বারাই বিভাজ্য হয়, তাহলে প্রিন্ট করতে হবে FizzBuzz. প্রতিটি সংখ্যা পরীক্ষা করার কাজটি একটি ফাংশন ব্যবহার করে করতে হবে।
#include <stdio.h>
void fizzbuzz (int n);
int main()
{
int i;
for (i = 1; i <= 100; i += 1) {
printf ("%d: ", i);
fizzbuzz (i);
}
return 0;
}
void fizzbuzz (int n)
{
if (n % 3 == 0 && n % 5 == 0) {
printf ("FizzBuzz\n");
}
else if (n % 3 == 0) {
printf ("Fizz\n");
}
else if (n % 5 == 0) {
printf ("Buzz\n");
}
else {
printf ("\n");
}
}
প্রোগ্রামঃ 5.33