সি প্রোগ্রামিং পয়েন্টার - C Programming Pointer
সি প্রোগ্রামিং পয়েন্টার
সি এবং সি++ প্রোগ্রামিং এর শক্তিশালী বৈশিষ্ট্য হলো পয়েন্টার(Pointer) যার মাধ্যমে ইহা অন্যান্য জনপ্রিয় প্রোগ্রামিং ল্যাঙ্গুয়েজ যেমন- পাইথন এবং জাভা থেকে বেশী প্রাধান্য পায়।
মেমোরি এক্সেস(access) করার জন্য এবং মেমোরি এড্রেস নিপুণভাবে পরিচালনা করার জন্য সি প্রোগ্রামিং এ পয়েন্টার ব্যবহৃত হয়।
সি মেমোরি এড্রেস
পয়েন্টারের ধারণা নেওয়ার পূর্বে চলুন সি প্রোগ্রামিং এড্রেসের সাথে পরিচিত হয়ে নিই।
আপনার প্রোগ্রামে যদি count একটি ভ্যারিয়েবল থাকে তাহলে &count
আপনাকে মেমোরির এড্রেস দিবে। এখানে &
কে রেফারেন্স অপারেটর বলা হয়।
আপনি যখন scanf()
ফাংশন ব্যবহার করবেন তখন অবশ্যই এই প্রতীকটি দেখবেন। ইউজার কর্তৃক ইনপুট ভ্যালু ভারিয়েবলের এড্রেসে জমা(store) করার জন্য ইহা ব্যবহৃত হয়।
scanf("%d",&count);
/*সি প্রোগ্রামিং এ রেফারেন্স অপারেটর ভালভাবে বুঝার জন্য এই প্রোগ্রাম। */
#include <stdio.h>
int main(){
int count=5;
printf("Value: %d\n",count);
printf("Address: %u",&count); // লক্ষ্য করলে দেখবেন যে, count ভ্যারিয়েবলের পূর্বে ampersand(&) ব্যবহার করা হয়েছে।
return 0;
}
আউটপুট
Value: 5 Address: 2686778
নোটঃ এই একই কোড ব্যবহার করে আপনি এড্রেসের বিভিন্ন ভ্যালু পেতে পারেন।
উপরের সোর্স কোডে ভ্যালু 5 মেমোরির 2686778 লোকেশনে জমা হয়। count শুধুমাত্র সেই লোকেশন(location) এর নাম।
সি Pointer ভ্যারিয়েবল
সি প্রোগ্রামিং এ এক ধরণের বিশেষ ভ্যারিয়েবল রয়েছে যা অন্য ভ্যারিয়েবলের এড্রেস জমা(store) রাখে। ইহাকে পয়েন্টার ভ্যারিয়েবল বা শুধু পয়েন্টার বলা হয়।
Pointer ডিক্লেয়ারেশন
data_type* pointer_variable_name; int* p;
উপরের স্টেটমেন্টে p কে int
টাইপের পয়েন্টার ভ্যারিয়েবল হিসাবে ডিক্লেয়ার(declare) করা হয়েছে।
সি রেফারেন্স(&) এবং ডিরেফারেন্স(*) অপারেটর
ইতোপূর্বেই বর্ণনা করা হয়েছে যে, & কে রেফারেন্স(reference) অপারেটর বলা হয়। ইহার মাধ্যমে আপনি ভ্যারিয়েবলের এড্রেস পাবেন।
অনুরূপভাবে, অন্য একটি অপারেটর রয়েছে যার মাধ্যমে আপনি এড্রেস থেকে ভ্যালু পেতে পারেন। ইহাকে ডিরেফারেন্স(*) অপারেটর বলা হয়।
নিচের উদাহরণে পয়েন্টার, রেফারেন্স(reference) অপারেটর এবং ডিরেফারেন্স(dereference) অপারেটরের ব্যবহার স্পষ্টভাবে ব্যাখ্যা করা হয়েছে।
নোটঃ: পয়েন্টার ডিক্লেয়ারেশন(declaration) এ ব্যবহৃত *
চিহ্ন ডিরেফারেন্স অপারেটর নয়। ইহা পয়েন্টার নির্দেশের জন্য শুধুমাত্র একটি প্রতীক।
উদাহরনঃ পয়েন্টারের ব্যবহার শেখার জন্য সি প্রোগ্রাম
#include <stdio.h>
int main(){
int* pc;
int c;
c=22;
printf("Address of c:%u\n",&c);
printf("Value of c:%d\n\n",c);
pc=&c;
printf("Address of pointer pc:%u\n",pc);
printf("Content of pointer pc:%d\n\n",*pc);
c=11;
printf("Address of pointer pc:%u\n",pc);
printf("Content of pointer pc:%d\n\n",*pc);
*pc=2;
printf("Address of c:%u\n",&c);
printf("Value of c:%d\n\n",c);
return 0;
}
আউটপুট
Address of c: 2686784 Value of c: 22 Address of pointer pc: 2686784 Content of pointer pc: 22 Address of pointer pc: 2686784 Content of pointer pc: 11 Address of c: 2686784 Value of c: 2
উপরের প্রোগ্রাম এবং চিত্রের ব্যাখ্যা
int* pc;
পয়েন্টার ভ্যারিয়েবল pc তৈরি করে এবংint c;
সাধারণ ভ্যারিয়েবল c তৈরি করে।
যেহেতু pc এবং c উভয়কেই ইনিশিয়ালাইজ(initialized) করা হয়নি, সুতরাং পয়েন্টার pc এড্রেস বা র্যান্ডম(random) এড্রেস কোনো কিছুকেই নির্দেশ করে না। একইভাবে ভ্যারিয়েবল c এর এড্রেস এসাইন(assigned) করা হয়ছে কিন্তু ইহা random/garbage ভ্যালু ধারণ করে।c=22;
ভ্যারিয়েবল c এ 22 এসাইন(assign) করে অর্থাৎ 22 ভ্যারিয়েবল c এর মেমোরি লোকেশনে জমা(store) করে।
মনে রাখবেন, c(ভ্যারিয়েবল) এর এড্রেস(&c
) প্রিন্ট করার সময় আমরা%d
এর পরিবর্তে%u
ব্যবহার করবো যেহেতু এড্রেস সবসময় ধনাত্মক(unsigned integer) হয়।pc=&c;
ভ্যারিয়েবল c এর এড্রেসকে পয়েন্টার pc তে এসাইন করে।
যখন প্রিন্ট করা হয় তখন দেখবেন পয়েন্টার pc এর এড্রেস এবং c এর এড্রেস একই হবে। এছাড়া পয়েন্টার pc এর কন্টেটও একই(22) হবে।c=11;
ভ্যারিয়েবল c এ 11 এসাইন করে।
আমরা ভ্যারিয়েবল c এ নতুন ভ্যালু এসাইন করলাম যা পয়েন্টার pc কে প্রভাবিত করে।- যেহেতু পয়েন্টার pc এবং c একই এড্রেসকে নির্দেশ করে, সুতরাং পয়েন্টার pc একই ভ্যালু 11 কেই রেফার করে।
pc এর এড্রেস এবং কন্টেন্ট প্রিন্ট করলে আপডেট ভ্যালু 11 প্রদর্শিত হয়। *pc=2;
পয়েন্টার pc দ্বারা নির্দেশিত মেমোরি লোকেশনের পূর্বের কন্টেন্ট পরিবর্তন করে 2 এসাইন করে।
যেহেতু পয়েন্টার pc এবং ভ্যারিয়েবল c একই এড্রেসকে নির্দেশ করে সুতরাং c এর ভ্যালু পরিবর্তন হয়ে 2 হয়।
পয়েন্টার ব্যাবহারের সময় সাধারণ ভুলসমূহ
ধরুন, আপনি পয়েন্টার pc কে c এর এড্রেসে পয়েন্ট/নির্দেশ করতে চাচ্ছেন। তাহলে
int c, *pc; pc=c; /* ভুল! যেখানে pc হলো এড্রেস অথচ c এড্রেস নয়। */ *pc=&c; /* ভুল! যেখানে *pc হলো এড্রেসের নির্দেশকৃত ভ্যালু অথচ &c হলো এড্রেস। */ pc=&c; /* Correct! যেহেতু pc এবং &c উভয়ই এড্রেস। */ *pc=c; /* সঠিক! যেহেতু *pc হলো এড্রেসের নির্দেশকৃত ভ্যালু এবং c ও ভ্যালু। */
উভয় ক্ষেত্রেই পয়েন্টার pc, c এর এড্রেসকে নির্দেশ করে না।