انواع داده‌ها در C#

09 تیر 1396
درسنامه درس 2 از سری آموزش سی شارپ (C#)
csharp-datatypes

با مطالعه فصل گذشته اطلاعاتی شامل آشنایی با محیط نرم افزار و همچنین اجرای اولین پروژه به زبان #C در اختیار شما قرار گرفت. حال در این فصل قصد داریم انواع داده‌ ها در زبان برنامه‌نویسی سی شارپ را خدمت شما عزیزان ارائه دهیم که آموختن این فصل برای ورود به دنیای حرفه‌ای بسیار مهم است.

مقدمه

در تمام زبان‌های برنامه‌نویسی انواع داده به عنوان یک معرف جهت ذخیره اطلاعات مورد استفاده قرار می‌گیرد. حال برای اینکه بدانیم چه نوع داده‌ای را به چه صورت درون یک متغییر ذخیره کنیم نیاز داریم تا با انواع داده در زبان برنامه‌نویسی سی شارپ آشنا شویم.

داده‌ها در زبان برنامه نویسی سی شارپ به در دو حالت کلی ذخیره می‌شوند: ثابت و متغییر تقسیم‌بندی می‌شوند.

داده‌های ثابت: به داده‌های گفته می‌شود که در طول اجرای برنامه همواره یک مقدار ثابت را در خود ذخیره می‌کنند.

داده‌ها متغییر: به داده‌هایی گفته می‌شود که در طول اجرای برنامه مقادیر مختلفی را می‌پذیرند.

حال نوع داده‌های ثابت و متغییر تعیین می‌کنند که چه فضایی از سیستم را برای ذخیره مقادیر اشغال کنند.

تعریف متغییر

برای تعریف متغییر در زبان سی شارپ باید ابتدا نوع متغییر را نوشته و سپس عنوان متغییر را به صورت camelCase (یعنی اولین حرف متغییر کلمه کوچک و سایر حروف بخش های دیگر آن به صورت کلمه بزرگ باشد). سپس یک علامت مساوی = قرار داده و در نهایت مقداری که می‌خواهیم درون متغییر ذخیره شود را بنویسیم. بنابراین در حالت کلی داریم:

Variable Type  Variable Name = مقدار

انواع داده متغییر

byte: این نوع داده‌ی عددی فضایی معادل ۸ بیت را اشغال می‌کند و اعداد صحیح مثبت بین ۰ تا ۲۵۵± را در خود جای می‌دهد.

sbyte: این نوع داده‌ی عددی فضایی معادل ۸ بیت را اشغال می‌کند و اعداد صحیح مثبت و منفی بین ۱۲۸- تا ۱۲۷ را در خود جای می‌دهد.

short: این نوع داده عددی فضایی معادل ۱۶ بیت را اشغال کرده و اعداد صحیح مثبت و منفی در بازه‌ی بین ۳۲۷۶۸- تا ۳۲۷۶۷ را در خود ذخیره می‌کند.

ushort: این نوع داده عددی فضایی معادل ۱۶ بیت را اشغال کرده و اعداد صحیح مثبت در بازه‌ی بین ۰ تا ۶۵۵۳۵± را در خود ذخیره می‌کند.

int:  این نوع داده عددی فضایی معادل ۳۲ بیت را اشغال کرده و اعداد صحیح مثبت و منفی در بازه‌ی بین ۲۱۴۷۴۸۳۶۴۸- تا ۲۱۴۷۴۸۳۶۴۸+ (حدود مثبت منفی ۲۰۰۰۰۰۰۰۰۰ دو میلیارد) را در خود ذخیره می‌کند.

uint: این نوع داده عددی فضایی معادل ۳۲ بیت را اشغال کرده و اعداد صحیح مثبت در بازه‌ی بین ۰ تا ۴۲۹۴۹۶۷۲۹۵± (حدود ۴۰۰۰۰۰۰۰۰۰ چهار میلیارد) را در خود ذخیره می‌کند.

long:  این نوع داده عددی فضایی معادل ۶۴ بیت را اشغال کرده و اعداد صحیح مثبت و منفی در بازه‌ی بین ۹۲۲۳۳۷۲۰۳۶۸۵۴۷۷۵۸۰۸- تا ۹۲۲۳۳۷۲۰۳۶۸۵۴۷۷۵۸۰۷+ را در خود ذخیره می‌کند.

ulong: این نوع داده عددی فضایی معادل ۶۴ بیت را اشغال کرده و اعداد صحیح مثبت در بازه‌ی بین ۰ تا ۱۸۴۴۶۷۴۴۰۷۳۷۰۹۵۵۱۶۱۵ را در خود ذخیره می‌کند.

float: این نوع داده‌ی عددی فضایی معادل ۳۲ بیت را اشغال کرده و اعداد اعشاری مثبت و منفی در بازه‌ی بین ۳.۴۰۲۸۲۳e۳۸- تا ۳.۴۰۲۸۲۳e۳۸- را درون خود ذخیره می‌کند.

double: این نوع داده‌ی عددی فضایی معادل ۶۴ بیت را اشغال کرده و اعداد اعشاری مثبت و منفی در بازه‌ی بین ۱.۷۹۷۶۹۳۱۳۴۸۶۲۳۲e۳۰۸- تا ۱.۷۹۷۶۹۳۱۳۴۸۶۲۳۲e۳۰۸+ را درون خود ذخیره می‌کند. همچنین با استفاده از این نوع داده مقدار اعشاری به صورت اتوماتیک رند می‌شود.

decimal: این نوع داده‌ی عددی فضایی معادل ۱۲۸ بیت را اشغال کرده و اعداد اعشاری مثبت و منفی در بازه‌ی بین  ۱۰e-۲ × ۱.۰ ± تا ۱۰e۲۸ × ۷.۹ ± را درون خود ذخیره می‌کند.

تفاوت بین نوع داده‌ی float و double و decimal:

توجه: داده‌های عددی float و double معمولا برای اندازه گیری مقادیری که دقت در آنها معیار نیست مورد استفاده قرار می‌گیرند. مثلا فاصله، مسافت و ... اما داده‌ی عددی decimal برای حالتی که دقت عددی مدنظر می‌باشد بکار گرفته خواهد شد مثل واحد پول، محاسبات حسابداری و ...

char: این نوع داده‌ی رشته‌ای فضایی معادل ۱۶ بیت را اشغال کرده و تمام کاراکترهای یونیکد را درون خود ذخیره می‌کند.

string: این نوع داده‌ی رشته‌ای مجموعه‌ای از کاراکترها را در خود ذخیره می‌کند و متناسب با آنها فضایی را اشغال خواهد کرد.

bool: این نوع داده‌ی باینری فضایی معادل ۸ بیت را اشغال کرده و معمولا برای عبارتهای درست و غلط یا ۰ و ۱ مورد استفاده قرار می‌گیرد.

object: این نوع داده بر اساس مقداری که برابر آن قرار می‌گیرد نوع عددی، رشته‌ای یا باینری را می‌تواند در خود ذخیره کند. به عبارتی نوع داده object تمام مقادیر و عبارتها را می‌تواند در خود ذخیره کند.

در مجموعه دستورهای زیر مثالی از هر یک از این داده‌ها ارائه شده است:

byte i = 10;
sbyte i = -10;
short i = -12345;
ushort i = 60500;
int i = -1999888777;
uint i = 3999888777;
long i = -8223372036854775808;
long i = 16223372036854775808;

float i = (float)3.44; (حتما باید نوع را داخل پرانتز برای float‌ بنویسیم)
float i = 3.44f; (یک راه دیگر برای تعریف نوع داد float نوشتن حرف f پس از مقدار است)

decimal i = (decimal)333.444; (حتما باید نوع را داخل پرانتز برای float‌ بنویسیم)
decimal i = 333.444m; (یک راه دیگر برای تعریف نوع داد float نوشتن حرف f پس از مقدار است)

char i = "r";
string i = "roxo"
bool i = true
object o = i

فرض کنید میخواهید یک داده با مقدار ۱۰ را درون یک متغییر ذخیره کنید. این متغییر باید یک نوع داشته باشد تا مقدار عددی ۱۰ را درون خود ذخیره کند. کمترین مقدار نوع داده عددی byte است که فضایی معادل ۸ بیت از سیستم را اشغال می‌کند. حال اگر ما مثلا نوع داده‌ی long را برای ذخیره‌ی عدد ۱۰ انتخاب کنیم، چیزی جز یک فاجعه اتفاق نمی‌افتد. چون شما برای ذخیره کردن عدد ۱۰ فضایی را که عددی معادل ۲۰۰۰۰۰۰ اشغال می‌کند، از سیستم خود گرفته‌اید. بنابراین تعیین نوع داده بسیار حیاتی بوده و روی عملکرد نرم افزار شما تاثیر بسزایی می‌گذارد.

نوع داده‌ی ثابت یا Constant

برای تعریف یک نوع داده‌ی ثابت که تنها یک مقدار را به خود اختصاص می‌دهد کافی‌ست عبارت const را در پشت نام ثابت قرار دهیم:

const int a = 100;

دوستان عزیز توجه بفرمایید که قرار نیست مطالب را پیچیده کنیم. بلکه برای هر عنوانی تنها یک توضیح به همراه مثال ارائه میدهیم. شما تمرکز محتوایی داشته باشید و خودتان را درگیر حاشیه نکنید تا تمام فصل ها را با موفقیت مطالعه بفرمایید.

Implicit Casting

قبل از ورود به بخش بعدی معرفی داده، بهتر است از عبارتی تحت عنوان کستینگ (فرم‌دهی) استفاده کرده و آن را معرفی کنیم. کستینگ به معنای فرم دهی و شکل دادن به نوع داده‌هاست یک مثال خیلی واضح را مطرح می‌کنیم:

int a = 10;
short b = 10;

b = a (True Implicit Casting)
a = b (error)

در مجموعه کد فوق ما عبارت b را برابر a قرار دادیم و با خطایی مواجه نشدیم ولی وقتی عبارت a را برابر با b قرار می‌دهیم کامپایلر خطا می‌دهد. زیرا نوع داده‌ی a بزرگتر از داده‌ی b است و انتساب به درستی صورت نگرفته است. این دقیقا معادل این مثال است: می‌خواهیم یک پارچ آب را درون یک لیوان بریزیم. اگر اینکار را انجام دهیم سرریز صورت گرفته و این خطاست. ولی می‌توان یک لیوان آب را درون یک پارچ ریخت و مشکلی پیش نمی‌آید.

بنابراین تبدیل انواع داده‌ها به صورت Implicit‌ (درونی یا نامحسوس) به صورت زیر است:

Source Type     Target Type
Byte            short, ushort, int, uint, long, ulong, float, double, or decimal
Sbyte           short, int, long, float, double, or decimal
Int             long, float, double, or decimal
Uint            long, ulong, float, double, or decimal
Short           int, long, float, double, or decimal
Ushort          int, uint, long, ulong, float, double, or decimal
Long            float, double, or decimal
Ulong           float, double, or decimal
Float           double
Char            ushort, int, uint, long, ulong, float, double, or decimal

حال برای اینکه این مشکل برطرف شود از تبدیل انواع داده استفاده می‌کنیم. برای اینکار داریم:

long long2 = 5483;
int int2 = (int)long2;

همانطور که ملاحظه می‌کنید در این روش داده‌ی long به نوع داده‌ی int تبدیل شد. یعنی با قرار دادن نوع داده در پرانتز قبل از داده‌ی اصلی، نوع جدیدی بوجود می‌آید. به این روش تبدیل واضح یا صریح (Explicit Conversion) گفته می‌شود. تبدیل انواع داده‌ها به صورت explicit در جدول زیر آمده است:

Source Type     Target Type
Byte            sbyte or char
Sbyte           byte, ushort, uint, ulong, or char
Int             sbyte, byte, short, ushort, uint, ulong, or char
Uint            sbyte, byte, short, ushort, int, or char
Short           sbyte, byte, ushort, uint, ulong, or char
Ushort          sbyte, byte, short, or char
Long            sbyte, byte, short, ushort, int, uint, ulong, or char
Ulong           sbyte, byte, short, ushort, int, uint, long, or char
Float           sbyte, byte, short, ushort, int, uint, long, ulong, char, ordecimal
Double          sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or decimal
Char            sbyte, byte, or short
Decimal         sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double

نوع داده‌ی Enumeration ( شمارشی)

از این نوع داده معمولا برای شمارش متغییرها استفاده می‌کنیم یعنی اگر یک داده‌ای از نوع enum تعریف شود قابل شمارش می‌باشد. این شمارنده از ۰ شروع شده و تا انتهای یک داده شروع به شمارش می‌کند. این داده معمولا به صورت زیر تعریف می‌شود:

public enum Color
{
    Green,   //defaults to 0
    Orange,  //defaults to 1
    Red,     //defaults to 2
    Blue     //defaults to 3
}

همچنین می‌توان به نوع داده‌ی شمارشی مقادیری را نسبت داد تا نوع شمارشی و ترتیب آنها بر اساس آن مقادیر تعیین شود.

public enum Color2
{
    Green = 10,
    Orange = 20,
    Red = 30,
    Blue = 40
}

تعریف مسیر فایل‌ها به صورت داده‌ی رشته‌ای

برای تعریف مسیر فایل ها که معمولا به صورت \\\\FileShare\\Directory\\file.txt می‌باشد کامپایلر خطا می‌دهد یعنی ما نمی‌توانیم یک مسیر را به یک رشته به صورت فوق نمایش دهیم بنابراین مطابق ذیل از یک علامت @ برای جلوگیری از بروز خطای احتمالی که معادل دستور "t\" برای tab یا "\" به عنوان بک‌اسلش است استفاده می‌کنیم:

string path1 = "\\\\FileShare\\Directory\\file.txt"; احتمال بروز خطا

string path1 = @"\\\\FileShare\\Directory\\file.txt"; درست

نوع داده‌ی Nullable

در زبان برنامه‌نویسی سی شارپ یک نوع داده‌ی خاص به نام نوع nullable وجود دارد که شما می‌توانید به آنها مقدار null را اختصاص دهید. برای مثال شما می‌توانید هر مقداری در بازه‌ی ۲۱۴۷۴۸۳۶۴۸- تا ۲۱۴۷۴۸۳۶۴۷ یا null را درون یک متغییر Nullable<Int32> قرار دهید. مثال دیگری را خدمت شما عزیزان مطرح می‌کنیم. فرض کنید می‌خواهید متغییر باینری را تعریف کرده و مقدار null را به آن اختصاص دهید در اینصورت می‌توان یک متغییر Nullable<bool> تعریف کرد. در حالت کلی ساختار نوع داده‌ی Nullable به صورت زیر است:

< data_type> ? <variable_name> = null;

به عنوان مثال برای تعریف متغییرها داریم:

int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;

bool? boolval = new bool?();

در نوع داده‌ی Null یک عملگر وجود دارد که به عملگر تلفیق معروف بوده و با علامت ?? معرفی می‌شود. این عملگر زمانی که بین دو داده بکار گرفته شود بدین صورت عمل می‌کند که اگر داده‌ی اول null بود داده‌ی دوم را نمایش می‌دهد و بالعکس. برای روشن تر شدن این موضوع مثال زیر را باهم بررسی می‌کنیم:

using System;
namespace CalculatorApplication
{
   class NullablesAtShow
   {
      static void Main(string[] args)
      {
         double? num1 = null;
         double? num2 = 3.14157;
         double num3;
         num3 = num1 ?? 5.34;      
         Console.WriteLine(" Value of num3: {0}", num3);
         num3 = num2 ?? 5.34;
         Console.WriteLine(" Value of num3: {0}", num3);
         Console.ReadLine();
      }
   }
}

همانطور که ملاحظه می‌کنید داده‌ی اول num1 مقداری برابر null دارد در داده‌ی سوم num3 از عملگر ?? استفاده شده است. یعنی بررسی می‌کند اگر داده‌ی اول مقداری برابر null داشته باشد مقدار بعد از عملگر را نمایش می‌دهد. این موضوع برای داده‌ی num2 نیز صادق است. خروجی این مثال به صورت زیر خواهد بود:

Value of num3: 5.34
Value of num3: 3.14157

بسیار عالی! تا به اینجای کار انواع داده‌ها در زبان برنامه‌نویسی سی شارپ را فرا گرفتید. در فصل بعدی به توضیح مفصلی درباره آرایه‌ها می‌پردازیم تا با آنها بیشتر آشنا شوید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش سی شارپ (C#) توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (5 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Jey183
05 مرداد 1400
سلام. لطفا اصلاح کنید. و مثال double هم نوشته نشده. float i = (float)3.44; (حتما باید نوع را داخل پرانتز برای float‌ بنویسیم) float i = 3.44f; (یک راه دیگر برای تعریف نوع داد float نوشتن حرف f پس از مقدار است) decimal i = (decimal)333.444; (حتما باید نوع را داخل پرانتز برای *****float‌ بنویسیم) decimal i = 333.444m; (یک راه دیگر برای تعریف نوع داد *****float نوشتن حرف *******f پس از مقدار است)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد
19 مرداد 1398
با سلام در این پاراگراف خطایی وجود دارد : هنگامی تبدیل ضمنی صورت می‌گیرد که نوع داده کوچکتر از نوع داده‌ای دیگر باشد ، پس این نوع تبدیل صحیح است : ;int a = 10 ;short b = 10 ;a = b این انتساب صحیح است چرا که نوع داده‌ی int بزرگتر از نوع داده‌ی b است و در جایگذاری بیت‌ها مشکلی به جود نمی‌آید و اما انتساب زیر غلط است چرا که نوع داده‌ی short کوچکتر از نوع داده‌ی int است و از آنجایی که short یک نوع داده‌ی 16 بیتی است و int یک نوع داده‎ی 32 بیتی در عمل انتساب سریزی صورت می‌گیرد و باعث ایجاد خطا می‎شود . ;int a = 10 ;short b = 10 ;b = a صحیح نیست و باعث ایجاد خطا می‏‎شود ، چرا که short ظرفیت نگهداری بیت‎های نوع داده‎ی int را ندارد .

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سیامک آهی
17 دی 1397
بنده مدرس حرفه ای سی شارپ هستم. مطلب فقوق بسیار عالی و کاربردی بود. انشالله دوستان علاقمند استفاده کنند. دست شما درد نکنه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

RAMIN
24 شهریور 1397
سلام خیلی خوب توضیح دادید ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سلطانی
20 تیر 1397
سلام فایل این فصل ها موجود نیست؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.