انواع دادهها «Data Types» مشخص میکنند که یک متغیر «variable» معتبر در #C چه نوع دادهای را میتواند نگه دارد. سی شارپ #C یک زبان برنامهنویسی قوی نوع است زیرا در #C هر نوع داده (مانند عدد صحیح، کاراکتر، شناور و غیره) به طور پیشفرض به عنوان بخشی از زبان برنامهنویسی تعریف شده است و تمام ثابتها یا متغیرهایی که برای یک برنامه داده شده تعریف میشوند باید با یکی از انواع دادهها توصیف شوند. در این مقاله، به معرفی و توضیح انواع داده در سی شارپ #C پرداخته میشود و نحوه استفاده از آنها برای ذخیرهسازی و مدیریت دادهها در برنامههای #C بررسی خواهد شد.
مقدمه
در زبان برنامهنویسی #C، انواع داده بخش مهمی از ساختار برنامه را تشکیل میدهند. هر متغیر یا ثابت در #C باید از یکی از انواع دادههای مشخص شده استفاده کند که نوع دادهی آن مشخص میکند چه نوع اطلاعاتی میتواند ذخیره کند و چگونه با آن اطلاعات کار خواهد شد. #C به عنوان یک زبان برنامهنویسی با نوعهای دادهی قوی، از تقسیم انواع دادهها به سه دسته اصلی، یعنی انواع دادههای مقدار «Value Types» و انواع دادههای ارجاعی «Reference Types» و و انواع دادههای اشارهگر «Pointer Type» استفاده میکند. این دستهبندی به برنامهنویسان کمک میکند تا با توجه به نیازهای برنامه، از انواع داده مناسب استفاده کنند.
انواع داده در سی شارپ
انواع داده در سی شارپ #C عمدتاً به ۳ دسته تقسیم میشوند:
- انواع دادههای مقدار
- انواع دادههای ارجاعی
- نوع داده اشارهگر
انواع داده های مقدار در سی شارپ
انواع دادههای مقدار مستقیماً مقدار متغیر را در حافظه ذخیره میکنند و همچنین هر دو نوع با علامت و بدون علامت را قبول میکنند. کلاس مشتق شده برای این انواع دادهها، System.ValueType است. در زیر انواع مختلف دادههای مقدار در زبان برنامهنویسی #C آمده است:
انواع عددی صحیح با علامت و بدون علامت (Signed & Unsigned Integral Types): 8 نوع عددی صحیح وجود دارد که از مقادیر ۸ بیتی، ۱۶ بیتی، ۳۲ بیتی و ۶۴ بیتی به صورت با علامت یا بدون علامت پشتیبانی میکنند.
نام مستعار | نام نوع | نوع | اندازه بیت | محدوده | مقدار پیش فرض |
---|---|---|---|---|---|
sbyte | System.Sbyte | signed integer | ۸ | ۱۲۸- تا ۱۲۷ | ۰ |
short | System.Int16 | signed integer | ۱۶ | ۳۲۷۶۸- تا ۳۲۷۶۷ | ۰ |
Int | System.Int32 | signed integer | ۳۲ | ۲۳۱– تا ۱-۲۳۱ | ۰ |
long | System.Int64 | signed integer | ۶۴ | ۲۶۳– تا ۱-۲۶۳ | 0L |
byte | System.byte | unsigned integer | ۸ | ۰ تا ۲۵۵ | ۰ |
ushort | System.UInt16 | unsigned integer | ۱۶ | ۰ تا ۶۵۵۳۵ | ۰ |
uint | System.UInt32 | unsigned integer | ۳۲ | ۰ تا ۲۳۲ | ۰ |
ulong | System.UInt64 | unsigned integer | ۶۴ | ۰ تا ۲۶۳ | ۰ |
انواع دادههای نقطه شناور (Floating Point Types): دو نوع داده نقطه شناور وجود دارد که شامل نقطه اعشاری میباشند.
- Float: این نوع داده، یک نوع نقطه شناور با دقت تک (۳۲ بیتی) است. دقت آن ۷ رقم است. برای مقداردهی به متغیر float، از پسوند f یا F استفاده میشود. مانند: float x = 3.5F. اگر از پسوند F یا f استفاده نشود، به طور پیشفرض به عنوان نوع double در نظر گرفته میشود.
- Double: این نوع داده، یک نوع نقطه شناور با دقت دوگانه (۶۴ بیتی) است. دقت آن ۱۴ تا ۱۵ رقم است. برای مقداردهی به متغیر double، از پسوند d یا D استفاده میشود. اما استفاده از پسوند ضروری نیست زیرا به طور پیشفرض نوع دادههای شناور از نوع double هستند.
نام مستعار | نام نوع | اندازه بیت | محدوده | مقدار پیش فرض |
float | System.Single | ۳۲ | ۱۰-۴۵×±۱.۵ تا ۱۰۳۸×۳.۴± | ۰.0F |
double | System.Double | ۶۴ | ۱۰-۳۲۴×±۵.۰ تا ۱۰۳۰۸×۱.۷± | ۰.0D |
انوع دادههای اعشاری Decimal Types: نوع داده decimal یک نوع داده ۱۲۸ بیتی است که برای محاسبات مالی و پولی مناسب است. دقت آن ۲۸ تا ۲۹ رقم است. برای مقداردهی به متغیر decimal، از پسوند m یا M استفاده میشود. مانند: decimal x = 300.5m. اگر از پسوند m یا M استفاده نشود، به طور پیشفرض به عنوان نوع double در نظر گرفته میشود.
نام مستعار | نام نوع | اندازه بیت | محدوده | مقدار پیش فرض |
decimal | System.Decimal | ۱۲۸ | ۱۰-۲۸×±۱.۰ تا ۱۰۲۸×۷.۹۲۲۸± | ۰.0M |
انواع دادههای کاراکتر Character Types: انواع دادههای کاراکتر نمایانگر یک واحد کد UTF-16 یا نمایانگر یک کاراکتر یونیکد ۱۶ بیتی هستند.
نام مستعار | نام نوع | اندازه بیت | محدوده | مقدار پیش فرض |
char | System.Char | ۱۶ | U +0000 تا U +ffff | ‘\۰’ |
مثال ۱: تکه کد زیر یک برنامهی سادهی C# است که انواع دادههای عددی و کاراکتری را معرفی و مقداردهی میکند و سپس مقدار هر یک را در کنسول نمایش میدهد.
// C# program to demonstrate // the above data types using System; namespace ValueTypeTest { class ProgramStore { // Main function static void Main() { // declaring character char a = 'P'; // Integer data type is generally // used for numeric values int i = 89; short s = 56; // this will give error as number // is larger than short range // short s1 = 87878787878; // long uses Integer values which // may signed or unsigned long l = 4564; // UInt data type is generally // used for unsigned integer values uint ui = 95; ushort us = 76; // this will give error as number is // larger than short range // ulong data type is generally // used for unsigned integer values ulong ul = 3624573; // by default fraction value // is double in C# double d = 8.358674532; // for float use 'f' as suffix float f = 3.7330645f; // for float use 'm' as suffix decimal dec = 389.5m; Console.WriteLine("char: " + a); Console.WriteLine("integer: " + i); Console.WriteLine("short: " + s); Console.WriteLine("long: " + l); Console.WriteLine("float: " + f); Console.WriteLine("double: " + d); Console.WriteLine("decimal: " + dec); Console.WriteLine("Unsinged integer: " + ui); Console.WriteLine("Unsinged short: " + us); Console.WriteLine("Unsinged long: " + ul); } } }
خروجی
char: P integer: 89 short: 56 long: 4564 float: 3.733064 double: 8.358674532 decimal: 389.5 Unsinged integer: 95 Unsinged short: 76 Unsinged long: 3624573
مثال ۲: این برنامه C# مفهوم نوع دادهای sbyte (عدد صحیح علامتدار ۸ بیتی) و سرریز عددی (Overflow) را نشان میدهد.
// signed integral data type using System; namespace ValueTypeTest { class ProgramStore { // Main function static void Main() { sbyte a = 126; // sbyte is 8 bit // singned value Console.WriteLine(a); a++; Console.WriteLine(a); // It overflows here because // byte can hold values // from -128 to 127 a++; Console.WriteLine(a); // Looping back within // the range a++; Console.WriteLine(a); } } }
خروجی
۱۲۶ ۱۲۷ -۱۲۸ -۱۲۷
- کد بالا نشان میدهد که چگونه اعداد علامتدار (sbyte) در C# رفتار میکنند و سرریز (Overflow) چگونه اتفاق میافتد.
- مقدار sbyte پس از رسیدن به بیشترین مقدار (۱۲۷)، با افزایش دوباره به کمترین مقدار (-۱۲۸) برمیگردد.
- این رفتار به دلیل ساختار مکمل دو در نمایش اعداد در کامپیوتر است.
مثال ۳: تکه کد زیر در #C نوع دادهای byte (عدد صحیح بدون علامت ۸ بیتی) و سرریز عددی «Overflow» را نشان میدهد.
// C# program to demonstrate // the byte data type using System; namespace ValueTypeTest { class Program { // Main function static void Main() { byte a = 0; // byte is 8 bit // unsigned value Console.WriteLine(a); a++; Console.WriteLine(a); a = 254; // It overflows here because // byte can hold values from // ۰ to 255 a++; Console.WriteLine(a); // Looping back within the range a++; Console.WriteLine(a); } } }
خروجی
۰ ۱ ۲۵۵ ۰
کد بالا نشان میدهد که چگونه اعداد بدون علامت (byte) در #C رفتار میکنند و سرریز (Overflow) چگونه اتفاق میافتد. مقدار byte پس از رسیدن به بیشترین مقدار (۲۵۵)، با افزایش دوباره به کمترین مقدار (۰) برمیگردد. این رفتار به دلیل نمایش دادهها در سطح باینری است.
انواع دادههای بولی Boolean Types: باید به مقدار true یا false اختصاص داده شوند. مقادیر نوع bool به صورت ضمنی یا صریح (با استفاده از نوعریزی with casts) به هیچ نوع دیگری تبدیل نمیشوند. اما برنامهنویس میتواند بهراحتی کد تبدیل را بنویسد.
Alias نام مستعار | Type Name نام نوع | Values مقادیر |
bool | System.Boolean | True / False |
مثال: تکه کد زیر در #C نوع دادهای bool (بولی) را بررسی میکند و نشان میدهد که چگونه مقدار true میتواند در شرطها استفاده شود. حالا بیایید کد را بررسی کنیم.
// C# program to demonstrate the // boolean data type using System; namespace ValueTypeTest { class ProgramStore { // Main function static void Main() { // boolean data type bool b = true; if (b == true) Console.WriteLine("Hi Pstore"); } } }
خروجی
Hi Pstore
- کد بالا نشان میدهد که چگونه نوع دادهای bool در #C استفاده میشود.
- مقدار true باعث اجرای کد داخل if شده و پیام “Hi Pstore” را در کنسول نمایش میدهد.
- نیازی به == true نیست و میتوان کد را به صورت if (b) نوشت.
انواع داده های ارجاعی در سی شارپ
انواع دادههای ارجاعی آدرس حافظه مقدار متغیر را ذخیره میکنند زیرا انواع ارجاعی مقدار متغیر را مستقیماً در حافظه ذخیره نمیکنند. زمانی که یک متغیر از نوع ارجاعی مانند شیء یا رشته ایجاد میکنید، در واقع یک ارجاع (یا اشارهگر) به مکان حافظهای که داده در آن ذخیره شده است را ذخیره میکنید. دادههای واقعی برای انواع ارجاعی در هیپ «heap» ذخیره میشوند. هیپ یک استخر بزرگ از حافظه است که برای تخصیص حافظه دینامیک استفاده میشود. انواع ارجاعی داخلی عبارتند از: string و object.
رشته (String): رشته یک دنباله از کاراکترهای یونیکد «Unicode» را نمایش میدهد و نام نوع آن System.String است. بنابراین، string و String معادل یکدیگر هستند.
مثال:
string s1 = "hello"; // creating through string keyword String s2 = "welcome"; // creating through String class
شیء (Object): در #C، تمام انواع دادهها، چه پیشفرض و چه کاربر تعریفشده، چه انواع ارجاعی و چه انواع مقدار، به طور مستقیم یا غیرمستقیم از کلاس Object ارثبری میکنند. بنابراین، اساساً Object کلاس پایه برای تمام انواع دادهها در #C است. قبل از اختصاص مقادیر، نیاز به تبدیل نوع دارد. هنگامی که یک متغیر از نوع مقدار به شیء تبدیل میشود، به آن Boxing میگویند. هنگامی که یک متغیر از نوع شیء به یک نوع مقدار تبدیل میشود، به آن Unboxing میگویند. نام نوع آن System.Object است.
مثال: تکه کد زیر در C# انواع دادهای مرجع «Reference Types» مانند string و object را بررسی میکند.
// C# program to demonstrate // the Reference data types using System; namespace ValueTypeTest { class Program { // Main Function static void Main() { // declaring string string a = "Prog"; //append in a a+="ram"; a = a+"Store"; Console.WriteLine(a); // declare object obj object obj; obj = 20; Console.WriteLine(obj); // to show type of object // using GetType() Console.WriteLine(obj.GetType()); } } }
خروجی
ProgramStore ۲۰ System.Int32
- کد بالا نشان میدهد که نوع دادهای string و object جزء Reference Types هستند.
- رشتهها «string» تغییرناپذیر «Immutable» هستند و بهتر است در تغییرات مداوم از StringBuilder استفاده شود.
- object میتواند هر نوع دادهای را ذخیره کند و تابع ()GetType نوع واقعی مقدار داخل آن را نمایش میدهد.
نوع داده اشارهگر در سی شارپ
در زبان برنامهنویسی، نوع داده اشارهگر برای ذخیره آدرس حافظهای که مقدار یک متغیر در آن قرار دارد، استفاده میشود. برای کار با اشارهگرها، از دو عملگر اصلی استفاده میشود:
- آمپرسند (&): بهعنوان عملگر آدرس شناخته میشود و برای بهدستآوردن آدرس یک متغیر بهکار میرود.
- ستاره (*): بهعنوان عملگر غیرمستقیم یا dereference شناخته میشود و برای دسترسی به مقدار ذخیرهشده در آدرس اشارهگر استفاده میشود.
نکته: برای استفاده از کدهای اشارهگر «Pointer» در #C باید کد را در یک بلوک unsafe قرار دهید و گزینه Allow unsafe code را در تنظیمات پروژه فعال کنید.
مثال: تکه کد زیر در #C استفاده از اشارهگرها «Pointers» را نشان میدهد که به ما امکان دسترسی مستقیم به آدرس حافظه را میدهد.
using System; namespace Pointerprogram { class Pstore { // Main function static void Main() { unsafe { // declare variable int n = 10; // store variable n address // location in pointer variable p int* p = &n; Console.WriteLine("Value :{0}", n); Console.WriteLine("Address :{0}", (int)p); } } } }
خروجی
Value :10 Address :865740784
- کد بالا نشان میدهد که چگونه با استفاده از unsafe و int* در C# میتوان آدرس حافظه را دریافت کرد.
- &n برای دریافت آدرس حافظهی متغیر و *p برای دسترسی به مقدار آن از طریق اشارهگر استفاده میشود.
- برای اجرای این کد، unsafe باید فعال باشد و کامپایلر C# از حالت unsafe پشتیبانی کند.
سخن آخر
در این مقاله، به بررسی انواع داده در سی شارپ #C پرداختیم و با ویژگیها و کاربردهای هر نوع آشنا شدیم. انواع داده در سی شارپ #C به سه دسته اصلی تقسیم میشوند: انواع دادههای مقدار (برای ذخیرهسازی مستقیم مقادیر در حافظه)، انواع دادههای ارجاعی (که به آدرس حافظه مقادیر اشاره میکنند) و انواع دادههای اشارهگر (برای مدیریت مستقیم حافظه).
هر کدام از این انواع دادهها، ابزارهای قدرتمندی برای مدیریت و پردازش اطلاعات در اختیار برنامهنویسان قرار میدهند. انتخاب نوع داده مناسب با توجه به نیاز برنامه و میزان استفاده از منابع سیستم، نقش کلیدی در بهینهسازی عملکرد برنامهها دارد.
در نهایت، آگاهی از جزئیات و نحوه استفاده از انواع دادهها به برنامهنویسان کمک میکند تا کدهای کارآمدتر، خواناتر و قابل مدیریتتری بنویسند و از امکانات غنی زبان #C بهره بیشتری ببرند.