সি প্রোগ্রামিং লেকচার সিরিজ | ফাইল ০২
সি প্রোগ্রামিং ডেটা টাইপ (Data Types in C) |
১. ভূমিকা ও ডেটা টাইপ কী (Introduction & Definition)
সি প্রোগ্রামিং ভাষায় ভ্যারিয়েবল (Variable) ঘোষণার সময় উক্ত ভ্যারিয়েবলে কোন ধরণের তথ্য সংরক্ষণ করা হবে এবং সেই তথ্য মেমোরিতে (RAM) কতটুকু জায়গা দখল করবে, তা নির্ধারণ করার মাধ্যমই হলো ডেটা টাইপ (Data Type)। ডেটা টাইপের মাধ্যমে কম্পাইলার বুঝতে পারে কীভাবে সংশ্লিষ্ট ভ্যারিয়েবলের ডেটা প্রসেস এবং রিড করতে হবে।
ডেটা টাইপ ব্যবহারের মূল উদ্দেশ্যসমূহ নিচে আলোচনা করা হলো:
- ১. মেমোরি নির্ধারণ (Memory Allocation): কম্পাইলারকে নির্দিষ্ট করে জানিয়ে দেয় যে ভ্যারিয়েবলের জন্য ঠিক কত বাইট (Bytes) জায়গা বরাদ্দ করতে হবে।
- ২. ডেটার ব্যাখ্যাকরণ (Data Interpretation): একই বাইনারি মান (0 ও 1) টেক্সট ক্যারেক্টার নাকি গাণিতিক সংখ্যা হিসেবে পড়া হবে তা নির্ধারণ করে।
- ৩. টাইপ সেফটি ও ভ্যালিডেশন (Type Safety): ভুল প্রকৃতির ডেটা অ্যাসাইনমেন্ট রোধ করে প্রোগ্রামকে ত্রুটিমুক্ত রাখে।
- ৪. মেমোরি অপটিমাইজেশন (Resource Efficiency): ছোট মানের জন্য অতিরিক্ত মেমোরি অপচয় না করে সঠিক টাইপ নির্বাচন করতে সাহায্য করে।
📌 গুরুত্বপূর্ণ বৈশিষ্ট্য: সি একটি **Statically Typed Language**। এর অর্থ হলো সি প্রোগ্রামে কোনো ভ্যারিয়েবল ব্যবহার করার আগেই কম্পাইল-টাইমে (Compile-time) তার ডেটা টাইপ সুনির্দিষ্টভাবে ঘোষণা (Declare) করে দিতে হয়। রান-টাইমে ভ্যারিয়েবলের ডেটা টাইপ পরিবর্তন করা যায় না। |
২. সি-তে ডেটা টাইপের প্রধান শ্রেণিবিভাগ (Classification of C Data Types)
সি প্রোগ্রামিং ভাষার ডেটা টাইপসমূহকে তাদের গঠন ও বৈশিষ্ট্যের ওপর ভিত্তি করে প্রধানত ৪টি শ্রেণিতে ভাগ করা হয়:
- ১. প্রাইমারি বা বেসিক ডেটা টাইপ (Primary / Built-in Data Types): সি ভাষার নিজস্ব বিল্ট-ইন মৌলিক টাইপসমূহ (যেমন: char, int, float, double, void)।
- ২. ডিরাইভড ডেটা টাইপ (Derived Data Types): মৌলিক ডেটা টাইপসমূহ ব্যবহার করে তৈরি করা সম্প্রসারিত টাইপসমূহ (যেমন: Array, Pointer, Function)।
- ৩. ইউজার-ডিফাইন্ড ডেটা টাইপ (User-Defined Data Types): প্রোগ্রামার নিজের প্রয়োজন অনুযায়ী কাস্টম গঠন করেন (যেমন: struct, union, enum, typedef)।
- ৪. এম্পটি বা ভয়েড ডেটা টাইপ (Void / Empty Data Type): এটি কোনো নির্দিষ্ট মান বা ডেটার অনুপস্থিতি নির্দেশ করে (যেমন: void)।
৩. প্রাইমারি ডেটা টাইপসমূহের বিস্তারিত আলোচনা (Primary Data Types - Deep Dive)
প্রাইমারি ডেটা টাইপসমূহ হলো সি প্রোগ্রামিংয়ের মূল ভিত্তি। এগুলোকে ৪টি প্রধান ভাগে আলোচনা করা হলো:
৩.১ ইনটিজার টাইপ (Integer Type - int)
পূর্ণসংখ্যা (যেমন: ১০, -৪৫, ০) সংরক্ষণের জন্য `int` ডেটা টাইপ ব্যবহৃত হয়। এতে কোনো দশমিক অংশ থাকে না।
- • মেমোরি সাইজ: কম্পাইলার ও সিস্টেমে (16-bit, 32-bit বা 64-bit) আর্কিটেকচার ভেদে এটি সাধারণত ২ বাইট (16 bits) অথবা ৪ বাইট (32 bits) মেমোরি গ্রহণ করে।
- • ফরমেট স্পেসিফায়ার: printf বা scanf-এ পূর্ণসংখ্যা ইনপুট/আউটপুটের জন্য %d অথবা %i ব্যবহার করা হয়।
৩.২ ক্যারেক্টার টাইপ (Character Type - char)
একক কোনো বর্ণ, সংখ্যা বা বিশেষ চিহ্ন (যেমন: 'A', 'z', '5', '$') প্রকাশের জন্য `char` টাইপ ব্যবহার করা হয়।
- • মেমোরি সাইজ: সর্বদাই ১ বাইট (8 bits) মেমোরি স্থান দখল করে।
- • ASCII মান: সি-তে প্রতিটি ক্যারেক্টার অভ্যন্তরীণভাবে তার সমতুল্য ASCII (American Standard Code for Information Interchange) মান হিসেবে মেমোরিতে রক্ষিত হয়। যেমন: 'A' এর ASCII মান 65।
- • ফরমেট স্পেসিফায়ার: ক্যারেক্টার প্রদর্শনের জন্য %c ব্যবহৃত হয়।
৩.৩ ফ্লোটিং-পয়েন্ট টাইপ (Floating-point Type - float & double)
ভগ্নাংশ বা দশমিক যুক্ত সংখ্যা (যেমন: ৩.১৪১৬, -৯৯.৫) সংরক্ষণের জন্য এই টাইপসমূহ ব্যবহৃত হয়:
- • float (Single Precision): ৪ বাইট মেমোরি দখল করে। দশমিকের পর ৬ থেকে ৭ ঘর পর্যন্ত নিখুঁত মান প্রদান করতে পারে। ফরমেট স্পেসিফায়ার: %f।
- • double (Double Precision): ৮ বাইট মেমোরি দখল করে। এটি float-এর চেয়ে দ্বিগুণ নিখুঁত মান (দশমিকের পর ১৫ থেকে ১৬ ঘর) ধারণ করতে পারে। ফরমেট স্পেসিফায়ার: %lf।
- • long double (Extended Precision): সাধারণত ৮, ১২ বা ১৬ বাইট মেমোরি গ্রহণ করে (সিস্টেম ভেদে)। বৈজ্ঞানিক ও সূক্ষ্ম গাণিতিক হিসাবে ব্যবহার করা হয়। ফরমেট স্পেসিফায়ার: %Lf।
৩.৪ ভয়েড টাইপ (Void Type - void)
Void শব্দটির অর্থ খালি বা শূন্য। এটি কোনো নির্দিষ্ট মান নির্দেশ করে না। সি-তে এর প্রধান ৩টি প্রয়োগ রয়েছে:
- ১. ফাংশন রিটার্ন টাইপ না থাকলে (void return type): যখন কোনো ফাংশন কোনো মান রিটার্ন করে না (যেমন: void printMessage())।
- ২. ফাংশনের প্যারামিটার শূন্য হলে: যখন ফাংশন কোনো ইনপুট নেয় না (যেমন: int main(void))।
- ৩. Generic Pointer (void*): কোনো নির্দিষ্ট টাইপ ছাড়া কেবল মেমোরি অ্যাড্রেস ধারণ করার জন্য generic pointer তৈরি করতে।
৪. ডেটা টাইপ মডিফায়ার ও মাষ্টার টেবিল (Type Modifiers & Reference Table)
মডিফায়ার (Modifiers) হলো এমন কিছু কিওয়ার্ড যা মৌলিক ডেটা টাইপের পূর্বে যুক্ত হয়ে তার সাইজ এবং ডেটা সীমাকে পরিবর্তন বা অপটিমাইজ করে। সি ভাষার ৪টি প্রধান মডিফায়ার হলো:
- ১. signed: ধনাত্মক ও ঋণাত্মক উভয় মান ধারণ করে (এটি ডিফল্ট অবস্থায় থাকে)।
- ২. unsigned: কেবল ধনাত্মক সংখ্যা (এবং শূন্য) ধারণ করতে পারে। ঋণাত্মক মান না থাকায় ধনাত্মক মানসীমার পরিসর দ্বিগুণ হয়।
- ৩. short: মেমোরির পরিমাণ কমিয়ে আনে (সাধারণত ২ বাইট)।
- ৪. long: মেমোরির পরিমাণ এবং সীমার পরিসর বৃদ্ধি করে (সাধারণত ৪ বা ৮ বাইট)।
সি ডেটা টাইপসমূহের সম্পূর্ণ মাষ্টার সামারি টেবিল (32/64-bit System Standard)
ডেটা টাইপ (Data Type) | আকার (Size) | ফরমেট স্পেসিফায়ার | ধারণক্ষমতার সীমা (Range / Limit) | বিবরণ ও ব্যবহার |
|---|---|---|---|---|
char / signed char | 1 Byte | %c | -128 থেকে 127 | একক ASCII অক্ষর বা ছোট সংখ্যা |
unsigned char | 1 Byte | %c | 0 থেকে 255 | ধনাত্মক ছোট সংখ্যা / বাইট ডেটা |
short int / short | 2 Bytes | %hd | -32,768 থেকে 32,767 | স্বল্প পরিসরের পূর্ণসংখ্যা |
unsigned short int | 2 Bytes | %hu | 0 থেকে 65,535 | কেবল ধনাত্মক ছোট পূর্ণসংখ্যা |
int / signed int | 4 Bytes | %d / %i | -2,147,483,648 থেকে 2,147,483,647 | সাধারণ পূর্ণসংখ্যার মান |
unsigned int | 4 Bytes | %u | 0 থেকে 4,294,967,295 | কেবল ধনাত্মক পূর্ণসংখ্যা (যেমন: কাউন্টার) |
long int / long | 4 / 8 Bytes | %ld | -2^31 থেকে (2^31 - 1) | বড় পরিসরের পূর্ণসংখ্যা |
unsigned long int | 4 / 8 Bytes | %lu | 0 থেকে (2^32 - 1) | বড় ধনাত্মক পূর্ণসংখ্যা |
long long int | 8 Bytes | %lld | -2^63 থেকে (2^63 - 1) | অত্যন্ত বিশাল পূর্ণসংখ্যা |
unsigned long long | 8 Bytes | %llu | 0 থেকে (2^64 - 1) | সর্বোচ্চ ধনাত্মক পূর্ণসংখ্যা |
float | 4 Bytes | %f | 1.2E-38 থেকে 3.4E+38 (৬-৭ দশমিক স্থান) | সাধারণ দশমিক যুক্ত সংখ্যা |
double | 8 Bytes | %lf | 2.3E-308 থেকে 1.7E+308 (১৫-১৬ দশমিক) | উচ্চ নিখুঁত দশমিক সংখ্যা |
long double | 12/16 Bytes | %Lf | 3.4E-4932 থেকে 1.1E+4932 | সর্বোচ্চ নিখুঁত বৈজ্ঞানিক মান |
void | 0 Byte | N/A | কোনো মান নেই | রিটার্নলেস ফাংশন / জেনারেল পয়েন্টার |
৫. মেমোরি বিন্যাস ও sizeof অপারেটর (Memory Structure & sizeof Operator)
কম্পিউটারের র্যামে (RAM) ডেটা বাইনারি (0 এবং 1) আকারে সংরক্ষিত হয়। ১ বাইট (Byte) মানে হলো ৮টি বিট (Bits)।
উদাহরণস্বরূপ, একটি `signed char` যদি ১ বাইট হয়, তবে তার প্রথম বিটটি (Most Significant Bit - MSB) সাইন বিট (Sign bit: 0 = Positive, 1 = Negative) হিসেবে ব্যবহৃত হয় এবং বাকি ৭টি বিট মান নির্ধারণের জন্য ব্যবহৃত হয়।
sizeof অপারেটরের ব্যবহার
`sizeof` হলো সি ভাষার একটি বিল্ট-ইন কম্পাইল-টাইম (Compile-time) অপারেটর। এর সাহায্যে যেকোনো ভ্যারিয়েবল বা ডেটা টাইপের মেমোরি সাইজ (বাইটে) সহজে নির্ণয় করা যায়।
- • সিনট্যাক্স ১: sizeof(datatype) — উদাহরণ: sizeof(int)
- • সিনট্যাক্স ২: sizeof(variable) — উদাহরণ: sizeof(age)
এটি সাধারণত `%lu` (unsigned long) ফরমেট স্পেসিফায়ার দিয়ে প্রিন্ট করা হয়।
৬. ডিরাইভড ও ইউজার-ডিফাইন্ড ডেটা টাইপ (Derived & User-Defined Data Types)
মৌলিক ডেটা টাইপ ছাড়াও সি প্রোগ্রামিংয়ে জটিল ও বাস্তবসম্মত ডেটা স্ট্রাকচার তৈরির জন্য ডিরাইভড এবং ইউজার-ডিফাইন্ড টাইপসমূহ ব্যবহৃত হয়:
৬.১ ডিরাইভড ডেটা টাইপ (Derived Data Types)
- ১. Array (অ্যারে): একই ডেটা টাইপের একাধিক উপাদানের একটি ধারাবাহিক মেমোরি গুচ্ছ। যেমন: int marks[5]; (এখানে ৫টি int মানের জন্য সংলগ্ন মেমোরি স্থান তৈরি হবে)।
- ২. Pointer (পয়েন্টার): একটি বিশেষ ভ্যারিয়েবল যা অন্য কোনো ভ্যারিয়েবলের মান ধারণ করার বদলে তার মেমোরি অ্যাড্রেস (Address) সংরক্ষণ করে। যেমন: int *ptr;
- ৩. Function (ফাংশন): নির্দিষ্ট কিছু ডেটা টাইপ ইনপুট গ্রহণ করে কোনো নির্দিষ্ট টাইপের মান রিটার্ন করার সুনির্দিষ্ট কোড ব্লক।
৬.২ ইউজার-ডিফাইন্ড ডেটা টাইপ (User-Defined Data Types)
- ১. Structure (struct): ভিন্ন ভিন্ন টাইপের ডেটাকে একত্রে একটি লজিক্যাল গ্রুপ হিসেবে ধারণ করে। যেমন: struct Student { char name[20]; int roll; float gpa; };
- ২. Union (union): স্ট্রাকচারের মতোই, কিন্তু এর সকল মেম্বার একই মেমোরি লোকেশন শেয়ার করে (যার ফলে মেমোরি খরচ সবচেয়ে বড় মেম্বারের সাইজের সমান হয়)।
- ৩. Enumeration (enum): নামযুক্ত ইনটিজার কনস্ট্যান্টের সেটিং তৈরি করে যা কোডের পঠনযোগ্যতা বাড়ায়। যেমন: enum Day { MON=1, TUE, WED };
- ৪. Typedef (typedef): বিদ্যমান যেকোনো ডেটা টাইপের জন্য একটি নতুন সংক্ষেপ নাম (Alias) তৈরি করতে ব্যবহৃত হয়। যেমন: typedef unsigned long long int uint64;
৭. প্রাক্টিক্যাল সি কোড উদাহরণ (Comprehensive C Code Examples)
নিচে বিষয়গুলো প্রাক্টিক্যালি বোঝার জন্য ৪টি অত্যন্ত গুরুত্বপূর্ণ প্রোগ্রাম উদাহরণসহ দেওয়া হলো:
💻 উদাহরণ ১: প্রাইমারি ডেটা টাইপের মান প্রিন্ট করা #include <stdio.h> |
💻 উদাহরণ ২: sizeof অপারেটর দিয়ে সাইজ নির্ণয় #include <stdio.h> |
💻 উদাহরণ ৩: ইনটিজার ওভারফ্লো (Integer Overflow) প্রদর্শন #include <stdio.h> |
💻 উদাহরণ ৪: float এবং double-এর মধ্যে Precision পার্থক্য #include <stdio.h> |
৮. টাইপ কনভার্সন ও টাইপ কাস্টিং (Type Conversion & Type Casting)
একটি ডেটা টাইপকে অন্য ডেটা টাইপে পরিবর্তন করার প্রক্রিয়াকে টাইপ কনভার্সন বলা হয়। এটি দুই প্রকার:
৮.১ Implicit Type Conversion (স্বয়ংক্রিয় রূপান্তর)
কম্পাইলার যখন স্বয়ংক্রিয়ভাবে ছোট টাইপকে বড় টাইপে রূপান্তর করে (Type Promotion), তখন তাকে ইমপ্লিসিট কনভার্সন বলে। এতে ডেটা লস (Data Loss) হয় না।
যেমন: `int` এবং `float`-এর মধ্যে যোগ করলে ফলাফল স্বয়ংক্রিয়ভাবে `float` হয়ে যায়।
৮.২ Explicit Type Conversion / Type Casting (কাস্ট রূপান্তর)
প্রোগ্রামার যখন কাস্ট অপারেটর `(datatype)` ব্যবহার করে ম্যানুয়ালি কোনো টাইপকে জোরপূর্বক পরিবর্তন করেন, তাকে এক্সপ্লিসিট কনভার্সন বা টাইপ কাস্টিং বলে।
উদাহরণস্বরূপ: পূর্ণসংখ্যার ভাগফলে দশমিক মান বজায় রাখতে টাইপ কাস্টিং করা হয়:
💻 টাইপ কাস্টিং-এর উদাহরণ int sum = 17, count = 5; |
৯. সাধারণ ভুলসমূহ ও বেস্ট প্র্যাকটিস (Common Pitfalls & Best Practices)
- ১. ভুল ফরমেট স্পেসিফায়ার: float টাইপে %d বা int টাইপে %f দিলে ভুল ফলাফল বা Garbage Value আসবে।
- ২. ইনটিজার ডিভিশন ট্রাঙ্কেশন (Integer Division): দুটি int ভাগ করলে দশমিকের পরের অংশ মুছে যায় (যেমন 5 / 2 = 2)। দশমিক পেতে অন্তত একটি সংখাকে float/double করতে হবে বা কাস্ট করতে হবে।
- ৩. Unsigned-এ ঋণাত্মক মান: Unsigned টাইপে ঋণাত্মক মান অ্যাসাইন করলে কোনো ওয়ার্নিং ছাড়াই বিশাল ধনাত্মক মানে রূপান্তরিত হয়ে যাবে।
- ৪. সঠিক টাইপ বাছাই: গেম বা মোবাইল অ্যাপ ডেভেলপমেন্টে ছোট ডেটার জন্য int-এর বদলে short বা char ব্যবহার করলে মেমোরি অনেক সাশ্রয় হয়।
১০. অনুশীলনী ও ভাইভা প্রশ্নাবলী (Review & Interview Questions)
আপনার শিখন যাচাইয়ের জন্য নিচের প্রশ্নগুলো পড়ুন ও সমাধান করার চেষ্টা করুন:
- • প্রশ্ন ১: float এবং double-এর মধ্যে প্রধান ৩টি পার্থক্য কী কী?
- • প্রশ্ন ২: sizeof(3.14) এবং sizeof(3.14f)-এর মেমোরি সাইজের পার্থক্য কত বাইট এবং কেন?
- • প্রশ্ন ৩: signed char c = 130; লিখলে c-এর আউটপুট কত হবে এবং কেন?
- • প্রশ্ন ৪: void* (Generic Pointer) কীভাবে ব্যবহার করতে হয়?
- • প্রশ্ন ৫: C প্রোগ্রামিংয়ে int-এর আকার কেন ২ বাইট বা ৪ বাইট ভিন্ন ভিন্ন সিস্টেমে পরিবর্তন হয়?