C Programming

Print Button

প্রথম প্রোগ্রামটির বিস্তারিত ভূমিকা

          
           #include<stdio.h>  
             int main () {  
               printf("Hello World");  
               return 0;  
              }
             
            

চলুন এখন একে একে ব্যাখ্যা করা যাক লাইনগুলো।

প্রথম লাইন ছিল: #include <stdio.h>, এখানে stdio.h একটি হেডার ফাইল। এখানে এই হেডার ফাইলটিকে আমাদের প্রোগ্রামে সংযুক্ত করার জন্য বলা হয়েছে। এটি কেন লিখেছি একটু পরে বলছি।

দ্বিতীয় লাইন ফাঁকা। দেখতে ভাল লাগে তাই। ফাঁকা না রাখলে কাজ করতো, কিন্তু প্রোগ্রামটি পড়তে সুবিধা হয় ফাঁকা রাখলে তাই রাখা।

তৃতীয় লাইন: int main()। এটিকে বলে মেইন ফাংশন। সি প্রোগ্রামগুলো মেইন ফাংশন থেকে কাজ করা শুরু করে, তাই সব প্রোগ্রামে একটি (এবং কেবল একটি) মেইন ফাংশন থাকতে হয়। মেইন ফাংশনের শুরুতে দ্বিতীয় বন্ধনী '{' দিয়ে শুরু করতে হয় আর শেষও করতে হয় একটি দ্বিতীয় বন্ধনী '}' দিয়ে। শেষ করার আগে আমরা return 0; লিখেছি, সেটি কেন এখন ব্যাখ্যা না করলেই ভালো হয়, ফাংশন নিয়ে যখন আলাপ করব তখন বলব। আপাতত আমরা যেকোনো প্রোগ্রামে নিচের অংশটুকু লিখে ফেলবো, এবং { ব্র্যাকেট শুরু করার পর এবং return 0; লেখার আগে যে অংশটুকু আছে, সেখানেই আমাদের প্রয়োজনীয় প্রোগ্রামটুকু লিখব।


int main()
{
    //এখানে কোড থাকবে।
    return 0;
}

প্রোগ্রামের পরের লাইনটি খেয়াল করুন: printf("Hello World"); এটি একটি স্টেটমেন্ট। এখানে printf() হচ্ছে একটি ফাংশন যার কাজ হচ্ছে স্ক্রিনে কিছু প্রিন্ট করা। ডাবল কোটেশন (" ") চিহ্নের ভেতরে যা লিখবেন তা-ই সে স্ক্রিনে প্রিন্ট করবে।

printf ফাংশনটি স্ক্রিনে প্রিন্ট করে কীভাবে সেটি আসলে বলা আছে stdio.h ফাইলে। এই ফাইলগুলোকে বলে হেডার (header) ফাইল (.h হচ্ছে হেডার ফাইলের এক্সটেনশন)stdio.h ফাইলে স্ট্যান্ডার্ড ইনপুট আর আউটপুট-সংক্রান্ত যাবতীয় ফাংশন লেখা আছে। এই ফাংশনগুলোকে ব্যবহার করার জন্য আমাদেরকে এই হেডার ফাইলকে সংযুক্ত করতে হয়। যেহেতু printf() ফাংশন ব্যবহার করেছি, তাই প্রোগ্রামের শুরুতে #include <stdio.h> লিখতে হয়েছে। আপাতত আমরা কেবল ফাংশনগুলো ব্যবহার করব, ফাংশনগুলো কীভাবে কাজ করে সেটি এখন আমাদের জানার দরকার নেই। এই রকম আরও অনেক প্রয়োজনীয় হেডার ফাইল আছে, যার কিছু আমরা পরবর্তী সময়ে কাজের প্রয়োজনে দেখব।

এখন একটি ব্যাপার খেয়াল করুন। printf("Hello World");-এর শেষে একটি সেমিকোলন রয়েছে। সি ল্যাঙ্গুয়েজে প্রতিটি স্টেটমেন্টের পরেই একটি সেমিকোলন থাকে। একটি স্টেটমেন্টের কাজ শেষ হলে পরের স্টেটমেন্টের কাজ শুরু হয়। return 0; এই লাইনটিও একটি স্টেটমেন্ট, তাই এটিও সেমিকোলন দিয়ে শেষ করতে হয়েছে। শুরুর দিকে অনেকেই সেমিকোলন দিতে ভুলে যায়, তখন কম্পাইল এরর (compile error) হয়। আপনি একটি সেমিকোলন মুছে দিয়ে রান করার চেষ্টা করে দেখতে পারেন।

বিভিন্ন কারনে কম্পাইলেশন এরর হতে পারে। এ ব্যাপারে বিস্তারিত এখনই না জানলেও চলবে। তবে জানতে চাইলে কম্পাইলেশন এরর লিংকে ক্লিক করতে পারেন।

নিউলাইন এস্কেপ ক্যারেক্টার, সি টোকেন

আমরা যদি একাধিক printf ব্যবহার করি, তাহলে আমাদের আউটপুট কি আসবে? ভিন্ন ভিন্ন লাইনে আসবে বলে মনে হয়? ধরুন আমরা যদি নিচের সি কোডটি লিখি?


#include<stdio.h>

int main()
{
    printf("Hello World");
    printf("How are you?");
    return 0;
}

আমরা কোডটি রান করলে দেখতে পাব যে লাইন দুইটি ভিন্ন ভিন্ন লাইনে না এসে একই লাইনে এসেছে। আসলে প্রোগ্রামিং এর সময় আমরা যদি না বলে দিই কম্পিউটারের নিজের থেকে করার কোন ক্ষমতা নেই। আমরা যেহেতু নতুন লাইন প্রিন্ট করার কথা বলে দিইনি, কাজেই সে একই সাথে দুইটি বাক্য প্রিন্ট করেছে।

তাহলে যদি চাই নতুন লাইন এ প্রিন্ট করতে? তাহলে আমাদেরকে নিউলাইন এস্কেপ ক্যারেক্টারটি ব্যবহার করতে হবে।

সি তে বহুল ব্যবহৃত এস্কেপ ক্যারেক্টার হল নিউলাইন (\n)। এটির মাধ্যমে আমরা নতুন লাইন থেকে আউটপুট দিতে পারি। যেমন নিচের কোডে


#include<stdio.h>

int main()
{
    printf("Hello World\nHow are you?");
    return 0;
}

Hello World এবং How are you? এই দুইটি লাইন আলাদা লাইনে দেখাবে কারন দুই লাইনের মাঝখানে আমরা নিউলাইন ক্যারেক্টার দিয়েছি। নিউলাইন দেওয়ার কারনে সেখানে printf ফাংশন নিচের লাইনে চলে গিয়েছে। আপনারা দেখতে পাচ্ছেন যে, \ বা n এর কোনটিই আউটপুটে দেখাচ্ছে না।

আপনার ইচ্ছেমত নিউলাইন জুড়ে দিয়ে বা বাদ দিয়ে দেখতে পারেন যে আউটপুটে কেমন পরিবর্তন আসে। তাহলে আরো ভাল মত বুঝতে পারবেন নিউলাইনের কাজ।

মনে রাখতে হবে, দুটো আলাদা printf এর মাধ্যমেও যদি আমরা লিখি লেখাগুলোকে পাশাপাশি দেখাবে যদি না আমরা নিউলাইন ব্যবহার না করি। নিউলাইন পেলে তখন আমরা পরের লাইনের একদম শুরুতে চলে যাব এবং সেখান থেকে প্রিন্ট করা শুরু হবে।

ভ্যারিয়েবলে হাতে খড়ি - ১ ভ্যারিয়েবল, ভূমিকা

এখন পর্যন্ত আমরা যা করেছি, তা হল যা দেখতে চাই তা সরাসরি printf function এর ভেতরে লিখে দিয়েছি। বোঝাই যাচ্ছে এইটুকু দিয়ে আমরা আসলে খুব বেশি কাজ করতে পারব না। এজন্য এখন আমরা শিখব ভ্যারিয়েবলের ব্যবহার।

ভ্যারিয়েবল হল, এমন কিছু নাম যা দ্বারা আমরা কম্পিউটারের মেমোরিতে (সাধারণত র‍্যাম) রাখা বিভিন্ন তথ্য পড়তে পারি। আবার চাইলে এই ভ্যারিয়েবলের মাধ্যমে আমরা মেমোরিতে আমাদের ইচ্ছা মত মানও রাখতে পারি। ভ্যারিয়েবল ব্যবহারের অনেক সুবিধা রয়েছে। সেগুলোর বিস্তারিত আমরা পরবর্তীতে জানব। আপাতত আমরা একটি ছোট উদাহরনের মাধ্যমে ভ্যারিয়েবল কিভাবে ব্যবহার করতে হয় তা শিখব।


#include <stdio.h>  
int main()
{  
   int a;    
   a = 50;   
   return 0;  
}

উপরের প্রোগামটি রান করলে আমরা কিছু দেখতে পারব না। কারণ, আমরা কম্পিটারকে কিছু প্রিন্ট করার নির্দেশ দিইনি। এই প্রোগ্রামে আমার শুধু মাত্র একটি ভ্যারিয়েবল ব্যবহার করেছি।

main ফাংশনের প্রথম লাইন লেখা "int a;"দ্বারা আমরা a নামের একটি ভ্যারিয়েবল ডিক্লেয়ার (Declare) করেছি। কোন ভ্যারিয়েবল ব্যবহার করার আগে অবশ্যই সেটি ডিক্লেয়ার করতে হয়। ডিক্লেয়ার করার জন্য আমাদেরকে ঐ ভ্যারিয়েবলটি কি টাইপের তা বলে দিতে হয়। যেমন আমাদের এই প্রোগ্রামে আমরা a ভ্যারিয়েবলটিকে int হিসাবে ডিক্লেয়ার করেছি। int টাইপটি হল Integer শব্দের সংক্ষিপ্ত রূপ, যার অর্থ হল পূর্ণ সংখ্যা। অর্থাৎ আমরা a ভ্যারিয়েবলটিতে শুধু মাত্র পূর্ণ সংখ্যা রাখতে পারব। এরকম আরো বিভিন্ন টাইপের ভ্যারিয়েবল আমরা ডিক্লেয়ার করতে পারি। এ ব্যাপারে আমরা পরবর্তীতে জানব।

দ্বিতীয় লাইনে লেখা "a = 50;" এর মাধ্যমে আমরা a তে একটি মান রেখেছি। এখানে = চিহ্নটি এর মাধ্যমে আমরা সমান বুঝাই না। বরং প্রোগ্রামে এর অর্থ হল এসাইনমেন্ট বা মান নির্ধারন।

একটি ভ্যারিয়বলে আমরা যতবার ইচ্ছা ততবার মান রাখতে বা এসাইন করতে পারি। কিন্তু একটি ভ্যারিয়েবলকে আমাদের মাত্র একবার ডিক্লেয়ার‍ করতে পারি। একই নামে দুইটি ভ্যারিয়েবলকে আমরা (সাধারণত) ডিক্লেয়ার করতে পারি না। একটি ভ্যারিয়েবলকে ডিক্লেয়ার না করে আমরা ব্যবহার করতে পারি না।

নিচে আমরা আরেকটি প্রোগ্রাম লিখছি।


#include <stdio.h>  
int main()
{  
   int a;
   int b;    
   a = 50;   
   b = a + 10;
   return 0;  
}

এই প্রোগ্রামে আমরা দেখতে পাচ্ছি যে দুইটি ভ্যারিয়েবল ডিক্লেয়ার করা হয়েছেঃ a এবং b। আমরা এও দেখতে পাচ্ছি যে দুইটি ভ্যারিয়েবলই int টাইপের, অর্থাৎ তারা শুধু পূর্ণ সংখ্যা ধারন করতে পারবে।

a তে আগের প্রোগ্রামটির মতই 50 এসাইন করা হয়েছে। কিন্তু b তে আমরা রেখেছি "a + 10"। চাইলে আমরা সরাসরি মান না বলে অন্যান্য ভ্যারিয়েবলের মাধ্যমে একটি ভ্যারিয়েবলের মান নির্ধারন করতে পারি। যেমন এই প্রোগ্রাম b তে আমরা রেখেছি 60। কারন a তে রাখা ছিল 50, এবং তার সাথে 10 যোগ করে হল 60 যা b তে এসাইন করা হয়েছে। এরকম আরো অনেক জটিল গাণিতিক রাশিকে আমরা চাইলে ভ্যারিয়েবলে এসাইন করতে পারি।

ভ্যারিয়েবলে হাতে খড়ি - ২ ভ্যারিয়েবল, প্রিন্ট

করা আমরা ইতিমধ্যেই শিখেছি। কিন্তু সেই মানটি যদি আমরা আউটপুট হিসাবে দেখতে চাই, তাহলে আমাদের করণীয় কি?


#include <stdio.h>  
int main()
{  
   int a;    
   a = 50;   
   printf("a");  
   return 0;  
}

উপরের মত লিখে আমরা a এর মান দেখতে পাই না। কারন এখানে printf এর ভেতরে যখন a লেখা হয়, তখন ফাংশনটি এটিকে ভ্যারিয়েবল হিসাবে বিবেচনা করে না। এজন্যই প্রোগামটি চালালে আমরা শুধু মাত্র একটি "a" দেখতে পাই। a ভ্যারিয়েবলের মান দেখতে চাইলে আমাদের প্রোগ্রামটি হতে হবে নিচের মত।


#include <stdio.h>  
int main()
{  
   int a;    
   a = 50;   
   printf("%d", a);  
   return 0;  
}

এখানে printf এর ভেতরে লেখা %d একটি বিশেষ ধরনের চিহ্ন, যার মাধ্যমে আমরা printf কে বোঝাই কোন একটি ভ্যারিয়েবল এর মান প্রিন্ট করা হবে। %d কে বলা হয় "Format Specifier"। বিভিন্ন টাইপের ভ্যারিয়েবলের মান প্রিন্ট করার জন্য বিভিন্ন ধরনের ফরম্যাট স্পেসিফায়ার রয়েছে। %d ব্যবহার করে আমরা int টাইপের ভ্যারিয়েবলের মান প্রিন্ট করতে পারি।

লক্ষ্য করুন, উপরের প্রোগ্রামের printf এর ভেতরে আমরা এখন " " (ডাবল কোটেশন) চিহ্নের ভেতরে লিখেছি %d। এর পর একটি কমা দিয়ে বাইরে এসে লিখেছি a ভ্যারিয়েবলটির নাম। এভাবে লিখেছি বলেই উপরের প্রোগ্রামটি চালালে আমরা a এর মানটি স্ক্রিনে দেখতে পাব।

 
 #include <stdio.h>  
  int main()
 {  
    int a;
    int b;    
   a = 50;   
   b = a + 10;
   printf("%d\n", a);
   printf("%d", b);  
   return 0;  
}

উপরের প্রোগ্রামে আমরা দুইটি ভ্যারিয়েবলের মান প্রিন্ট করেছি। খেয়াল করে দেখবেন প্রথম printf এর শেষে আমরা এখন নিউলাইন (\n) ব্যবহার করেছি। এর কারনে দুইটি ভ্যারিয়েবলের মান দুইটি ভিন্ন লাইনে প্রিন্ট হয়েছে। যদি নিউলাইন না দেওয়া হত তাহলে মান দুটি পাশাপাশি প্রিন্ট হত।

আমরা এখন সর্বশেষ একটি উদাহরণ দেখব। দুইটি সংখ্যা যোগ করার প্রোগ্রাম। এই প্রোগ্রামের printf এর ভেতরে কি লিখেছি এবং তার ফলে আউটপুট কেমন এসেছে তা খুব ভাল মত খেয়াল করুন।


#include <stdio.h>  
int main()
{  
   int a;  
   int b;  
   int sum;  
   a = 50;  
   b = 60;  
   sum = a + b;  
   printf("a = %d\nb = %d\nSum is %d\n", a, b, sum);  
   return 0;  
}

ভ্যারিয়েবলে হাতে খড়ি - ৩ float, double, ভূমিকা, ভ্যারিয়েবল

আমাদের প্রোগ্রামে পূর্ণসংখ্যার বাইরেও অন্য ধরনের মান রাখার দরকার হতেই পারে। যেমন একটি বৃত্তের ক্ষেত্রফল বের করতে গেলে আমরা কখনই একই পূর্ণসংখ্যা পাব না। সেক্ষেত্রে আমরা যদি int টাইপের ভ্যারিয়েবলে মান গুলো রাখি তাহলে আমরা শুধু পূর্ণসংখ্যার অংশটুকু রাখতে পারব। নিচের উদাহরনটি দেখিঃ



int main()
{
    int a;
    a = 13.45;
    printf("%d\n", a);
    a = 2.5 + 3.6;
    printf("%d\n", a);
    return 0;
}

প্রোগ্রামটি চালালে আমরা দেখতে পাব আউটপুট হিসাবে এসেছে 13 এবং 6। যার অর্থ হল a তে মানগুলোর শুধু ইন্টিজার অংশটুকু রয়েছে। দশমিকের পরের অংশটুকু বাদ পরে গেছে। তাহলে, সেটুকুকে রাখার জন্য আমরা কি ধরনের ভ্যারিয়েবল ব্যবহার করব?

ভগ্নাংশ বা ফ্র্যাকশন রাখার জন্য আমরা double টাইপের ভ্যারিয়েবল ব্যবহার করতে পারি। এর নাম কেন double হল সেটা নিয়ে আমরা বিস্তারিত আলোচনা করব পরে। আপাতত এটুকু জেনে রাখুন যে এটি প্রিন্ট করতে %d এর বদলে ব্যবহার করতে হয় %lf। চলুন উদাহরণ দেখা যাকঃ


#include<stdio.h>

int main()
{
    double a;
    a = 13.45;
    printf("%lf\n", a);
    a = 2.5 + 3.6;
    printf("%lf\n", a);
    return 0;
}

উপরের প্রোগ্রামটি চালালে দেখতে পাবেন যে এখন মানগুলো ঠিক মতই দেখাচ্ছে। শুধু শেষে কিছু অতিরিক্ত শূণ্য দেখাচ্ছে। এটি আসলে %lf এর ক্ষেত্রে সবসময়ই হবে। %lf দিয়ে প্রিন্ট করলে দশমিকের পর ৬ ঘর দেখাবে। এর অন্যথা করা যায় কিভাবে তা আমরা পরে শিখব।

ইনপুটে হাতে খড়ি - ১ ইনপুট, scanf, ভূমিকা

নিচের প্রোগ্রামটি খেয়াল করি।


#include <stdio.h>

int main() 
{
    int side, area;
    side = 10;
    area = side * side;
    printf("Area = %d\n", area);
    return 0;
}

প্রোগামটি একই বর্গের ক্ষেত্রফল নির্ণয় করছে। এইভাবে প্রোগ্রাম লেখার সমস্যা হল, এখন আমরা যদি অন্য আরেকটি বর্গ, যার বাহুর দৈর্ঘ্য ২০, এর ক্ষেত্রফল নির্ণয় করতে চাই, তাহলে আমাদেরকে সোর্স কোডে গিয়ে side এর মান পরিবর্তন করে ২০ লিখে আসতে হবে। কিন্তু এভাবে প্রোগ্রাম করা বেশ অসুবিধাজনক।

এ জন্য আমরা scanf ফাংশন ব্যবহার করে কি বোর্ড থেকে ইনপুট নিতে পারি। এই ইনপুট এর মানটি প্রোগ্রাম রান করা অবস্থাতেই আমরা পরিবর্তন করতে পারি। এর জন্য উপরের প্রোগ্রামটি পরিবর্তন করে আমরা নিচের মত করে লিখবঃ


#include <stdio.h>

int main() 
{
    int side, area;
    scanf("%d", &side);
    area = side * side;
    printf("Area = %d\n", area);
    return 0;
}

এখানে লক্ষ্য করলে আমরা দেখব যে scanf এর ব্যবহার করার নিয়ম printf এর মতই। শুধু এখানে ভ্যারিয়েবলের নামের আগে & ব্যবহার করতে হয়। এর কারন আমরা যখন পরবর্তীতে ব্যাখ্যা করব। এখন উপরের প্রোগ্রামটি চালানোর জন্য আমরা কোডল্যাবে গিয়ে কোডটি টাইপ করার পর যে বাক্সে "আপনার প্রোগ্রাম ইনপুট এখানে লিখুন" লেখা আছে, সেখানে লিখব। এরপর আগের মত "রান করুন" বাটনে ক্লিক করলেই আমাদের প্রোগ্রাম আপনার দেওয়া ইনপুটের মান অনু্যায়ী আউটপুট দেখাবে। চাইলে ইনপুট বাক্সে মান পরিবর্তন করে দিয়ে আবার রান করলেই নতুন মানের জন্য আউটপুট দেখা যাবে।

ইনপুটে হাতে খড়ি - ২ ইনপুট

আমরা যদি একাধিক ভ্যারিয়েবলে ইনপুট নিতে চাই, তাহলে আমাদেরকে ইনপুট বক্সে আলাদা আলাদা লাইনে সেই ইনপুট এর মানগুলোকে লিখে দিতে হবে। একটি প্রোগ্রামে আমরা আমাদের চাহিদা মত ইনপুট নিতে পারব। এমনকি একই ভ্যারিয়েবলে একাধিক বার ইনপুট নেওয়া সম্ভব। আমরা যদি নিচের মত একটি প্রোগ্রাম লিখি সেখানে একাধিক ভ্যারিয়েবলে ইনপুট নেওয়া হয়েছে।


#include <stdio.h>  
int main()
{  
   int a;  
   int b;  
   int sum;  
   scanf("%d", &a);
   scanf("%d", &b);
   sum = a + b;  
   printf("a = %d\nb = %d\nSum is %d\n", a, b, sum);  
   return 0;  
}

এই প্রোগ্রামটি চালানোর জন্য আমাদেরকে ইনপুট বক্সে আলাদা আলাদা লাইনে a এবং b এর মান দিতে হবে। যেমন a = 15, b = 20 এর জন্য আমরা নিচের মত আউটপুট পাবঃ

আমরা চাইলে একই ভ্যারিয়েবলে একাধিক বার ইনপুট নিতে পারি। তবে এইজন্য আমাদেরকে ঠিক যতগুলো scanf রয়েছে, ততবার ইনপুট বক্সে মান দিতে হবে।


#include <stdio.h>  
int main()
{  
   int a;  
   int b;  
   scanf("%d", &a);
   scanf("%d", &b);
   printf("a = %d\nb = %d\n", a, b);
   scanf("%d", &b);
   printf("a = %d\nb = %d\n", a, b);
   return 0;  
}

কাজেই উপরের প্রোগ্রামের জন্য আমরা যদি নিচের ছবির মত করে ইনপুট দিই, তাহলে আউটপুট পাওয়া যাবেঃ

এখানে খেয়াল করতে হবে, প্রথম scanf এর কারনে a তে 15 এসাইন হয়েছে। দ্বিতীয় scanf এর কারনে b তে 20 এসাইন হয়েছে। যেহেতু তৃতীয় scanf এর আগেই প্রথম printf এর কাজ করা হয়েছে, কাজেই সেই printf এর সময় a = 15 এবং b = 20প্রিন্ট হয়েছে। এরপর তৃতীয় scanf এর কারনে b তে 120 এসাইন করা হয়েছে। এ কারনেই এর পরের printf এর সময় a = 15 এবং b = 120 প্রিন্ট হয়েছে।

ইনপুটে হাতে খড়ি - ৩ double, ইনপুট, scanf

আমরা যদি int টাইপের ভ্যারিয়েবলে ইনপুট না নিয়ে double টাইপের ভ্যারিয়েবলে ইনপুট নিতে চাই, তাহলে আমাদের শুধু মাত্র %d এর বদলে %lf ব্যবহার করতে হবে। আর সবকিছুই আগের মত রাখতে হবে। নিচের উদাহরণ দেখলে আপনাদের কাছে ব্যাপারটি পরিষ্কার হবেঃ


#include<stdio.h>

int main()
{
    double a;
    double b;
    double sum;
    scanf("%lf", &a);
    scanf("%lf", &b);
    sum = a + b;
    printf("%lf\n", sum);
    return 0;
}

খেয়াল করে দেখবেন, এখানেও ভ্যারিয়েবলের নামের আগে & ব্যবহার করা হয়েছে। scanf ব্যবহার করলে এটি করতেই হবে। printf এর সময় এমনটি করা যাবে না। উপরের প্রোগ্রামটি দেখে নিশ্চয়ই বুঝতে পারছেন int টাইপের ভ্যারিয়েবলে ইনপুট নেওয়া আর double টাইপের ভ্যারিয়েবলে ইনপুট নেওয়ার মধ্যে তেমন বড় কোন পার্থক্য নেই।

প্রোগ্রাম কমেন্ট ভূমিকা

আপনি চাইলে আপনার সোর্স কোড অর্থাৎ প্রোগ্রামের লিখাগুলোর মধ্যে আপনার খুশিমতো কমেন্ট লিখতে পারেন। কোন একটি লাইন কি কাজ করছে, বা প্রোগ্রামের একটি অংশের কাজ কি তা সহজ ইংরেজিতে বর্ননা করতে পারেন আপনার প্রোগ্রাম এর ভেতরে। কমেন্ট লিখতে হলে অবশ্যই আপনাকে /* লিখে কমেন্ট শুরু করতে হবে এবং */ লিখে কমেন্ট শেষ করতে হবে। এইভাবে লিখলে আমরা অনেকগুলো লাইন জুড়ে কমেন্ট লিখতে পারব। আরেকটু উপায় হল, // এই চিহ্নের মাধ্যমে কমেন্ট লেখা। এইভাবে লিখলে, আমরা শুধু একটি লাইনেই কমেন্ট দিতে পারব। যদি একের অধিক লাইন জুড়ে দিতে চাই, তাহলে প্রতি লাইনের শুরুতে // লিখতে হবে। নিচের উদাহরণটি দেখলে ব্যাপারটি পরিষ্কার হবেঃ


/* program to calculate 
the area of a circle */ 

#include <stdio.h>
int main() {
    float radius, area;
    scanf("%f", &radius);
    // calculating area from radius using 
    // pi * r-squared formula
    area = 3.14159 * radius * radius;
    printf("Area = %f", area);
    return 0;
}

কম্পাইলার এই কমেন্টগুলো উপেক্ষা করবে এবং এই অংশটিকে মেশিন ল্যাঙ্গুয়েজ এ ট্রান্সলেট করার চেষ্টা করবেনা। সুতরাং কমেন্ট অংশে আপনি যেকোন কিছু লিখতে পারেন আপনার ও আপনার কোড যারা পড়বে তাদের বোঝার সুবিধার্থে।

ইফ এর প্রাথমিক ধারনা লজিক, ইফ

এখন পর্যন্ত যতগুলো প্রোগ্রাম আমরা দেখেছি, তার সবগুলোতেই প্রত্যেকটি স্টেটমেন্ট (statement) এক্সিকিউট (execute) হয়েছে। কিন্তু আমরা যদি চাই যে, শর্ত মেনে প্রোগ্রাম এর কিছু স্টেটমেন্ট মাঝে মাঝে কাজ করুক, আর মাঝে মাঝে বাদ পরুক তাহলে কি করব?

উদাহরন স্বরূপ বলা যায়, আপনাকে ১০০ টাকার একটা নোট দিয়ে বলা হল, বাজারে গিয়ে কলম কিনতে। যদি কম দামে <(১০ টাকা বা তার কম) পাওয়া যায় তাহলে ১০টি কলম কিনবেন। কিন্তু যদি দাম বেশি (১০ টাকার বেশি) হয় তাইলে আপাতত কিছু করার দরকার নেই।

এই সমস্যার ক্ষেত্রে আমরা দেখতে পাচ্ছি, কলমের দাম (যা আমাদের প্রোগ্রামের ইনপুট) এর নির্ভর করে আমাদের কাজ। এই এক একটি কাজকে যদি আমরা এক একটি স্টেটমেন্ট হিসাবে চিন্তা করি তাহলে আমাদের মূল কাজ হল তিনটি স্টেটমেন্টঃ


printf(“Price of a single pen = ”);
scanf( “%d” , &priceOfPen ); //কলমের দাম জিজ্ঞেস করা হল
printf( “Buy 10 pens.\n” ); //১০টি কলম কেনা হল

এখন আমাদের প্রয়োজন এমন কোন উপায় যাতে 3 নম্বর লাইনটি শুধু মাত্র যখন priceOfPen ভ্যারিয়েবলের মান ১০ বা তার কম তখন কাজ করবে, অন্যথায় করবে না।

এই উপায়টিই হল ifif হল একপ্রকার C/C++ কিওয়ার্ড (keyword)। এর মাধ্যমে আমরা কন্ডিশনাল (conditional) স্টেটমেন্ট লিখতে পারি। কন্ডিশনাল স্টেটমেন্ট এ কোন কন্ডিশন বা শর্তের সাপেক্ষে এর মধ্যেকার স্টেটমেন্ট ব্লক (block) এক্সিকিউট হয়। যেমন উপরের সমস্যার জন্য সমাধানটি দেখতে হবে এরকমঃ


printf(“Price of a single pen = ”);
scanf( “%d” , &priceOfPen ); //কলমের দাম জিজ্ঞেস করা হল
if( priceOfPen <= 10 ) //যদি কলমের দাম ১০ টাকার সমান বা কম হয়
{
   printf( “Buy 10 pens.\n” ); //১০টি কলম কেনা হল
}

এখানে 3 নম্বর লাইনের ( priceOfPen <= 10 ) অংশটুকুই হল এই if এর জন্য ব্যবহৃত কন্ডিশন বা শর্ত। 4 ও 5 নম্বর লাইনে ব্যবহৃত { এবং } দিয়ে if এর মধ্যেকার স্টেটমেন্ট ব্লক কে বোঝানো হয়। এই ব্লকের মধ্যে লেখা স্টেটমেন্ট গুলো শুধু মাত্র if এর কন্ডিশনটি সত্যি হলে এক্সিকিউট হবে অন্যথায় হবে না। if এর ব্লকের মধ্যে একাধিক স্টেটমেন্ট থাকতে পারে। সেক্ষেত্রে সবার জন্যই একই শর্ত প্রযোজ্য হবে। যে সব স্টেটমেন্ট if এর ব্লকের বাইরে, তাদের ক্ষেত্রে if এর কন্ডিশন সত্যি বা মিথ্যা হওয়ার কোন রূপ পরিবর্তন আনবে না। একটি উদাহরনের সাহায্যে আমরা বুঝতে চেষ্টা করিঃ


printf(“Price of a single pen = ”);
scanf( “%d” , &priceOfPen ); //কলমের দাম জিজ্ঞেস করা হল
if( priceOfPen <= 10 ) //যদি কলমের দাম ১০ টাকার সমান বা কম হয়
{
   printf( “Buy 10” ); //১০টি কলম কেনার লাইনটি আমরা একাধিক
   printf( “ pens.\n” ); //লাইন জুড়ে লিখলাম
}
printf( “End of Program\n” );

এই প্রোগ্রামটি চালালে, আমরা আগের মতই priceOfPen এর মানের উপর নির্ভর করে Buy 10 pens. লেখাটা দেখতেও পারে, আবার নাও পারে। কিন্তু priceOfPen এর মান যাই হোক না কেন, আমরা সবসময়ই 8 নম্বর লাইনে লেখা End of Program অবশ্যই দেখব। কারন এই লাইনটি if এর ব্লকের বাইরে অবস্থিত।

ইফ এলস এর প্রাথমিক ধারনা লজিক, ইফ, এলস

আমরা অনেক সময়ই এরকম বাক্য শুনে থাকি, “যদি আজ চাঁদ দেখা যায়, তাহলে আগামীকাল ঈদ। নাহলে আগামী পরশুদিন ঈদ।” আমরা এর আগে এরূপ বাক্যের প্রথম অংশকে কিভাবে প্রোগ্রামিং দিয়ে প্রকাশ করা যায় তা দেখেছি। এর জন্য আমরা if ব্যবহার করেছিলাম।


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ

কিন্তু এভাবে যদি আমরা প্রোগ্রামটি লিখি, তাহলে ৭ নম্বর লাইনটি সবসময়ই এক্সিকিউট (execute) হবে, যেটা আমরা চাইনা। আমরা চাই শুধু মাত্র যখন চাঁদ উঠবে না, তখনই শুধু এই লাইনটি এক্সিকিউট (execute)হোক। এরজন্য আমরা চাইলে নিচের মত করে প্রোগ্রাম লিখতে পারিঃ


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
if( answer == ‘n’) // যদি উত্তর না হয়
{
   printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ
}

আমাদের পক্ষে এর থেকেও সহজে এই প্রোগ্রামটি করা সম্ভব if else ব্যবহার করে। অনেক সময়ই আমাদের দুই এর অধিক শর্ত নিয়ে কাজ করতে হবে, এবং সেগুলোর সবগুলোকে একই ভাবে প্রোগ্রাম করানো খুবই কষ্টসাধ্য হবে। উপরোক্ত প্রোগ্রামটি আমরা খুব সহজে নিচের মত করে if else এর সাহায্যে সমাধান করতে পারি।


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
else // অথবা
{
   printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ
}

এই প্রোগ্রামটিও আগেরটির মতই কাজ করবে। এখানে ৭ নম্বর লাইনে লেখা else এর পরের ব্লক (block) টি ({} এর মধ্যে আবধ্য) শুধু মাত্র তখনই এক্সিকিউট (execute) হবে যখন if এ লিখিত কন্ডিশন (condition) বা শর্তটি মিথ্যা হবে। মজার ব্যাপার হল, দ্বিতীয় প্রোগ্রামে, answer হিসাবে শুধুমাত্র ‘n’ লিখলেই কেবল ৯ নম্বর লাইনটি এক্সিকিউট (execute) হত। কিন্তু তৃতীয় প্রোগ্রামে, answer এর মান ‘y’ বাদে অন্য যেকোন কিছু লিখলেই ৯ নম্বর লাইন এক্সিকিউট (execute) হবে। কারন answer এর মান ‘y’ বাদে অন্য যে কোন কিছু হওয়া মাত্রই answer == ‘y’ এই শর্তটি মিথ্যা হয়ে যায়।

ইফ এলস এর প্রাথমিক ধারনা লজিক, ইফ, এলস

আমরা অনেক সময়ই এরকম বাক্য শুনে থাকি, “যদি আজ চাঁদ দেখা যায়, তাহলে আগামীকাল ঈদ। নাহলে আগামী পরশুদিন ঈদ।” আমরা এর আগে এরূপ বাক্যের প্রথম অংশকে কিভাবে প্রোগ্রামিং দিয়ে প্রকাশ করা যায় তা দেখেছি। এর জন্য আমরা if ব্যবহার করেছিলাম।


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ

কিন্তু এভাবে যদি আমরা প্রোগ্রামটি লিখি, তাহলে ৭ নম্বর লাইনটি সবসময়ই এক্সিকিউট (execute) হবে, যেটা আমরা চাইনা। আমরা চাই শুধু মাত্র যখন চাঁদ উঠবে না, তখনই শুধু এই লাইনটি এক্সিকিউট (execute) হোক। এরজন্য আমরা চাইলে নিচের মত করে প্রোগ্রাম লিখতে পারিঃ


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
if( answer == ‘n’) // যদি উত্তর না হয়
{
   printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ
}

আমাদের পক্ষে এর থেকেও সহজে এই প্রোগ্রামটি করা সম্ভব if else ব্যবহার করে। অনেক সময়ই আমাদের দুই এর অধিক শর্ত নিয়ে কাজ করতে হবে, এবং সেগুলোর সবগুলোকে একই ভাবে প্রোগ্রাম করানো খুবই কষ্টসাধ্য হবে। উপরোক্ত প্রোগ্রামটি আমরা খুব সহজে নিচের মত করে if else এর সাহায্যে সমাধান করতে পারি।


printf(“Did the moon rise today?”);
scanf(“%c” , &answer); //চাঁদ উঠলে ‘y’ আর না উঠলে ‘n’ ইনপুট দিব
if( answer == ‘y’ ) // যদি উত্তর হ্যা হয়
{
   printf(“Tomorrow is Eid!!!\n”); //আগামীকাল ঈদ
}
else // অথবা
{
   printf(“Day after tomorrow is Eid!\n”); // আগামী পরশুদিন ঈদ
}

এই প্রোগ্রামটিও আগেরটির মতই কাজ করবে। এখানে ৭ নম্বর লাইনে লেখা else এর পরের ব্লক (block) টি ({} এর মধ্যে আবধ্য) শুধু মাত্র তখনই এক্সিকিউট (execute) হবে যখন if এ লিখিত কন্ডিশন (condition) বা শর্তটি মিথ্যা হবে। মজার ব্যাপার হল, দ্বিতীয় প্রোগ্রামে, answer হিসাবে শুধুমাত্র ‘n’ লিখলেই কেবল ৯ নম্বর লাইনটি এক্সিকিউট (execute) হত। কিন্তু তৃতীয় প্রোগ্রামে, answer এর মান ‘y’ বাদে অন্য যেকোন কিছু লিখলেই ৯ নম্বর লাইন এক্সিকিউট (execute) হবে। কারন answer এর মান ‘y’ বাদে অন্য যে কোন কিছু হওয়া মাত্রই answer == ‘y’ এই শর্তটি মিথ্যা হয়ে যায়।

লুপের প্রাথমিক ধারনা ভূমিকা, লুপ

প্রোগ্রামিং এর খুব মজার একটা ব্যাপার হল লুপ। আমাদের যখন একই ধরনের কাজ বার বার করতে হয়, তখন আমরা সে কাজটি বার বার না লিখে সেটাকে লুপের মাধ্যমে করে ফেলতে পারি। যেমন, আপনাদেরকে যদি বলা হয়, চারবার "Bangladesh" শব্দটি লিখতে, তাহলে এখন হয়ত আপনারা নিচের কোডের মত কিছু চিন্তা করবেন।


#include<stdio.h>

int main(){
    printf("Bangladesh\n");
    printf("Bangladesh\n");
    printf("Bangladesh\n");
    printf("Bangladesh\n");
    return 0;
}

কিন্তু আপনাকে যদি এই একই কাজ ১০০ বার করতে বলা হয়, তখন কিন্তু এভাবে কোড করাটা বেশ কঠিন হয়ে যাবে। কাজেই তখন আমাদের লুপের সাহায্য নিতে হবে।


#include<stdio.h>

int main(){
    int i;
    for(i = 1; i <= 100; i++){
        printf("Bangladesh\n");
    }
    return 0;
}

উপরের কোডে আমরা একটি for লুপ নিয়ে কাজ করেছি। for লুপ লেখার জন্য আমাদের একটি লুপ কন্ট্রোল ভ্যারিয়েবল দরকার হয়, এই কোডে যেটি i। একটি লুপের কন্ট্রোল ভ্যারিয়েবলকে সাধারনত আমরা অন্য লুপের কন্ট্রোল ভ্যারিয়েবল হিসাবে ব্যবহার করি না। আপাতত আমরা এইটুকু বুঝি যে, উপরের লুপে i এর মান 1 থেকে শুরু করে 100 পর্যন্ত যাবে, এবং প্রতিবার এর মান ১ করে করে বাড়বে (i++ লেখার কারনে)। কাজেই যদি আমরা চাইতাম ২০০ বার বাংলাদেশ কথাটি লিখতে, তাহলে আমাদের কোডটি দেখতে নিচের মত হতঃ


#include<stdio.h>

int main(){
    int i;
    for(i = 1; i <= 200; i++){
        printf("Bangladesh\n");
    }
    return 0;
}

লুপের শুরু হিসাবে আমরা এখন শুধু for লুপ দেখলাম। লুপের অধ্যায়ে গিয়ে আমরা লুপ বিষয়ক বিস্তারিত জানতে পারব।

লুপের প্রাথমিক ধারনা - ২ scanf, লুপ

এখন পর্যন্ত আপনারা লুপকে শুধু কোন কাজ নির্দিষ্ট সংখ্যক বার করার কাজে ব্যবহার করেছেন। চাইলে লুপটি কতবার ঘুড়বে, সেটা আমরা নির্দিষ্ট না করে দিয়ে, কি বোর্ড থেকে ইনপুট নিয়ে তার মাধ্যমেও নিয়ন্ত্রন করতে পারি। নিচের প্রোগ্রামটি লক্ষ্য করুনঃ


#include<stdio.h>

int main(){
    int i, n;
    scanf("%d", &n);
    for(i = 1; i <= n; i++){
        printf("Bangladesh\n");
    }
    return 0;
}

এই প্রোগ্রামটি দেখতে আগের উদাহরনের মতই, শুধু পার্থক্য হল এখানে আমরা লুপটিকে n বার ঘুড়িয়েছি। n এর মান কি বোর্ড থেকে ইনপুট নেওয়া হয়েছে।কাজেই আমরা যখন n এর মান যত ইনপুট দিব লুপটি ততবার ঘুরবে। আপনার বিভিন্ন মান ইনপুট দিয়ে কোডটি রান করে দেখতে পারেন।

তাহলে, আমরা যদি চাই এমন প্রোগ্রাম লিখতে যেটি প্রথম nটি জোড় সংখ্যা প্রিন্ট করবে, তার কোডটি কেমন হবে?


#include<stdio.h>

int main(){
    int i, n, even_number = 0;
    scanf("%d", &n);
    for(i = 1; i <= n; i++){
        printf("%d\n", even_number);
        even_number = even_number + 2;
    }
    return 0;
}

সি ডাটা টাইপসমূহ ডাটা টাইপ

যে কোনো প্রোগ্রাম এর জন্যই কিছু data বা তথ্য এর দরকার হয়। কিছু data কম্পিউটার এর ভিতরে থাকে এবং কিচ্ছু data কীবোর্ড বা মাউসের মাধ্যমে ইনপুট দিতে হয়। যেমন আপনারা যখন কোনো রেসিং গেম খেলেন তখন গাড়ির ডিসাইন, ট্র্যাকার এর ডিসাইন সব ই data হিসাবে কম্পিউটার এ সংরক্ষিত থাকে। আবার যখন ,arrow key দিয়ে গাড়িকে ডানে অথবা বামে সরান তখন সেগুলো ও program এর data হিসাবে কাজ করে। তবে এসব ডাটা সাধারণ কোনো data নয় তাই আপাতত আমরা অনেক সহজ কিছু data বা তথ্য নিয়ে আলাপ করব। ধরা যাক আপনি একটি ছোট প্রোগ্রাম লিখতে চান যা কোনো পরীক্ষা এর ফলাফল তৈরী করবে। সেক্ষেত্রে ওই প্রোগ্রাম কে নিম্নলিখিত তথ্য গুলো দিতে হবে


পরীক্ষার্থীর নাম
বাবার নাম
মার নাম
রোল নম্বর
রেজিস্ট্রেশন নম্বর
প্রতি বিষয়ে প্রাপ্ত নম্বর

প্রতি বিষয়ে প্রাপ্ত নম্বর পাওয়ার পর প্রোগ্রাম CGPA বের করবে। এখন লক্ষ্য করুন যে প্রোগ্রামটি তে নানা রকম data এর প্রয়োজন এবং তারা সব গুলা একই ধরনের নয়। পরীক্ষার্থীর নাম, বাবার নাম, মার নাম এইগুলা হলো স্ট্রিং টাইপ data; রোল নম্বর, রেজিস্ট্রেশন নম্বর, প্রতি বিষয়ে প্রাপ্ত নম্বর এইগুলা হলো পূর্ণ সংখ্যা বা integer data এবং CGPA হলো একটি ভগ্নাংশ বা fractional বা floating-point data. এসব data type এর মধ্যে string data type, C language এর কোনো মৌলিক data type নয়। কাজেই এটি নিয়ে আমরা পরে আলোচনা করব। C language এ মৌলিক data type তিনটি। এগুলো হলো:


Integer data type
Character data type
Floating-point data type

ভ্যারিয়েবল ১ ভ্যারিয়েবল

আমাদের প্রথম প্রোগ্রামটি হবে দুটি সংখ্যা যোগ করার প্রোগ্রাম। এখন কথা হচ্ছে, সংখ্যাগুলো তো কম্পিউটারের মেমোরিতে রাখতে হবে, সেই জটিল কাজটি কীভাবে করব? চিন্তা নেই! সব প্রোগ্রামিং ল্যাঙ্গুয়েজে ভ্যারিয়েবল বলে একটি জিনিস আছে যেটি কোন নির্দিষ্ট মান ধারণ করার জন্য ব্যবহার করা হয়। ভ্যারিয়েবলের একটি নাম দিতে হয়, তারপর ভ্যারিয়েবল = কোনো মান লিখে দিলে ভ্যারিয়েবলের ভেতর সেটি ঢুকে যায়। এটির সঙ্গে গাণিতিক সমীকরণের কিন্তু কোনো সম্পর্ক নেই। চলুন, প্রোগ্রামটি লিখে রান করাই, তারপর ব্যাখ্যা করা যাবে।


#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-এর সমান, অর্থাৎ ab-এর যোগফল যে সংখ্যাটি হবে সেটি আমরা 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 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); লিখে প্রোগ্রামটি আবার চালিয়ে দেখুন। একটু চিন্তা করে দেখুন তো বুঝতে পারছেন কিনা!

আসলে, printf এর ভেতরে আমরা যতগুলো %d দেব, ঠিক ততগুলো ভ্যারিয়েবলকে সে প্যারামিটার হিসাবে চাইবে। কোন %d এর জায়গায় কোন ভ্যারিয়েবলের মান বসবে সেটা নির্ধারণ হবে কমা দিয়ে দিয়ে লেখা ভ্যারিয়েবলের ক্রমের উপরে। আমাদের কোডে printf("%d + %d = %d", a, b, sum); লেখায়, প্রথম %d এর জায়গায় a এর মান, দ্বিতীয় %d এর জায়গায় b এর মান এবং শেষ %d এর জায়গায় sum এর মান বসেছে। printf("%d + %d = %d", b, a, sum); লিখলে প্রথমে b এর মান, এবং পরে a এর মান বসবে।

printf("%d + %d = %d", a, sum, a); লিখলে কি প্রিন্ট হয় চেষ্টা করে দেখুন তো?

ভ্যারিয়েবল ৪ ভ্যারিয়েবল

ধরা যাক, আমরা যদি 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 ব্যবহার করলাম। এবারে প্রোগ্রাম চালান, দেখুন কী হয়।

আউটপুট হবে: 50 + 60 = 110

সি কম্পাইলার a-এর মান 50 ধরেছে, যদিও আমরা 50.45 অ্যাসাইন করেছি। এই ব্যাপারটিকে বলে টাইপ কাস্ট (type cast)। বাস্তব (real number) সংখ্যা রাখার জন্য সি ভাষায় double নামের ডাটা টাইপ রয়েছে। টাইপ কাস্ট করে double সংখ্যাটিকে int-এ নেওয়া হয়েছে, এটি অটোমেটিক হয়। আবার কম্পাইলারকে বলেও দেওয়া যায়: int a = (int) 50.45

int a = 50.99; এখানে a-এর মান হবে 50int 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টি সংখ্যা।

ইন্টেজার ডাটা টাইপ - ১ ডাটা টাইপ

কোনো পূর্ণ সংখ্যা বুঝানোর জন্য C তে যে data type ব্যবহার করা হয় তাকে বলা হয় integer data type. Integer data type চেনার উপায়ে হলো যে এর মধ্যে ডিজিট ছাড়া অন্য কিছু থাকবে না। Integer data type এর মান গুলোকে আমরা তিন ধরনের ধ্রুবক (Constant) দিয়ে প্রকাশ করি

Decimal Integer ধ্রুবক

Octal ধ্রুবক

Hexadecimal ধ্রুবক

ইন্টেজার ডাটা টাইপ - ২ ডাটা টাইপ

Decimal Integer ধ্রুবক:

যে কোনো দশমিক মানকে Decimal Integer ধ্রুবক দিয়ে প্রকাশ করা যায়। Decimal Integer ধ্রুবক এর বৈশিষ্ট্য হলো

এটি শুধু মাত্র দশমিক অঙ্ক ,(Decimal Digit - 0...9) দিয়ে তৈরী হবে.

Decimal Integer ধ্রুবক এর একদম শুরুতে একটি বিয়োগ (unary মাইনাস) থাকতে পারে।কাধিক অঙ্ক বিশিষ্ট Decimal Integer ধ্রুবক এর প্রথম অঙ্কটি শূন্য ,code>(০)

হবে নাহ.তাই 678, -567 এগুলো সব সঠিক Decimal Integer ধ্রুবক। কিন্তু নিম্নের Decimal Integer ধ্রুবক গুলো সঠিক নয়:


20,000 //কারণ এখানে কমা রয়েছে
040000 //কারণ এইখানে প্রারম্ভে একটি শূন্য রয়েছে
246A //কারণ এখানে A কোনো decimal অঙ্ক নয়
-45-66 //কারণ এখানে সংখ্যার মাঝখানে বিয়োগ চিহ্ন রয়েছে।

ইন্টেজার ডাটা টাইপ - ৩ ডাটা টাইপ

Octal ধ্রুবক:

যে কোনো Octal মানকে Octal ধ্রুবক দিয়ে প্রকাশ করা যায়। Octal ধ্রুবক এর বৈশিষ্ট্য হলো

এটি শুধু মাত্র Octal অঙ্ক (Octal Digit - 0...7) দিয়ে তৈরী হবে.Octal ধ্রুবক এর একদম শুরুতে একটি বিয়োগ (unary মাইনাস) থাকতে পারে।Octal ধ্রুবক এর প্রথম অঙ্কটি শূন্য (০) হবে.তাই 067, -567 এগুলো সব সঠিক Octal ধ্রুবক। কিন্তু নিম্নের Octal ধ্রুবক গুলো সঠিক নয়:



020,000 //কারণ এখানে কমা রয়েছে
40000 //কারণ এইখানে প্রারম্ভে একটি শূন্য নাই
02468 //কারণ এখানে 8 কোনো octal অঙ্ক নয়
45-66 //কারণ এখানে সংখ্যার মাঝখানে বিয়োগ চিহ্ন রয়েছে।

Hexadecimal ধ্রুবক

যে কোনো Hexadecimal মানকে Hexadecimal ধ্রুবক দিয়ে প্রকাশ করা যায়। Hexadecimal ধ্রুবক এর বৈশিষ্ট্য হলোএটি শুধু মাত্র Hexadecimal অঙ্ক (Hexadecimal Digit - 0...9, A...F ,a...f) দিয়ে তৈরী হবে.Hexdecimal ধ্রুবক এর একদম শুরুতে একটি বিয়োগ (unary মাইনাস) থাকতে পারে।Hexadecimal ধ্রুবক এর শুরুতে 0x থাকবেতাই 0x67, -0x567A, 0xabcf এগুলো সব সঠিক Hexadecimal ধ্রুবক। কিন্তু নিম্নের Hexadecimal ধ্রুবক গুলো সঠিক নয়:


0x20000 //কারণ এখানে কমা রয়েছে
040000 //কারণ এইখানে প্রারম্ভে 0x নাই
0x246G //কারণ এখানে G কোনো hexadecimal অঙ্ক নয়
0x45-66 //কাHexadecimal ধ্রুবক

যে কোনো Hexadecimal মানকে ,Hexadecimal ধ্রুবক দিয়ে প্রকাশ করা যায়। Hexadecimal ধ্রুবক এর বৈশিষ্ট্য হলো

এটি শুধু মাত্র Hexadecimal অঙ্ক (Hexadecimal Digit - 0...9, A...F ,a...f) দিয়ে তৈরী হবে.Hexdecimal ধ্রুবক এর একদম শুরুতে একটি বিয়োগ (unary মাইনাস) থাকতে পারে।Hexadecimal ধ্রুবক এর শুরুতে 0x থাকবে তাই 0x67, -0x567A, 0xabcf এগুলো সব সঠিক Hexadecimal ধ্রুবক। কিন্তু নিম্নের Hexadecimal ধ্রুবক গুলো সঠিক নয়:


0x20000 //কারণ এখানে কমা রয়েছে
040000 //কারণ এইখানে প্রারম্ভে 0x নাই
0x246G //কারণ এখানে G কোনো hexadecimal অঙ্ক নয়
0x45-66 //কারণ এখানে সংখ্যার মাঝখানে বিয়োগ চিহ্ন রয়েছে।রণ এখানে সংখ্যার মাঝখানে বিয়োগ চিহ্ন রয়েছে।


ফ্লোটিং পয়েন্ট ডাটা টাইপ ডাটা টাইপ

প্রকতিতে প্রাপ্ত জিনিসের পরিমাপে integer বা পূর্ণসংখ্যাই প্রায় সব ক্ষেত্রে যথেষ্ট। যেমন দুটি গাছ, পঞ্চাশটি লিচু ইত্যাদি। কিন্তু মানুষ যখন পরিমাপ করতে শিখল, সময়ের হিসাব শিখল, কিংবা বৈজ্ঞানিক পরীক্ষা করতে শিখল তখন পূর্ণ সংখ্যা দিয়ে সবকিছু পরিমাপ করতে আর পারল না। যেমন বেলা আড়াইটা বাজে, তোমার ওজন ১২৫.৬ পাউন্ড, pi এর মান (প্রায়) ৩.১৪১৫৯২৬৫৪, এক কেজি চকলেট তিন জনের মধ্যে সমান ভাগ করে দিলে প্রত্যেকে ১/৩ কেজি করে পাবে, একটি বর্গের ক্ষেত্রফল হলে এর বাহুর দৈর্ঘ্য । তখন আবিষ্কার হলো অপূর্ণ দশমিক সংখ্যা (২.৫৬), ভগ্নাংশ (১/৩), মূলদ (৪/৩) এবং অমূলদ (২) সংখ্যার। C language এ ভগ্নাংশ, মূলদ এবং অমূলদ সংখ্যার জন্য আলাদা কোনো data type নেই। কিন্তু অপূর্ণ দশমিক সংখ্যা বুঝানোর জন্য একটি data type রয়েছে যাকে আমরা বলি floating-point data type. floating-point data type এর মান গুলো প্রকাশের জন্য আমরা floating-point constant ব্যবহার করি. যেমন 15.6, 10e+006 এ সব গুলি floating-point constant. C language এর floating-point constant এর বৈশিষ্ট্য গুলো হলো:

Decimal Integer কনস্ট্যান্ট এর মত floating-point constant ও শুধুমাত্র দশমিক অঙ্ক (০-৯) থাকতে পারবে।এর মধ্যে অবশ্যই একটি দশমিক চিহ্ন (.) অথবা সুচক চিহ্ন (e/E) অথবা দুটোই সর্বোচ্চ একবার থাকতে হবে।সংখ্যার শুরুতে একটি এবং সুচক চিহ্নর পর আরকেটি বিয়োগ (-) চিহ্ন থাকতে পারে।সংখ্যাটি ভগ্নাংশ হলেও সুচক এর মান সবসময় পূর্ণ সংখ্যা হবে.প্রথম অঙ্কটি শূন্য হলেও ধ্রুবকটি ডেসিমাল হিসাবেই বিবেচিত হবে.কাজেই 34.56, -45e+30, 33.56E-90, 033.6 এসবগুলোই সঠিক floating-point ধ্রুবক কিন্তু নিম্নের floating-point ধ্রুবক গুলো সঠিক নয়:


34..566 //কারণ এখানে দুটি দশমিক চিহ্ন রয়েছে
0xABC.13 //কারণ floating-point ধ্রুবক শুধু দশমিক সংখ্যা হতে পারে।
4646e-13.0 //কারণ সূচকের মান কখনো floating-point হতে পারে না
34283 //কারণ floating-point constant এ দশমিক চিহ্ন অথবা সুচক চিহ্ন থাকতেই হবে।
234A //কারণ শুধুমাত্র দশমিক অঙ্ক ব্যবহার করা যাবে
 

ক্যারেক্টার ডাটা টাইপ - ১ ডাটা টাইপ

ক্যারেক্টার ডাটা টাইপ (character data type) এবং ইন্টিজার ডাটা টাইপ (integer data type) এর মধ্যে পার্থক্য খুব ই সামান্য। ইন্টিজার ডাটা টাইপ (integer data type) এর শুধু একটি ইন্টিজার (integer) মান থাকে কিন্তু ক্যারেক্টার ডাটা টাইপ এর একটি ইন্টিজার মান এবং একটি ক্যারেক্টার মান থাকে। C প্রোগ্রামিং ভাষায় ক্যারেক্টার ডাটা টাইপ ২৫৬ রকমের মান গ্রহণ করতে পারে। এর মধ্যে প্রথম ১২৮ টি মান বেশি ব্যবহৃত হয়। যে table এ ক্যারেক্টার ডাটা টাইপ এর ইন্টিজার ও ক্যারেক্টার মান দেয়া থাকে তাকে ASCII Character Table বলা হয়। character মান বুঝানোর জন্য আমরা C তে সেটিকে single quotation (' ') এর মধ্যে লিখে থাকি। কাজেই C প্রোগ্রামিং ভাষা এ a একটি identifier কিন্তূ 'a' একটি character. ক্যারেক্টার এর প্রকৃতি ভেদে ASCII Character Set কে কযেক ভাগে ভাগ করা হয়। এগুলো হলো


ASCII কন্ট্রোল ক্যারেক্টার সমূহ (ASCII Control Character) (৩৪ টি )
ইংলিশ বর্ণমালা ক্যারেক্টার সমূহ (English Alphabet Characters) (৫২ টি)
যতিচিহ্ন বিষয়ক ক্যারেক্টার সমূহ (Punctuation Characters) (৩২ টি)
Numbers (১০ টি)
অতিরিক্ত ASCII ক্যারেক্টার সমূহ (Extended ASCII Characters) (১২৮ টি )
 

ক্যারেক্টার ডাটা টাইপ - ৬ ডাটা টাইপ

Extended ASCII Characters তালিকা এখানে দিচ্ছি না কারণ এগুলোর ব্যবহার খুবই সীমিত ASCII ক্যারেক্টার table এর মান গুলো সব মুখস্ত করার কোনো প্রয়োজন নাই। শুধু কয়েকটা ক্যারেক্টার এর মান মুখস্ত করলেই চলবে। এগুলো হলো


'0' = ৪৮ //Zero
'A ' = ৬৫ //Capital A
'a' = ৯৭ //Small A
' ' = ৩২ //Space

এর কারণ হলো যে 'A' এর মান মনে রাখলে 'A' থেকে 'Z' পর্যন্ত সকল character এর Integer মান বের করা সম্ভব। যেমন 'B' এর মান 'A' থেকে বেশি, 'C' এর মান 'A' থেকে বেশি, এভাবে 'Z' এর মান 'A' থেকে ২৫ বেশি। 'a' এর মান মনে রাখলে 'a' থেকে 'z' পর্যন্ত সকল character এর Integer মান বের করা সম্ভব। যেমন 'b' এর মান 'a' থেকে বেশি, 'c' এর মান 'a' থেকে বেশি, এভাবে 'z' এর মান 'a' থেকে ২৫ বেশি। একইভাবে, '0' এর মান মনে রাখলে '0' থেকে '9' পর্যন্ত সকল character এর Integer মান বের করা সম্ভব।

ওভারফ্লো এবং আন্ডারফ্লো - ২ ওভারফ্লো, ডাটা টাইপ

ধরা যাক আমরা তিনটি integer variable a, b এবং c ডিক্লেয়ার করলাম।


int a = 2000000000, b = 2000000000, c;
c = a + b;

এখন যদি আমরা a এবং b এর যোগফল c ভ্যারিয়েবল এ রাখার চেষ্টা করি তাহলে সমস্যা হবে। কারণ a এবং b এর যোগফল 4000000000, কিন্তু signed integer এ সর্বোচ্চ যে মানটি রাখা সম্ভব তা হলো , 2147483647। কাজেই এখনে যোগটি ঠিকমত হবেনা, যা ঘটবে সেটা হলো overflow.

Overflow যে শুধু ধনাত্মক মানের জন্য ঘটে তা নয়। ঋণাত্মক মানের জন্য ও ঘটতে পারে। যেমন আমরা নিচের variable declaration টি লক্ষ্য করি:


int a = -2000000000, b = -2000000000, c;
c = a + b;

এখন যদি আমরা a এবং b এর যোগফল c ভ্যারিয়েবল এ রাখার চেষ্টা করি তাহলেও সমস্যা হবে। কারণ a এবং b এর যোগফল -4000000000, কিন্তু signed integer এ সর্বনিম্ন যে মানটি রাখা সম্ভব তা হলো -2147483648। কাজেই এখনে যোগটি ঠিকমত হবেনা, যা ঘটবে সেটাও হলো overflow. সাবধান থাকতে হবে কারণ এখানে overflow টি ঋণাত্মক মানের জন্য ঘটছে বলে অনেকে এটাকে underflow ভাবলে সেটা হবে একটি বড় ভুল।

অন্যান্য ধরনের variable এর ক্ষেত্রেও overflow ঘটতে পারে। নিচের উদাহরণটি লক্ষ্য করি:


double a = 1e300, b = 1e200, c;
c = a * b;

এখন double ভ্যারিয়েবল এ সর্বোচ্চ যে মানটি রাখা যায় তা হলো 1.797693e+308, কিন্তু এখানে a*b এর মান ,1e500, কাজেই এখন overflow ঘটবে।

unsigned integer data type এর ক্ষেত্রে ওভারফ্লো ঘটেনা। তবে এর কারণ এখন বিস্তারিতভাবে না বলাই ভাল।

ওভারফ্লো এবং আন্ডারফ্লো - ৩ আন্ডারফ্লো, ডাটা টাইপ

Integer data type এর ক্ষেত্রে underflow flow ঘটেনা। এটি শুধুমাত্র floating-point এর ক্ষেত্রে ঘটে. উপরের টেবিল এ আমরা যদি লক্ষ্য করি তাহলে দেখব যে ,double type variable এর রেঞ্জ দেয়া আছে 2.225074e-308 থেকে 1.797693e+308. ঠিক এক ই রকম রেঞ্জ ঋণাত্মক অংশেও আছে. অর্থাৎ সেখানে range টা হলো: -2.225074e-308 থেকে 1.797693e+308 পর্যন্ত। সুতরাং 2.225074e-308 বা -2.225074e-308 থেকেও শুন্যের আরো কাছাকাছি কোনো মান, যেমন ১e-৪০০ বা -১e-৪০০ যদি আমরা double variable এ রাখতে যাই তাহলে রাখা সন্ভব হবেনা। এই ঘটনাকেই C languageunderflow বলা হয়। আমরা এখন নিচের উদাহরণটি দেখি:


double a=1e-300, b=4.5e-200, c;
c=a*b;

এখানে a এবং b এর মান গুণ হবার সময় underflow ঘটবে, ফলে c তে সঠিক মান থাকবে না।

ডাটা টাইপের রেঞ্জ ভ্যারিয়েবল

আমরা চাইলে নিচের টেবিলে দেখানো টাইপের মত যে কোন ভ্যারিয়েবল নিয়ে কাজ করতে পারি। কোন টাইপের ভ্যারিয়েবল কি কি মান নিয়ে কাজ করতে পারে, তার একটা ধারনা নিচের টেবিলে দেওয়া হলঃ


Variable Type*  প্রয়োজনীয় memory  সর্বনিম্ন মান সর্বোচ্চ মান
signed character(char)  1 byte  -27 = -128  27 -1= 127
short integer (short) 2 byte  -215 = -32768 215-1 = 32767
signed integer (int)  4 byte1 -231 = -2147483648  231-1 = 2147483647
unsigned integer (unsigned int) 4 byte1 0 232-1 = 4294967295
signed long integer (long int)  4 byte2 -231 = -2147483648  231-1 = 2147483647
unsigned long integer (unsigned long int) 4 byte2 0 232-1 = 4294967295
long long integer ( long long)  8 byte3 -263 = -9223372036854775808 263-1 = 9223372036854775807
unsigned long long integer (unsigned long long) 8 byte  0 
264-1 = 18446744073709551615

single precision floating-point (float)4  4 byte  1.175494e-038 3.402823e+038
double precision floating-point (double)4 8 byte  2.225074e-308 1.797693e+308
 
* প্রয়োজনীয় memory এর মান মূলত 32-bit compiler এর সাপেক্ষে বসানো হয়েছে।

1 অনেক ৬৪-bit compiler এ integer ৮ byte জায়গা দখল করে।

2 অনেক ৬৪-bit compiler এ long integer ৮ byte জায়গা দখল করে।

3 মাইক্রোসফট এর Visual  C++ compiler এ long long বলতে কিছু নেই। সেখানে 64-bit integer এর জন্য __int64 keyword ব্যবহার করা হয়।

4 এখানে শুধু ধনাত্মক মানের range দেয়া আছে। ঋণাত্মক মানের দিকেও একই রেঞ্জ বিদ্যমান।
উপরের টেবিল থেকে আমরা সাধারণ ভাবে যেটা বলতে পারি তা হলো:

একটি n-bit signed integer  এর সম্ভব সর্বোচ্চ মান = 2n-1-1

একটি n-bit signed integer  এর সম্ভব সর্বনিম্ন মান = -2n-1

একটি n-bit unsigned integer  এর সম্ভব সর্বোচ্চ মান = 2n-1

একটি n-bit unsigned integer  এর সম্ভব সর্বনিম্ন মান = -2n

Hello World প্রিন্ট করা আউটপুট

আমরা কম্পিউটার প্রোগ্রামের (program) মাধ্যমে অনেক জটিল জটিল হিসাব নিকাশ করতে পারি। কিন্তু আমাদেরতো শুধু হিসাব নিকাশ করলেই হবে না, ফলাফলও দেখতে হবে। সি (C) প্রোগ্রামিং ল্যাঙ্গুয়েজ (programming language) থেকে যেকোনো কিছু ফলাফল সরূপ আউটপুট (output) হিসাবে দেখতে হলে তোমাকে সি (C) এর কিছু লাইব্রেরি ফাংশন (library function) যেমন printf() ব্যবহার করতে হবে এবং আউটপুটটি তোমাকে একটি স্ক্রিন (screen) তথা কনসোলে (console) দেখাবে যদি আমরা স্ক্রীনে “Hello World” লেখাটি দেখাতে চাই, তাহলে আমাদের একটি প্রোগ্রাম লেখতে হবে, যার মেইন (main) ফাংশনে থাকবে নিচের লাইনটি:

printf("Hello World");

আমরা আমাদের পছন্দের যেকোনো ইংরেজি বাক্য স্ক্রিনে প্রিন্ট করতে পারব| যেমন:


printf("My name is Meena.");
printf("I have to go to school.");

উপরের দুটো লাইনের কারণ আমরা আউটপুট পাব My name is Meena. I have to go to school.

করা আউটপুট, ইন্টেজার

আমরা ইতিমধ্যে পুর্ণসংখা বা ইন্টিজার ভ্যারিয়েবল (integer variable) কিভাবে ডিক্লেয়ার (declare) করা যায় তা জেনেছি| আমরা ইন্টিজার ভ্যারিয়েবলের একটি উদাহরণ যদি দেখি| তোমাকে যদি জিজ্ঞাসা করা হয় যে সুন্দরবনে কয়টি বাঘ আছে, তুমি কখনই বলবে না ৩.৯ টি বা ৪.২ টি| তুমি হয়ত বলবে সুন্দরবনে ৪ টি বাঘ আছে (তুমি তাই জানো)| তাহলে আমরা একটি ইন্টিজার ভ্যারিয়েবল ডিক্লেয়ার করতে পারি এভাবে:

int number_of_tiger = 4;

এখন একজন যদি তোমার কাছে জানতে চায় বা তোমাকে বলে যে সুন্দরবনে কয়টি বাঘ আছে তুমি আমাকে প্রিন্ট করতে দেখাও তাহলে তুমি উপরের ডিক্লেয়ার করা ভ্যারিয়েবলটি প্রিন্ট করে দাও এইভাবে:

printf("%d",number_of_tiger);

এই প্রোগ্রামটি এক্সিকিউট করলে আমরা আউটপুট হিসাবে দেখবে পাব 4.

আমরা যদি আরেকটি ভ্যারিয়েবল এর কথা চিন্তা করি:


int number_of_tiger = 4;
int number_of_deer = 10;

আর যদি আমরা বাঘের সংখ্যার সাথে সাথে হরিনের সংখ্যাও জানতে চাই তাহলে আমরা লিখব:

printf("%d %d", number_of_tiger, number_of_deer);

এই প্রোগ্রামটি এক্সিকিউট করলে আমরা আউটপুট পাব 4 10. উল্লেখ্য, এখানে %d হচ্ছে ইন্টিজার ভ্যারিয়েবলের জন্য output formate specifier | তুমি যদি কখনো printf() এর মাধ্যমে ইন্টিজার ভ্যারিয়েবল এর মান প্রিন্ট করতে চাও তাহলে তোমাকে %d ব্যবহার করতে হবে | উপরের উদাহরণে প্রথম %d এর মাধ্যমে প্রিন্ট হবে number_of_tiger এর মান এবং দ্বিতীয় %d এর মাধ্যমে প্রিন্ট হবে number_of_deer এর মান|

string প্রিন্ট করা আউটপুট, ইন্টেজার, ডাবল, ক্যারেক্টার, স্ট্রিং

আমরা ইতিমধ্যে পুর্ণসংখা বা ইন্টিজার ভ্যারিয়েবল (integer variable) কিভাবে ডিক্লেয়ার (declare) এবং প্রিন্ট করা যায় তা জেনেছি| আমরা ইন্টিজার ভ্যারিয়েবল প্রিন্টের আগের উদাহরণটি যদি আবার দেখি: জঙ্গলে যদি ৫ টি বাঘ আর ১০ টি হরিন থাকে, আমরা ২ টি ভ্যারিয়েবল দিয়ে প্রকাশ করতে পারি এভাবে:


int number_of_tiger = 5;
int number_of_deer = 10;

এখন আমরা যদি বাঘ এবং হরিনের সংখ্যা প্রিন্ট করতে চাই তাহলে লিখব:

printf("%d %d", number_of_tiger, number_of_deer);

এই প্রোগ্রামটি এক্সিকিউট করলে আমরা আউটপুট পাব 4 10 | কিন্তু আমরা যদি আরেকটু ভাবপূর্ণ একটি বাক্য দেখতে চাই তাহলে আমরা লিখতে পারি:

printf("Number of Tiger %d and Number of Deer %d", number_of_tiger, number_of_deer);

এই প্রোগ্রামটি এক্সিকিউট করলে আমরা আউটপুট পাব Number of Tiger 5 and Number of Deer 10

এভাবে আমরা যেকনো বাক্যের ভিতর অজানা ভ্যারিয়েবল এর মান প্রিন্ট করতে পারি| একইভাবে আমরা যদি বাস্তব ভ্যারিয়েবল বা দশমিক ভ্যারিয়েবল (double) প্রিন্ট করতে চাই তাহলে আমরা printf() ফাংশনে %d output specifier এর জায়গায় %lf ব্যবহার করবো| যেমন:

double pi = 3.14159265; printf("Value of Pi is %lf",pi);

উপরের প্রোগ্রামটি এক্সিকিউট করলে আমরা আউটপুট পাব Value of Pi is 3.141593

একইভাবে আমরা char টাইপ ভ্যারিয়েবল প্রিন্ট করতে পারি %c output specifier ব্যবহার করব| যেমন


char alphabet = 'Z';
printf("Last alphabet of english is %c",alphabet);

উপরের প্রোগ্রামটির আউটপুট হবে : Last alphabet of english is Z

String ভ্যারিয়েবল প্রিন্ট করা আউটপুট, স্ট্রিং

আমরা ইতিমধ্যে স্ট্রিং (string or character array) ভ্যারিয়েবল কিভাবে ডিক্লেয়ার (declare) করা যায় তা জেনেছি| ধরো তোমার নাম XYZ | আমরা একটি স্ট্রিং ভ্যারিয়েবল দিয়ে তোমার নাম টি যদি সেভ করতে চাই তাহলে লিখতে পারি

char name[5] = "XYZ";

আমরা এখন তোমার নামটি কনসোলে প্রিন্ট করে দেখতে চাই| তাহলে আমরা লিখবো

printf("%s", name);

এখানে %s হলো স্ট্রিং ভ্যারিয়েবল প্রিন্ট করার জন্য output specifier | এই প্রোগ্রামটি রান (run) করলে আউটপুট পাবো :

XYZ

আমরা যদি লেখি

printf("My name is %s.",name);

তাহলে আমরা আউটপুট পাবো

My name is XYZ.

ইনপুট নেয়া ইনপুট, ইন্টেজার

আমরা ইতিমধ্যে পুর্ণসংখা বা int কিভাবে ডিক্লেয়ার করতে হয় এবং int ভ্যারিয়েবল কিভাবে প্রিন্ট করতে হয় তা জেনেছি | উধাহরণ সরূপ আমরা যদি দেখি

int numberOfTiger = 5;

এখানে তুমি আগে থেকেই জানো যে সুন্দরবনে ৫ টি বাঘ আছে | তাই তুমি ভ্যারিয়েবলটি ডিক্লেয়ার এর সময় তার মান ৫ বসিয়ে দিতে পার | কিনতু যদি তুমি আগে থেকে না জানো বনে কয়টি বাঘ আছে অথবা প্রোগ্রামটি করার আগে তুমি জানতে বনে ৫ টি বাঘ আছে কিনতু প্রোগ্রামটি রান করার পর তোমাকে বাঘের সংখ্যা পরিবর্তন করতে হতে পারে | তুমি রানটাইমে বা প্রোগ্রাম টি রান (run) করার পর numberOfTiger ভ্যারিয়েবলটির মান পরিবর্তন করবা কিভাবে? এখানে আমরা scanf() ফাংশনটি ব্যবহার করতে পারি | যেমন


int numberOfTiger;
scanf("%d",&numberOfTiger);
printf("Number of tiger = %d.\n",numberOfTiger);

এই প্রোগ্রামটি রান (run) করলে প্রোগ্রামটি তোমার কাছ থেকে ইনপুট নেয়ার জন্য অপেক্ষা করে বসে থাকবে | যেহেতু তুমি scanf এর ভিতর "%d" output specifier ব্যবহার করেছ তাই শুধু মাত্র পূর্ণসংখ্যা ইনপুট দিতে পারবে | ধরো তুমি ইনপুট দিলে 100, তাহলে প্রোগ্রামটি আউটপুট দিবে

Number of tiger = 100.

এখানে একটি জিনিস লক্ষনীয় যে scanf এ ভ্যারিয়েবল এর আগে আমরা & চিহ্নটি ব্যবহার করি | আমরা যদি আরেকটি উধাহরণ দেখি


int x, y;
printf("Enter two integer number: ");
scanf("%d %d", &x, &y);
printf("You have entered %d and %d.\n", x, y);

উপরের প্রোগ্রামটি রান (run) করলে প্রোগ্রামটি প্রথমে একটি লাইন প্রিন্ট করবে

Enter two integer number:

তারপর সে তোমার ইনপুটের জন্য অপেক্ষা করবে | তুমি দুটি পুর্ণসংখ্যা ইনপুট দিলে সে, এই দুটো নম্বরকে x এবং y নামক দুটি ভ্যারিয়েবল এ রেখে দিবে | ধরো তুমি ইনপুট দিলে 15 এবং 7, তাহলে x এ সেভ হবে 15 এবং y এ সেভ হবে 7 | শেষের printf টির বদলৌতে আমরা আরেক লাইন আউটপুট পাব

You have entered 15 and 7.

ইনপুট নেয়া ইনপুট, ইন্টেজার, ডাবল, ক্যারেক্টার

আমরা ইতিমধ্যে পুর্ণসংখা বা int কিভাবে ডিক্লেয়ার, প্রিন্ট এবং ইনপুট নিতে হয় তা জেনেছি | একইভাবে আমরা অন্য টাইপের ভ্যারিয়েবলের ইনপুট ও নিতে পারি | আমাদের শুধু সঠিক output specifier ব্যবহার করতে হবে | যেমন আমরা যদি একটি char টাইপ ভ্যারিয়েবলের মান ইনপুট নিতে চাই তাহলে আমরা "%c" output specifier ব্যবহার করব | উধাহরণ সরূপ


char alphabet;
scanf("%c", &alphabet);
printf("The alphabet is %c.\n",alphabet);

উপরের প্রোগ্রামটি রান করলে, প্রোগ্রামটি তোমার ইনপুট নেবার জন্য অপেক্ষা করবে | তুমি যদি ইনপুট দেও D তাহলে আউটপুট পাবো

The alphabet is D.

একইভাবে, আমরা দশমিক নম্বর ইনপুট নিতে পারি


double pi;
scanf('%lf",&pi);
printf("Value of pi is %lf.\n",pi);

উপরের প্রোগ্রামটি রান (run) করার পর তুমি যদি pi ভ্যারিয়েবল এর জন্য ইনপুট দেও 3.14 তাহলে আমরা আউটপুট পাবো

Value of pi is 3.140000.

স্ট্রিং ভারিয়াবলে ইনপুট নেয়া ইনপুট, স্ট্রিং


char myName[20] = "XYZ";
printf("My name is %s.\n",myName);

উপরের প্রোগ্রামটি তোমার নাম প্রিন্ট করবে যা কিনা একটি ভ্যারিয়েবল এ সেভ করা ছিলো | কিনতু যদি তুমি তোমার নাম আগে থেকে প্রোগ্রাম এ লিখে না রেখে ইনপুট নিতে চাও তাহলে আমরা টা স্ট্রিং হিসাবে ইনপুট নিতে পারি | যেমন


char myName[20];
scanf("%s",&myName);
printf("My name is %s.\n",myName);

উপরের প্রোগ্রামটি রান করলে, প্রোগ্রামটি তোমার কাছে ইনপুট নেয়ার জন্য অপেক্ষা করবে | তুমি যদি ইনপুট দেও Celica তাহলে প্রোগ্রামটি আউটপুট দিবে

My name is Celica.

আমরা আগেই জেনেছি যে স্ট্রিং ডাটা টাইপের ভ্যারিয়েবল প্রিন্ট করতে আমরা "%s" specifier ব্যবহার করি | একইভাবে স্ট্রিং ডাটা টাইপের ভ্যারিয়েবল এ ইনপুট নিতে হলে আমরা "%s" specifier ব্যবহার করবো|

long long I/O টিউটোরিয়াল I/O

long long I/O নিম্নলিখিত উপায়ে সমাধান করতে হবেঃ


#include <stdio.h>
int main(){
    long long x;
    scanf("%lld",&x);
    printf("%lld\n", x);
    return 0;
}
H2>ইনপুট/আউটপুট এর সম্পর্কে ধারণা ১ ইনপুট/আউটপুট

ইনপুট বলতে কোন একটি প্রোগ্রামে ডেটা ফিড করানোকে বোঝানো হয়। ইনপুট একটি ফাইল অথবা কমান্ড লাইনের মাধ্যমে দেয়া যায়।

আউটপুট বলতে একটি প্রোগ্রাম থেকে ফাইল, প্রিন্টার, অথবা স্ক্রিনে ডেটা দেখানোকে বোঝানো হয়। সি তে কিছু বিল্টইন ফাংশন আছে যা দ্বারা এই কাজ সম্পন্ন করা যায়।

ইনপুট/আউটপুট এর সম্পর্কে ধারণা ২ ইনপুট/আউটপুট

ইনপুট আউটপুট এর ক্ষেত্রে সি প্রোগ্রাম সব কিছুকেই ফাইল হিসেবে ধরে নেয়। অতএব কিবোর্ড, মাউস, স্ক্রিন সবকিছুই সি প্রোগ্রামের কাছে একটি ফাইলের সমতুল্য।


Standard ফাইল ফাইল পয়েন্টার পয়েন্টারডিভাইস
Standard input  stdin কিবোর্ড
Standard output stdout  স্ক্রিন
Standard error  stderr  স্ক্রিন
 

int I/O টিউটোরিয়াল I/O

int I/O নিম্নলিখিত উপায়ে সমাধান করতে হবেঃ


#include <stdio.h>
int main(){
    int x;
    scanf("%d",&x);
    printf("%d\n", x);
    return 0;
}

float I/O টিউটোরিয়াল I/O

float I/O নিম্নলিখিত উপায়ে সমাধান করতে হবেঃ


#include <stdio.h>
int main(){
    float x;
    scanf("%f",&x);
    printf("%.5f\n", x);
    return 0;
}

double I/O টিউটোরিয়াল I/O

double I/O নিম্নলিখিত উপায়ে সমাধান করতে হবেঃ


#include <stdio.h>
int main(){
    double x;
    scanf("%lf",&x);
    printf("%.5lf\n", x);
    return 0;
}

ইনপুট আউটপুট নিয়ে কাজ ১ ইনপুট, আউটপুট

এখন আমরা যোগ করার প্রোগ্রামটি লিখব যেটি সব বাস্তব সংখ্যা (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;  
 }

কোডল্যাবে ইনপুট দিতে হলে ইনপুট দেবার ঘরে আপনি সংখ্যা দুটো space দিয়ে অথবা দুই লাইনে লিখতে পারেন। এরপর রান করলে আউটপুটে যোগফল দেখতে পাবেন।

scanf("%d", &a); এখানে ডবল কোটেশনের ভেতরে %d দিয়ে scanf-কে বলে দেওয়া হচ্ছে যে একটি ইন্টিজার বা int টাইপের ভেরিয়েবলের মান পড়তে হবে (ব্যবহারকারী কিবোর্ড থেকে ইনপুট দেবে)। আর দেখুন a-এর আগে এমপারসেন্ড (&) চিহ্ন ব্যবহার করা হয়েছে, &a দিয়ে বোঝানো হয়েছে যে সংখ্যাটি ইনপুট দেওয়া হবে সেটি a ভেরিয়েবলের মাঝে অ্যাসাইন হবে। আপনি যখন সি আরেকটু ভালোভাবে শিখবেন, তখন &a-এর প্রকৃত অর্থ বুঝতে পারবে, আপাতত আমরা ব্যবহারের দিকেই মনোযোগ দিই। a এবং b-এর মান একটি scanf ফাংশন দিয়েও নেওয়া যেত এভাবে: scanf("%d %d", &a, &b);

এখন আমরা যদি ইনপুট হিসেবে ইন্টিজার না নিয়ে ডবল টাইপের ডাটা নিতে চাইতাম তাহলে scanf-এ %d-এর বদলে %lf ব্যবহার করলেই চলত।

ইনপুট আউটপুট নিয়ে কাজ ৩ ইনপুট, আউটপুট

এবারে আমরা আরেক ধরনের ডাটা টাইপের ইনপুট আউটপুট দেখব, সেটি হচ্ছে 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';

ফাইল ইনপুট/আউটপুট ১৯ ফাইল ইনপুট/আউটপুট

ফাইলে একই সাথে পড়া এবং লিখা

একই সাথে ফাইল এ পরতে এবং লিখতে r+ mode ব্যবহার করা যায়।

নিচের উদাহরনটি খেয়াল করুন,


#include <stdio.h>

int main()
{
    char ch;
    char str[100];

    FILE *fp;

    fp = fopen("input.txt", "r+"); /* r+ = ফাইলটি একই সাথে পড়া এবং লিখার জন্য খুলবে  */

    /*  ফাইলের প্রতিটি  character পরবে এবং আউটপুট দিবে  */
    do
    {
        ch = fgetc(fp);
        if(ch!=EOF) putchar(ch);
    }
    while(ch!=EOF);

    puts(""); /* পরের লাইন এ চলে যাবে */

    gets(str); /* string ইনপুট নিবে  */

    fputs(str,fp); /* string টি ফাইল এ রাখবে */

    fclose(fp);

    return 0;
}

জন্য বিশেষ ক্যারেক্টার সমূহ) আউটপুট, এস্কেপ ক্যারেক্টার

আমরা অনেক সময় এমন কিছু character বা sequence of character ব্যবহার করি যা আসলে অনেকটা কমান্ড হিসাবে কাজ করে এবং তার আউটপুট হিসাবে আমরা অন্য কিছু পেয়ে থাকি | যেমন ধরো তুমি একটি প্রোগ্রামের মাধ্যমে ২ টি লাইন Hello World এবং Hello Bangladesh লিখতে চাচ্ছো| তাহলে printf ফাংশনে কে বলে দিতে হবে যে Hello World প্রিন্ট করার পর সে যেন নতুন একটি লাইন এ চলে যায় এবং Hello Bangladesh প্রিন্ট করে | এই নতুন লাইনে চলে যাওয়া বা নতুন লাইন প্রিন্ট করতে হবে newline নামক একটি escape character দিয়ে যা প্রকাশ করা হয় \n দিয়ে | যেমন

printf("Hello World \nHello Bangladesh");

এই প্রোগ্রামটির আউটপুট হিসাবে আমরা পাবো


Hello World
Hello Bangladesh

আমরা আমাদের বাঘ এবং হরিনের উধাহরণটি যদি আরেকবার দেখি:


int numberOfTiger = 4;
int numberOfDeer = 10;

আমরা যদি বাঘ এবং হরিনের সংখ্যা ২ টি আলাদা লাইনে দেখতে চাই তাহলে লিখব

printf("Number of Tiger = %d \nNumber of Deer = %d\n", numberOfTiger, numberOfDeer);

এই প্রোগ্রামটির আউটপুট হিসাবে আমরা দেখতে পাবো


Number of Tiger = 4
Number of Deer = 10

আরো কিছু গুরুত্ত্বপূর্ণ escape character আমরা যদি দেখি তাহলে \t, \\, \’, \” এর কথা বলতে হবে |

আমরা যদি কখনো horizontal tab প্রিন্ট করতে চাই তাহলে আমরা printf এর মধ্যে \t ব্যবহার করবো |যেমন :

printf("Hello\tWorld");

প্রোগ্রামটির আউটপুট পাবো

Hello World

আমরা সাধারণত single qoute (‘) দিয়ে character এবং double qoute (") দিয়ে স্ট্রিং প্রকাশ বা স্টোর করি | printf এর ভিতর ও আমরা double qoute এর মধ্যে যা লেখি টা প্রিন্ট হয় | তাই single অথবা double qoute প্রিন্ট করতে হলে আমাদের \’ এবং \" ব্যবহার করতে হবে | যেমন

printf("He always says that, \"don\'t lie\".");

প্রোগ্রামটির আউটপুট হবে

He always says that, "don't lie".

একইভাবে আমরা escape character প্রিন্ট করার জন্য \ কে ব্যবহার করি | তাই \ সরাসরি প্রিন্ট করা যাবে না, তোমাকে \ এর সামনে আরেকটি \ মানে \\ ব্যবহার করতে হবে | যেমন

printf("C:\\Users\\My Document\\a.txt");

প্রোগ্রামটির আউটপুট হবে

C:\Users\My Document\a.txt

অপারেটর এর ধারনা অপারেটর

আমরা ইতোমধ্যেই দেখেছি যে কন্সটান্ট, ভ্যারিয়েবল, এরে এলিমেন্টস এবং ফাংশন রেফারেন্সসমূহ বিভিন্ন অপারেটর এর সাহায্যে একত্রিত করে এক্সপ্রেশন তৈরি করা হয়। সি তে যেসকল অপারেটর রয়েছে তাদেরকে বেশ কয়েক ভাগ্যে ভাগ করা যায়। যেমন এরিথমেটিক অপারেটর, ইউনারি অপারেটর, রিলেশনাল ও লজিক্যাল অপারেটর, এসাইনমেন্ট অপারেটর, কন্ডিশনাল অপারেটর ইত্যাদি। যে সকল ডাটা আইটেম এর উপর অপারেটর সমূহ কাজ করে, তাদের বলা হয় অপারেন্ড।

এরিথমেটিক অপারেটর ১ অপারেটর

সি তে ৫ টি এরিথমেটিক অপারেটর রয়েছে,এগুলো হলঃ


+ (যোগ) 
- (বিয়োগ) 
* (গুন) 
/ (ভাগ) 
% (ইন্টেজার ভাগ্যের পর ভাগশেষ)

% অপারেটরকে অনেক ক্ষেত্রে মডিউলাস অপারেটর ও বলা হয়। সি তে কোন এক্সপনেনশিয়াল অপারেটর নেই, কিন্তু এক্সপনেনশিয়াল অপারেশন করতে pow নামে একটি লাইব্রেরি ফাংশন রয়েছে। এরিথমেটিক অপারেটরগুলোর অপারেন্ডগুলো অবশ্যই সংখ্যা হতে হবে। সুতরাং অপারেন্ডগুলো ইন্টেজার বা ভগ্নাংশ সংখ্যা হতে হবে।

এরিথমেটিক অপারেটর ২ অপারেটর

অপারেন্ডগুলো ক্যারেক্টার টাইপ হলে সমস্যা নেই যেহেতু ক্যারেক্টার আসলে ইন্টেজার সংখ্যা দিয়েই প্রকাশ করা হয়। উদাহরণ হিসেবে বলা যায়, একটি ক্যারেক্টার এর সাথে যদি ১ যোগ করা হয়, তাহলে তা আসলে ঐ ক্যারেক্টার এর সাংখ্যিক মানের সাথে ১ যোগ করলে যে ক্যারেক্টারের মান দ্বারায় সেই ক্যারেক্টার বোঝানোর সামিল। যেমন A + 1 এর মান হবে B.

আপনি যদি A থেকে Z পর্যন্ত স্ক্রিন এ প্রিন্ট করতে চান, তাহলে এভাবে সংখ্যার ব্যাবহার করে করতে পারেন। যেমন আপনি চাইলে A এর মান থেকে শুরু করে Z এর মান পর্যন্ত লুপ চালিয়ে প্রতিবার ক্যারেক্টার ভ্যারিয়েবলে এক যোগ করে প্রিন্ট করতে পারেন।

এরিথমেটিক অপারেটর ৩ অপারেটর

ভাগশেষ বা মডিউলাস অপারেটর এর অপারেন্ডগুলো ইন্টেজার হতে হবে এবং দ্বিতীয় অপারেন্ড অবশ্যই ০ হতে পারবেনা। যেমন একটি ভ্যারিয়েবল num এর মান যদি হয় তাহলে num%3 এর মান হবে । একই ভাবে একটি সংখ্যা জোড় কি বেজোড় তা বোঝা সম্ভব তাকে দিয়ে ভাগ করলে ভাগশেষ নাকি হয়।

এরিথমেটিক অপারেটর ৪ অপারেটর

ভাগ অপারেটর একটু ভিন্নভাবে কাজ করে। যেমন ০ দিয়ে ভাগ যেহেতু অনির্নেয়, তাই ০ দিয়ে ভাগ করলে আপনার প্রোগ্রাম রানটাইম এরর দেখাবে। এছাড়া আপনার অপারেন্ড দুটি যদি ইন্টেজার হয়, তাহলে ভাগফল সবসময় ইন্টেজার হবে। অর্থাৎ 3/2 এর মান 1.5 না হয়ে 1 হবে। একই ভাবে 11/3 এর মান 3 হবে। আপনি যদি এই ক্ষেত্রে ভগ্নাংশ মান চান, তাহলে অন্তত একটি অপারেন্ড ফ্লোটিং পয়েন্ট বা ডাবল টাইপ এর হতে হবে। যেমন 3/2.0 অথবা 3.0/2 অথবা 3.0/2.0 এর মান হবে 1.5. সুতরাং আপনি যদি দুটি ইন্টেজার ভ্যারিয়েবলের ভাগফল ভগ্নাংশ চান, তাহলে হয় যেকোন একটি ভ্যারিয়েবলকে float বা double এ কাস্ট করতে পারেন।

ইউনারী অপারেটর অপারেটর

ইউনারী অপারেটরগুলো একটিমাত্র অপারেন্ড এর উপর কাজ করে এবং সেই অপারেন্ড এর মানকে পরিবর্তন করে দেয়। সাধারণত ইউনারি অপারেটরগুলো অপারেন্ড এর পুর্বে বসে, যদি কিছু কিছু ক্ষেত্রে ইউনারি অপারেটর অপারেন্ড এর পরে বসে। যেমন কোন অপারেন্ড এর পুর্বে মাইনাস ( - ) সাইন একটি ইউনারি অপারেটর। এই অপারেটর একটি পজিটিভ সংখ্যাকে নেগেটিভ ও একটি নেগেটিভ সংখ্যাকে পজিটিভ করে দেয়। যেমনঃ -743, -0.2, - (x + y) ইত্যাদি।

আরও দুটি বহুল ব্যাবহৃত ইউনারি অপারেটর হল ইনক্রিমেন্ট ++ এবং ডিক্রিমেন্ট -- অপারেটর। ++ অপারেটর তার অপারেন্ড এর মান ১ বাড়িয়ে দেয় আর -- অপারেটর তার অপারেন্ড এর মান ১ কমিয়ে দেয়। যেমন একটি ভ্যারিয়েবল num এর মান যদি ১০ হয়, তাহলে num++ অথবা ++num করার পর তার ভ্যালু হবে ১১. একই ভাবে num-- অথবা --num করলে তার ভ্যালু দাঁড়াবে ৯। এক্ষেত্রে বলে নেয়া ভাল ++-- অপারেন্ড এর আগে ও পরে যেকোন স্থানেই বসানো যায়। তবে আগে আর পরে বসানোর মাঝে কিছুটা পার্থক্য রয়েছে। নিচের উদাহরণটি দেখলে ব্যাপারটি পরিষ্কার হবেঃ


#include <stdio.h>

int main() {
    int num1, num2, result1, result2;

    num1 = 1;
    num2 = 1;

    result1 = num1++;
    result2 = ++num2;

    printf("Result1 = %d, num1 = %d\n", result1, num1);
    printf("Result2 = %d, num2 = %d\n", result2, num2);

    return 0;
}

এই প্রোগ্রামটি রান করালে দেখা যাবে num1 এবং num2 দুইটি ভ্যারিয়েবলের মানই ১ করে বেড়েছে, কিন্তু result1 এবং result2 এই দুটির মান ভিন্ন। কারণ হল, num1++ আগে num এর ভ্যালু result1 এ এসাইন করে, তারপর num1 এর ভ্যালু বাড়ায়। আর ++num2 আগে num2 এর ভ্যালু বাড়ায় তারপরে তা result2 তে এসাইন করে।

বিটওয়াইজ অপারেটর অপারেটর, বিটওয়াইজ, বিট

যে সকল অপারেটর ব্যবহার করে বিট ম্যানিপুলেশন করা হয়, তাদের বিটওয়াইজ অপারেটর বলা হয়। সি তে ৬ ধরনের বিটওয়াইজ অপারেটর আছে -


  &   বিটওয়াইজ AND
  |   বিটওয়াইজ inclusive OR
  ^   বিটওয়াইজ XOR (eXclusive OR)
  <<    লেফট সিফট (left shift)
  >>    লেফট সিফট (right shift)
  ~   বিটওয়াইজ NOT (one's complement) (unary)

বিটওয়াইজ AND অপারেটর, AND, বিটওয়াইজ

সি তে বিটওয়াইজ AND অপারেটরকে একটি & দ্বারা প্রকাশ করা হয়। বিটওয়াইজ AND এর মাধ্যমে দুইটি সংখ্যার প্রতিটি বিট -এর লজিকাল AND বের করা হয়।


     01001000 & 
     10111000
     ---------------
     00001000

বিটওয়াইজ OR অপারেটর, বিটওয়াইজ, OR

সি তে বিটওয়াইজ OR অপারেটরকে একটি | দ্বারা প্রকাশ করা হয়। বিটওয়াইজ OR এর মাধ্যমে দুইটি সংখ্যার প্রতিটি বিট -এর লজিকাল ,OR বের করা হয়।

বিটওয়াইজ OR

 bit a   bit b   a | b (a OR b)
 0         0             0
 0         1             1
 1         0             1
 1         1             1
 

বিটওয়াইজ XOR অপারেটর, বিটওয়াইজ, XOR

সি তে বিটওয়াইজ XOR অপারেটরকে একটি ^ দ্বারা প্রকাশ করা হয়। বিটওয়াইজ XOR এর মাধ্যমে দুইটি সংখ্যার প্রতিটি বিট -এর লজিকাল XOR বের করা হয়।

বিটওয়াইজ XOR

 bit a   bit b   a ^ b (a XOR b)
 0         0          0
 0         1          1
 1         0          1
 1         1          0

বিটওয়াইজ NOT বিটওয়াইজ NOT

সি তে বিটওয়াইজ NOT অপারেটরকে একটি ~ দ্বারা প্রকাশ করা হয়। বিটওয়াইজ NOT এর মাধ্যমে দুইটি সংখ্যার প্রতিটি বিট -এর লজিকাল NOT বের করা হয়।


bit a ~a (complement of a)
    0      1
    1      0

বিটওয়াইজ রাইট সিফট বিটওয়াইজ রাইট সিফট

সি তে বিটওয়াইজ রাইট সিফট অপারেটরকে একটি >> দ্বারা প্রকাশ করা হয়। বিটওয়াইজ রাইট সিফট এর মাধ্যমে একটি সংখ্যার লজিকাল রাইট সিফট বের করা হয়।


 int i = 4; /*  100 -> 4*/
 int j = i >> 1; /* 10 -> 2 */

লজিকাল অপারেটর অপারেটর, লজিকাল

সি তে বিটওয়াইজ অপারেটর এর অনুরূপ লজিকাল অপারেটর ৪টি ।


Bitwise Logical
a & b a && b
a | b a || b
a ^ b a != b
~a  !a

টার্নারি অপারেটর - ১ অপারেটর, টার্নারি

টার্নারি (?) অপারেটর ব্যবহার করে সহজে কনডিশনাল স্টেটমেন্ট লেখা যায়। টার্নারি অপারেটরে ৩ টি অংশ থাকে প্রথমে থাকে condition তারপর true block তারপর থাকে false block. টার্নারি অপারেটরে বেসিক স্ট্রাকচার নিম্নের মতঃ

condition ? True_Block : False_Block

টার্নারি অপারেটর - ২ অপারেটর, টার্নারি

এই পাঠে আমরা প্রথমে দেখব if else ব্যবহার করে একটি নাম্বার জোড় নাকি বিজোড় তার কোড। তারপর দেখব সেই কাজটি কিভাবে টার্নারি অপারেটর ব্যবহার করে করা যায়।


#include <stdio.h>
int main()
{
    bool yes = true | false ;
    if(yes)
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}
টার্নারি অপারেটর দিয়ে এই কাজটি এক লাইনে করে ফেলা যায়।

#include <stdio.h>
int main(){
    bool yes = true | false ;
    printf("%s\n",yes ? "Yes" : "No"); 
    return 0; 
} 

রিলেশনাল অপারেটর অপারেটর, রিলেশনাল অপারেটর

যে সকল অপারেটর দ্বারা দুইটি ডেটা এর মধ্যে তুলনা করা হয় তাদেরকে রিলেশনাল অপারেটর বলা হয়ে থাকে। যেমন, <, >, == ইত্যাদি। সি তে মোট ৬টি রিলেশনাল অপারেটর আছে। তারা হলঃ

== != > < >= <=

লেস দেন অপারেটর অপারেটর, রিলেশনাল অপারেটর, লেস দেন

দুটি সংখ্যার মধ্যে ছোট সংখ্যাটি বের করার জন্য লেস দেন অপারেটর ব্যবহার করা হয়ে থাকে। একে < দ্বারা চিহ্নিত করা হয়। সি তে তা নিম্নরূপে ব্যবহার করা হয়ঃ


int a = 10;
int b = 199;
int small ;

if(a < b){
    small = a ;
}else{
    small = b ;
}

গ্রেটার দেন অপারেটর অপারেটর, গ্রেটার দেন

দুটি সংখ্যার মধ্যে বড় সংখ্যাটি বের করার জন্য গ্রেটার দেন অপারেটর ব্যবহার করা হয়ে থাকে। একে > দ্বারা চিহ্নিত করা হয়। সি তে তা নিম্নরূপে ব্যবহার করা হয়ঃ


int a = 10;
int b = 199;
int big ;

if(a > b){
    big = a ;
}else{
    big = b ;
}

লেস দেন ইকুয়াল অপারেটর অপারেটর, লেস দেন ইকুয়াল

দুটি সংখ্যার মধ্যে ছোট বা সমান সংখ্যাটি বের করার জন্য লেস দেন ইকুয়াল অপারেটর ব্যবহার করা হয়ে থাকে। একে <= দ্বারা চিহ্নিত করা হয়। সি তে তা নিম্নরূপে ব্যবহার করা হয়ঃ


int a = 10;
int b = 199;
int res ;

if(a <= b){
    res = a ;
}else{
    res = b ;
}

গ্রেটার দেন ইকুয়াল অপারেটর অপারেটর, গ্রেটার দেন ইকুয়াল

দুটি সংখ্যার মধ্যে বড় বা সমান সংখ্যাটি বের করার জন্য গ্রেটার দেন ইকুয়াল অপারেটর ব্যবহার করা হয়ে থাকে। একে >= দ্বারা চিহ্নিত করা হয়। সি তে তা নিম্নরূপে ব্যবহার করা হয়ঃ


int a = 10;
int b = 199;
int res ;

if(a >= b){
    res = a ;
}else{
    res = b ;
}

আনইকুয়াল অপারেটর অপারেটর, আনইকুয়াল অপারেটর

দুটি সংখ্যা সমান নয় কিনা তা বের করার জন্য আনইকুয়াল অপারেটর ব্যবহার করা হয়ে থাকে। একে != দ্বারা চিহ্নিত করা হয়। সি তে তা নিম্নরূপে ব্যবহার করা হয়ঃ


int a = 2;
int b = 4;
int res ;

if(a != b){
    puts("YES THEY ARE NOT EQUAL");
}

যোগ টিউটোরিয়াল অপারেটর


#include <stdio.h>
int main(){
    int a , b ;

    while(scanf(" %d %d", &a , &b) == 2){
        printf("%d\n" , a+b);
    }

    return 0 ;
}

ASCII Print টিউটোরিয়াল ASCII, অপারেটর

#include <stdio.h> int main(){ char ch ; for(ch = 'A' ; ch <= 'Z' ; ch++){ printf("%c", ch); } return 0 ; }

০ থেকে ১০০ পর্যন্ত বেজোড় সংখ্যা টিউটোরিয়াল operator


#include <stdio.h>
int main(){
    int i ;

    for(i = 0 ; i <= 100 ; i++){
        if(i % 2 == 1)
            printf("%d\n" , i);
    }

    return 0 ;
}