অপারেটর এবং এক্সপ্রেশন (Operators & Expressions)
সি-এর আপগ্রেড করা টুলবক্স (C's Toolbox, Upgraded)
যদি সি (C) আপনাকে হাতুড়ি, স্ক্রুড্রাইভার এবং রেঞ্চের মতো বিভিন্ন শক্তিশালী টুলবক্স (toolbox) দিয়ে থাকে, তবে সি++ (C++) মূলত ওই একই টুলবক্সের ভেতর একটি পাওয়ার ড্রিল, একটি লেজার লেভেল এবং একটি লেবেল মেকারকে যুক্ত (added) করে দিয়েছে। সি (C) প্রোগ্রামিং থেকে আপনি যত অপারেটরের কাজ জানেন, সি++ (C++)-এ তার সবকিছুই ঠিক একইভাবেই (exactly the same) কাজ করে। তবে সি++ (C++) এটিকে আরও বেশি এক্সপ্রেসিভ বা পরিষ্কার (expressive) করে তুলতে এতে আরও নতুন (new) কিছু অপারেটর যুক্ত করেছে।
চলুন পরিচিত কিছু অপারেটরগুলোর (familiar operators) মাধ্যমেই শুরু করা যাক, এবং এরপর আমরা এর নতুন অপারেটরগুলো (newcomers) সম্পর্কে জানব।
পরিচিত অপারেটরগুলো (The Familiar Operators)
সি-এর (C) সকল অপারেটরগুলোই এখানে অপরিবর্তিত (unchanged) অবস্থায় রয়েছে:
- অ্যারিথমেটিক বা গাণিতিক (Arithmetic):
+,-,*,/,%(ভাগশেষ বা modulo) - কম্পারিজন বা তুলনামূলক (Comparison):
==,!=,<,>,<=,>= - লজিক্যাল বা যৌক্তিক (Logical):
&&(অ্যান্ড বা AND),||(অর বা OR),!(নট বা NOT) - বিটওয়াইজ (Bitwise):
&,|,^,~,<<,>> - অ্যাসাইনমেন্ট (Assignment):
=,+=,-=,*=,/=,%=,&=,|=,^= - ইনক্রিমেন্ট/ডিক্রিমেন্ট (Increment/Decrement):
++,--(প্রিফিক্স বা prefix এবং পোস্টফিক্স বা postfix) - টার্নারি (Ternary):
condition ? valueIfTrue : valueIfFalse
এগুলো মূলত সি-এর (C) মতোই একইভাবে (identically) কাজ করে। তাই এখানে অবাক (surprises) হওয়ার মতো কিছুই নেই।
সি++ এর পরিচিত অপারেটরগুলো (Familiar Operators in C++)
নতুন সদস্য: স্কোপ রেজোলিউশন (Scope Resolution বা ::)
এই :: অপারেটরটি হলো মূলত সি++ (C++)-এর "আমি ঠিক এটিকে (this specific) বোঝাতে চেয়েছি" বলার একটি দারুণ উপায়। এটি মূলত বিভিন্ন নামের মধ্যে থাকা অ্যাম্বিগুইটি বা অস্পষ্টতা (ambiguity) দূর করতে সাহায্য করে — অনেকটা কোনো একটি ঘরে "অ্যালেক্স" নামের দুজন ব্যক্তি থাকলে, তাদের মধ্যে "অ্যাকাউন্টিংয়ের অ্যালেক্স" এবং "ইঞ্জিনিয়ারিংয়ের অ্যালেক্স"-কে আলাদা করে চিহ্নিত করার মতো।
আপনি মূলত এই ::-টিকে সব জায়গাতেই দেখতে পাবেন: যেমন বিভিন্ন নেমস্পেস মেম্বারে (namespace members) (যেমন std::cout) অ্যাক্সেস (accessing) করার ক্ষেত্রে, ক্লাসের বাইরে তার বিভিন্ন মেথড (class methods) ডিফাইন বা সংজ্ঞায়িত করার ক্ষেত্রে, এবং বিভিন্ন লোকাল ভ্যারিয়েবলের (local variables) আড়ালে লুকিয়ে থাকা গ্লোবাল ভ্যারিয়েবলগুলোতে (global variables) পৌঁছানোর (reaching) ক্ষেত্রে।
স্কোপ রেজোলিউশন অপারেটর বা Scope Resolution Operator (::)
স্ট্রিম অপারেটর: << এবং >> (Stream Operators: << and >>)
সি++ (C++)-এর অন্যতম একটি সেরা কাজ মূলত এখানেই রয়েছে। সি (C) প্রোগ্রামিংয়ে এই << এবং >> মূলত বিটওয়াইজ শিফট অপারেটরগুলো (bitwise shift operators) হিসেবে কাজ করে — এগুলো মূলত বিভিন্ন বিটকে (bits) ডানে (right) বা বামে (left) সরিয়ে (shift) দেয়। সি++ (C++) তার ইন্টিজারের (integers) জন্য এর এই ধর্মটিকে বা ব্যবহারটিকে বজায় রাখলেও, বিভিন্ন আই/ও (I/O) স্ট্রিমগুলোর জন্য সে এটিকে ওভারলোড (overloads) করেছে।
এক্ষেত্রে আপনি <<-টিকে "স্ট্রিমে ডেটা পুশ (push) করা" হিসেবে (যেমন স্ক্রিনের দিকে যাওয়া কোনো কনভেয়র বেল্টের ওপরে আইটেমগুলো রাখা) এবং >>-টিকে "স্ট্রিম থেকে ডেটা তুলে (pull) আনা" হিসেবে (যেমন কিবোর্ড থেকে আসা কোনো বেল্ট থেকে আইটেমগুলো তুলে নেয়া) কল্পনা করতে পারেন।
cout << চেইনিং (Chaining) — বেল্টের ওপরে আইটেমগুলো (Items) রাখা
<< এবং >> হলো বিটওয়াইজ শিফট (bitwise shift) অপারেটর, কিন্তু সি++ (C++)-এ এগুলোকে স্ট্রিমের জন্য মূলত আই/ও-তে ওভারলোড (overloaded for I/O) করা হয়েছে। এক্ষেত্রে কন্টেক্সটের (Context) ভূমিকা বেশ গুরুত্বপূর্ণ! এগুলোকে মূলত যখন cout/cin-এর সাহায্যে ব্যবহার করা হয়, তখন এগুলো স্ট্রিম অপারেটর (stream operators) হিসেবে কাজ করে। এবং যখন এগুলোকে বিভিন্ন ইন্টিজারের (integers) সাথে ব্যবহার করা হয়, তখন এগুলো বিটওয়াইজ শিফট (bitwise shift) হিসেবে কাজ করে। এখানকার অবজেক্টের বা অপারেন্ডের টাইপের (operand types) ওপর ভিত্তি করে মূলত এর কম্পাইলারটি (compiler) ঠিক করে যে কোনটির ক্ষেত্রে সে কোনটিকে ব্যবহার করবে।new এবং delete — সি++ স্টাইলের (C++ Style) ম্যানুয়াল মেমোরি
সি (C) প্রোগ্রামিং মূলত malloc() এবং free() নিয়ে কাজ করে। কিন্তু সি++ (C++) মূলত new এবং delete নিয়ে এসেছে — যেগুলো কোনো সাধারণ মেথডস বা ফাংশন নয়, এগুলো হলো এক ধরনের অপারেটর (operators), যা মেমোরি অ্যালোকেট (allocate) বা বরাদ্দ করতে পারে এবং এর কনস্ট্রাক্টর/ডেস্ট্রাক্টরগুলোকে কল (call) করতে পারে। এগুলো মূলত এর টাইপের দিক থেকে অত্যন্ত নিরাপদ (type-safe) এবং অনেক বেশি ক্লিন বা পরিষ্কার (cleaner)। তবে একটি আধুনিক সি++ (C++) মূলত new/delete দিয়ে বিভিন্ন র বা raw মেমোরি পরিচালনার চেয়ে স্মার্ট পয়েন্টারগুলোর (smart pointers) ব্যবহারটিকেই বেশি প্রাধান্য বা পছন্দ (prefers) করে।
new এবং delete
sizeof এবং typeid — বিভিন্ন টাইপ (Types) খুঁজে বের করা
এই sizeof মূলত একদম সি-এর (C) মতোই কাজ করে — এটি আপনাকে বাইট (bytes) হিসেবে কোনো কিছুর আকার বা সাইজটি (size) বলে দেয়। কিন্তু সি++ (C++)-এ এর সাথে আরও typeid (এটি <typeinfo> থেকে আসে) যুক্ত করা হয়েছে, যা মূলত আপনাকে রানটাইমে (runtime) যেকোনো একটি ভ্যারিয়েবলের (variable) আসল টাইপটিকে (actual type) পরিদর্শন করতে বা দেখতে (inspect) সাহায্য করে। এটি মূলত auto-এর ক্ষেত্রে বেশ দুর্দান্তভাবে (especially useful) কাজ করে — বিশেষত যখন আপনি নিশ্চিত হতে পারেন না যে কম্পাইলারটি আসলে ঠিক কোন টাইপটি (type) অনুমান (deduced) করেছে।
sizeof এবং typeid
দ্রষ্টব্য (Note): typeid().name()-এর আউটপুটটি (output) মূলত এর কম্পাইলারের ওপর নির্ভরশীল (compiler-dependent)। যদি আপনি জিসিসি (GCC) ব্যবহার করেন তবে এটি আপনাকে i (ইন্টিজার বা int), d (ডাবল বা double), c (ক্যারেক্টার বা char), b (বুলিয়ান বা bool)-এর মতো বিভিন্ন ছোট ছোট কোডগুলো (short codes) দেখাবে। আর যদি আপনি এমএসভিসি (MSVC) ব্যবহার করেন তবে এটি আপনাকে আরও সহজে পড়া যায় এমন বা পঠনযোগ্য (readable) নাম দেখাবে। তবে এর দুইটির আউটপুট নাম (names) আলাদা হলেও, তারা মূলত আপনাকে এটিই জানিয়ে দেয় যে এখানকার কম্পাইলারটি (compiler) আসলে ওই অবজেক্টের টাইপটিকে (type) ঠিক কী বলে চিন্তা (thinks) বা বিবেচনা করছে।