
آموزش گام به گام #C (جلسه دوم: عملگرها، نوعها و متغیرها)
عملگرها، نوعها و متغیرها اجزای اصلی پایهای سازنده کدها هستند. شناخت کامل و درک عملکرد این اجزاء، از جمله اساسیترین و مهمترین بخش هر زبان برنامهنویسی است. در این جلسه به معرفی و توضیح کامل عملگرها، نوعها و متغیرهای زبان #C میپردازیم. با ما همراه باشید.
جلسه اول: آغاز کار با #C | جلسه ششم: namespaceها | جلسه یازدهم: اندیس گذار یا indexerها | جلسه شانزدهم: استفاده از اتریبیوتها | جلسه بیست و یکم: متدهای بینام یا anonymous |
جلسه دوم: عملگرها، نوعها و متغیرها | جلسه هفتم: مقدمهای بر کلاسهای #C | جلسه دوازدهم: ساختار یا structها | جلسه هفدهم: enumها | جلسه بیست و دوم: موضوعاتی در مورد نوع در #C |
جلسه سوم: عبارات کنترلی - گزینشی | جلسه هشتم: وراثت کلاس در #C | جلسه سیزدهم: واسط یا interfaceها | جلسه هجدهم: عملگرهای overloading | جلسه بیست و سوم: کار با نوعهای nullable |
جلسه چهارم: عبارات کنترلی - حلقهها | جلسه نهم: چند ریختی | جلسه چهاردهم: مقدمهای بر delegateها و رویدادها | جلسه نوزدهم: کپسولهسازی | |
جلسه پنجم: متدها | جلسه دهم: ویژگی یا propertyها | جلسه پانزدهم: مقدمهای بر کنترل خطا یا exception | جلسه بیستم: مقدمهای بر generic collectionها |
در این جلسه به معرفی عملگرها، نوعها و متغیرهای C# میپردازیم. هدف این جلسه دستیابی به اهداف زیر است:
- شناخت متغیرها.
- آشنایی با نوعها در زبان #C.
- آشنایی مقدماتی با عملگرهای #C.
- آموختن طرز استفاده از آرایهها.
متغیرها و نوعها
"متغیرها" در واقع فضاها یا ظرفهایی از حافظه هستند که دادهها را در خود جای میدهند. میتوانید در آنها داده قرار دهید و همچنین میتوانید محتوای آنها را به عنوان بخشی از یک کد #C فراخوانی کنید. تفسیر دادههای داخل یک متغیر توسط "نوعها" کنترل میشود.
#C یک زبان به شدت حساس به نوع است. بنابراین همه عملگرهایی که برای متغیرها به کار میروند با توجه به نوع متغیر انتخاب و به کار گرفته میشوند. قوانینی وجود دارند که تعریف میکنند چه عملگرهایی برای حفظ جامعیت دادههای قرار گرفته در متغیرها قانونی و معتبر هستند.
نوعهای ساده #C عبارتاند از نوع boolean و سه نوع عددی(یعنی Integralها، Floating Point و Decimal) و نوع رشته.
واژه "Integral" که مخصوصا در زبان برنامهنویسی #C تعریف شده است، شامل طبقهبندی نوعهای sbyte، byte، short، ushort، Int، Uint، Long، ulong و char میباشد.
در ادامه این جلسه بیشتر در مورد انواع Integralها صحبت خواهیم کرد. واژه “Floatin Point” به نوعهای float و double اشاره دارد که همراه با نوع Decimal به طور مفصل در بخشهای بعدی این جلسه مورد بحث قرار خواهند گرفت.
نوع رشته یا string شامل رشتهای از حروف(character) است که در بخش مخصوص به رشتهها در این جلسه در مورد آن صحبت خواهیم کرد. در بخش بعد، به معرفی نوع boolean خواهیم پرداخت.
نوع boolean
نوعهای boolean با استفاده از کلیدواژه bool معرفی میشوند. این نوعها دارای دو مقدار هستند: true یا false. در زبانهای دیگر مانند C و ++C، شرط بولین به این صورت برقرار میشود که صفر به معنی false و هر چیز دیگر به معنی true است.
به هر حال، در #C تنها مقادیری که شرط boolean را برقرار میکنند همان True و false هستند که کلمات کلیدی رسمی زبان #C میباشند. لیست ۱-۲ یکی از چندین روش استفاده از نوعهای بولین در یک برنامه را نمایش میدهد.
لیست ۱-۲: نمایش مقادیرboolean : Boolean.cs
using System;
class Booleans
{
public static void Main()
{
bool content = true;
bool noContent = false;
Console.WriteLine("It is {0} that MUG provides C# programming language content.", content);
Console.WriteLine("The statement above is not {0}.", noContent);
}
}
در لیست ۱-۲، مقادیر boolean در کنسول به عنوان بخشی از یک جمله نوشته شدهاند. تنها مقادیر قانونی و معتبر برای نوع bool مقادیر true و False هستند. همانطور که مشاهده میکنید مقدار true به content و مقدار false به nocontent اختصاص یافته است.
وقتی برنامه اجرا شود، خروجی زیر به دست میآید.
It is True that MUG provides C# programming language content.
The statement above is not False.
نوعهای Integral
در C#، Integral یک دسته از چندین نوع است. برای آن دسته از افرادی که واژه Integral یادآور مباحث ریاضیات است باید بگویم که از نقطه نظر زبان برنامهنویسی #C، نوعهای موجود در دسته Integral در واقع به عنوان انواع نوعهای عددی در برنامهنویسی شناخته میشوند.
این نوعها شامل تمام اعداد صحیح(مثبت و منفی) و نوع char هستند. نوع char یک حرف یا کاراکتر یونیکد(Unicode) است، چون توسط استاندارد یونیکد تعریف شده است. جدول ۱-۲ نوعهای integral، سایز و بازه آنها را نشان میدهد.
جدول ۱-۲: سایز و بازه نوعهای Integral در #C
نوعهای Integral برای عملگرهایی که در محاسبات عددی دخیل هستند بسیار مناسب میباشند. نوع char یک استثنا است و نماینده یک حرف یا کاراکتر یونیکد است.
همانطور که در جدول بالا مشاهده میکنید، بسته به نیازهایی که در کد نویسی دارید، از حق انتخاب بسیار گسترده و وسیعی برخوردار هستید.
نوعهای Floating Point و decimal
یک نوع floating point در #C یا یک float است یا یک double. زمانی از این نوعها استفاده میشود که لازم باشد از یک عدد حقیقی که توسط استاندارد IEEE754 تعریف شده باشد، استفاده کنید.
نوعهای decimal باید وقتی میخواهید مقادیر مالی یا پولی نمایش دهید مورد استفاده قرار گیرند.
جدول ۲-۲ نوعهای floating point و Decimal به همراه سایز و بازه آنها را نشان میدهد.
جدول ۲-۲: نوعهای floating point و Decimal همراه با سایز، دقت و بازه آنها.
نوعهای Floating point زمانی مورد استفاده قرار میگیرند که بخواهید عملیاتی انجام دهید که در آن اعداد اعشاری به کار روند. به هر حال، برای محاسبات مالی، نوع decimal بهترین انتخاب است چون با استفاده از این نوع میتوانید از ارورهای گرد کردن اعداد جلوگیری کنید.
نوع رشته(string)
یک رشته، دنبالهای از کاراکترهای متنی است. معمولا رشتهها بین دو دبل کوتیشن و با ادبیات معمول ساخته میشوند، به عنوان مثال: "این متن نمونهای از یک رشته است". در جلسه اول در مثالی که از Console.WriteLine برای ارسال خروجی به کنسول استفاده کردیم، طرز استفاده از رشتهها را مشاهده کردید.
برخی کاراکترها نیاز نیست در خروجی نشان داده شوند، اما با این حال مجبور هستید در رشتهها از آنها استفاده کنید. به همین دلیل، #C نحوه کد نویسی خاصی دارد که به واسطه آن، برنامه از نمایش کاراکترهایی که نباید در خروجی نشان داده شوند خودداری میکند.
برای مثال، برای رفتن به خط بعدی در یک متن از کاراکتر ‘\n’ استفاده میشود. در این کاراکتر، بک اسلش(\) نمادی است که به برنامه میگوید این را نمایش نده. حالا، حرفی که بعد از بک اسلش قرار میگیرد(در اینجا n) دیگر توسط برنامه به عنوان یک حرف از حروف الفبا تفسیر نمیشود، بلکه به عنوان دستور رفتن به خط بعدی تفسیر میشود.
حالا ممکن است برایتان سوال پیش بیاید که چطور میتوانید از کاراکتر بک اسلش در کد استفاده کنید. برای این منظور نیز باید از همان روش گذر از کاراکتر یا scape استفاده کرد، یعنی باید به شکل ‘\\’ کد بزنید. جدول ۳-۲ لیستی از دنبالههای معمول scape را نمایش میدهد.
جدول ۳-۲: دنبالههای scape در #C
یک ویژگی مفید دیگر رشتههای #C ادبیات یا لفظ کلمه به کلمه است، که رشته به همراه یک پیشوند @ به این شکل نمایش داده میشود: ”some string”@. این کد باعث میشود دنبالههای escape به عنوان کاراکترهای معمولی تفسیر شوند تا خوانایی کد افزایش یابد.
برای درک زیبایی و خوانایی این روش، یک عبارت آدرس و مسیر مانند این را در نظر بگیرید:
“c:\\topdir\\subdir\\subdir\\myapp.exe”
همانطور که مشاهده میکنید، بک اسلشها با روش Escape به کار رفتهاند و این امر باعث شده تا خوانایی کد خیلی بد و کم شود. میتوانید کد نویسی رشتهها را با روش کلمه به کلمه بهبود دهید، به این شکل:
”c:\topdir\subdir\subdir\myapp.exe”@
مثال بالا خیلی ساده بود، اگر رشته خیلی پیچیده و طولانی بود و استفاده از روش کلمه به کلمه باعث به وجود آمدن دبل دبل کوتیشن شود، آنگاه با مشکل جدی مواجه میشوید. برای مثال، رشته زیر را در نظر بگیرید:
“copy\”c:\\source file name with spaces.txt\”c:\\newfilename.txt”
اگر از روش کد نویسی کلمه به کلمه استفاده کنید رشته بالا به این شکل نوشته میشود:
”copy””c:\source file name with spaces.txt””c:\newfilename.txt”@
بنابراین مراقب باشید که چه موقع از چه روشی استفاده میکنید.
عملگرهای #C
نتایج با استفاده از معادلات، محاسبه میشوند. این معادلات با ترکیب متغیرها و عملگرها با یکدیگر درون یک عبارت تشکیل میشوند. جدول زیر عملگرهای مجاز ، اولویت آنها و وابستگی آنها را نشان میدهد.
جدول ۴-۲: عملگرها همراه با اولویت و وابستگی.
وابستگی چپ یعنی اینکه عملگرها از چپ به راست ارزیابی میشوند.
وابستگی راست یعنی همه عملگرها از راست به چپ عمل میکنند، مثلا عملگرهای اختصاص وقتی به کار میروند، هر چیزی در سمت راست آنها قرار داشته باشد پیش از اینکه نتیجه در متغیر سمت چپ قرار گیرد، محاسبه و ارزیابی میشوند.
اکثر عملگرها یا یکنواخت هستند یا دودویی. عملگرهای یکنواخت معادلات تک متغیره تشکیل میدهند، اما عملگرهای دودویی معادلات دو متغیره ایجاد میکنند. لیست ۲-۲ طرز استفاده از عملگرهای یکنواخت را نمایش میدهد.
using System;
class Unary
{
public static void Main()
{
int unary = 0;
int preIncrement;
int preDecrement;
int postIncrement;
int postDecrement;
int positive;
int negative;
sbyte bitNot;
bool logNot;
preIncrement = ++unary;
Console.WriteLine("pre-Increment: {0}", preIncrement);
preDecrement = --unary;
Console.WriteLine("pre-Decrement: {0}", preDecrement);
postDecrement = unary--;
Console.WriteLine("Post-Decrement: {0}", postDecrement);
postIncrement = unary++;
Console.WriteLine("Post-Increment: {0}", postIncrement);
Console.WriteLine("Final Value of Unary: {0}", unary);
positive = -postIncrement;
Console.WriteLine("Positive: {0}", positive);
negative = +postIncrement;
Console.WriteLine("Negative: {0}", negative);
bitNot = 0;
bitNot = (sbyte)(~bitNot);
Console.WriteLine("Bitwise Not: {0}", bitNot);
logNot = false;
logNot = !logNot;
Console.WriteLine("Logical Not: {0}", logNot);
}
}
در هنگام محاسبه و ارزیابی عبارات، ابتدا عملگرهای ++x و -x مقادیر فعلی خود را بازمیگردانند و سپس عملگرها اعمال میشوند. به هر حال، وقتی از عملگرهای x++ و x– استفاده میوشد، عملگر پیش از اینکه مقدار نهایی را بازگرداند، روی متغیر اعمال میشود.
در لیست ۲-۲، متغیر unary در ابتدای کار مقدار صفر میگیرد. وقتی عملگر x++ اعمال میشود، مقدار unary به ۱ افزایش مییابد و مقدار ۱ به متغیر preIncrement اختصاص مییابد. عملگر x– دوباره مقدار unary را صفر کرده و سپس مقدار را به متغیر preDecrement اختصاص میدهد.
وقتی عملگر -x اعمال میشود، مقدار unary یعنی صفر درون متغیر postDecrement قرار گرفته و سپس مقدار unary به ۱- تغییر مییابد. سپس، عملگر ++x ابتدا مقدار فعلی متغیر unary یعنی ۱- را به متغیر PostIncrement انتقال داده و سپس مقدار unary به ۰ افزایش میدهد.
متغیر bitNot در ابتدا با مقدار صفر مقداردهی میشود و عملگر ~ اعمال میشود. عملگر ~ بیتهای درون متغیر را تغییر میدهد. در این مورد، نمایش باینری عدد صفر که “00000000” است به کد باینری ۱- که "11111111" میباشد تبدیل میشود.
اگرچه وظیفه عملگر ~ تغییر بیتها است، اما عملگر نقیض منطقی(!) یک عملگر منطقی است که روی مقادیر bool اعمال میشود و true را به False و false را به true تبدیل میکند.
در مورد متغیر logNot در لیست ۲-۲، مقدار در ابتدا False است و خط بعدی عملگر نقیض منطقی(!) را اعمال میکند که در نتیجه مقدار true بازمیگردد و مقدار جدید یعنی true به متغیر logNot اختصاص مییابد. در واقع این قطعه کد، مقدار متغیر bool یعنی logNot را تغییر میدهد.
تنظیم متغیر positive کمی مشکل است. وقتی positive تنظیم میشود، مقدار متغیر postIncrement برابر با ۱- است و وقتی عملگر منفی(-) روی یک عدد منفی اعمال شود، نتیجه یک عدد مثبت خواهد بود.
یعنی اینکه مقدار متغیر positive برابر با ۱ خواهد بود، نه ۱-. عملگر منها(-) که اصلا شبیه به عملگر x– نیست، مقدار postInc را تغییر نمیدهد – فقط یک علامت منفی اضافه میکند.
عملگر بهعلاوه(+) نیز روی مقدار یک عدد اثر نمیگذارد، پس همان مقدار قبلی(یعنی ۱-) در متغیر postIncrement قرار میگیرد.
به عبارت (sbyte)(~nitNot) توجه کنید. هر عملیاتی روی نوعهای sbyte، byte، short، یا ushort انجام شود، مقادیر int بازمیگرداند. برای تخصیص نتیجه به متغیر bitNot باید از یک عملگر تبدیل یا cast(به شکل (type)) استفاده میکردیم.
در این عبارت، type همان نوعی است که شما میخواهید مقدار به آن تغییر کنید(که در این مثال، نوع مورد نظر sbyte است). عملگر cast همانند عملگرهای یکنواخت، (T(x، در جدول ۴-۲ نمایش داده میشود.
در استفاده از عملگرهای cast باید خیلی دقت کنید، چون وقتی میخواهید از یک نوع بزرگ به یک نوع کوچکتر Cast کنید، امکان از دست رفتن داده وجود دارد. اما در کل، هر موقع خواستید یک نوع کوچک را به یک نوع بزرگ cast کنید، هیچ مشکلی وجود ندارد.
چون نوع بزرگ فضای کافی برای نگهداری کل مقدار نوع کوچکتر را دارد. همچنین مراقب خطرهای cast کردن بین انواع مثبت و منفی نیز باشید. شما باید جامعیت و صحیح بودن دادههای خود را حفظ و نگهداری کنید.
خروجی کدهای لیست ۲-۲ به این صورت هستند:
pre-Increment: 1
pre-Decrement 0
Post-Decrement: 0
Post-Increment: -1
Final Value of Unary: 0
Positive: 1
Negative: -1
Bitwise Not: -1
Logical Not: true
علاوه بر عملگرهای یکنواخت، #C همچنین دارای عملگرهای باینری یا دودویی نیز میباشد که این عملگرها عبارات دو متغیری تشکیل میدهند. لیست ۳-۲ نحوه استفاده از عملگرهای دودویی را نمایش میدهد.
لیست ۳-۲: عملگرهای دودویی: Binary.cs
using System;
class Binary
{
public static void Main()
{
int x, y, result;
float floatresult;
x = 7;
y = 5;
result = x+y;
Console.WriteLine("x+y: {0}", result);
result = x-y;
Console.WriteLine("x-y: {0}", result);
result = x*y;
Console.WriteLine("x*y: {0}", result);
result = x/y;
Console.WriteLine("x/y: {0}", result);
floatresult = (float)x/(float)y;
Console.WriteLine("x/y: {0}", floatresult);
result = x%y;
Console.WriteLine("x%y: {0}", result);
result += x;
Console.WriteLine("result+=x: {0}", result);
}
}
و خروجی آن به این شکل است:
x+y: 12
x-y: 2
x*y: 35
x/y: 1
x/y: 1.4
x%y: 2
result+=x: 9
لیست ۳-۲ چندین نمونه از عملگرهای دودویی را نمایش میدهد. همانطور که انتظار میرود، نتایج جمع(+)، تفاضل(-)، ضرب(×) و تقسیم(/) نتایج ریاضی مورد انتظار و صحیحی ایجاد کردند.
متغیر floatresult یک نوع floating point است. ما خیلی با دقت متغیرهای x و y را که integerبودند را Cast کردیم تا بتوانیم یک مقدار floating point را محاسبه کنیم.
همچنین مثالی هم از عملگر باقیمانده(٪) وجود دارد. این عملگر، عملیات تقسیم را روی دو مقدار انجام داده و باقیمانده را بازمیگرداند.
آخرین عبارت، شکل دیگری از اختصاص را با عملگر عملیاتی (+=) نشان میدهد. هر دفعه که فرآیند اختصاص را با عملگر عملیاتی انجام میدهید، مثل این است که عملگر دودویی را هم در سمت چپ و هم به سمت راست عملگر اضافه کنید و نتایج را در سمت چپ قرار دهید.
این مثال را میتوانستیم به این شکل هم بنویسیم: result = result + x و مقدار بازگشتی هم دقیقا یکسان خواهد بود.
نوع آرایه
آرایه یکی دیگر از انواع دادهای میباشد، که میتوان آن را به عنوان ظرفی در نظر گرفت که دارای لیستی از موقعیتها یا خانههای حافظه برای یک نوع داده خاص است. وقتی میخواهید یک آرایه تعریف کنید باید نوع، نام، ابعاد و سایز آن را مشخص کنید.
لیست ۴-۲: عملیات روی آرایه: Array.cs
using System;
class Array
{
public static void Main()
{
int[] myInts = { 5, 10, 15 };
bool[][] myBools = new bool[2][];
myBools[0] = new bool[2];
myBools[1] = new bool[1];
double[,] myDoubles = new double[2, 2];
string[] myStrings = new string[3];
Console.WriteLine("myInts[0]: {0}, myInts[1]: {1}, myInts[2]: {2}", myInts[0], myInts[1], myInts[2]);
myBools[0][0] = true;
myBools[0][1] = false;
myBools[1][0] = true;
Console.WriteLine("myBools[0][0]: {0}, myBools[1][0]: {1}", myBools[0][0], myBools[1][0]);
myDoubles[0, 0] = 3.147;
myDoubles[0, 1] = 7.157;
myDoubles[1, 1] = 2.117;
myDoubles[1, 0] = 56.00138917;
Console.WriteLine("myDoubles[0, 0]: {0}, myDoubles[1, 0]: {1}", myDoubles[0, 0], myDoubles[1, 0]);
myStrings[0] = "Joe";
myStrings[1] = "Matt";
myStrings[2] = "Robert";
Console.WriteLine("myStrings[0]: {0}, myStrings[1]: {1}, myStrings[2]: {2}", myStrings[0], myStrings[1], myStrings[2]);
}
}
و خروجی به این صورت است:
myInts[0]: 5, myInts[1]: 10, myInts[2]: 15
myBools[0][0]: true, myBools[1][0]: true
myDoubles[0, 0]: 3.147, myDoubles[1, 0]: 56.00138917
myStrings[0]: Joe, myStrings[1]: Matt, myStrings[2]: Robert
لیست ۴-۲ روشهای استفاده متفاوت آرایه را نشان میدهد. اولین مثال، آرایه myInts است که یک آرایه تک بعدی است. این آرایه در زمان تعریف شدن، مقادیری نیز دریافت کرده است.
مثال بعدی، آرایه ناهموار myBools است. این آرایه در واقع آرایهای از آرایهها است. برای اینکه بتوانیم سایز آرایه اصلی را مشخص کنیم مجبور به استفاده از یک عملگر جدید شدیم. سپس برای هر آرایه زیرمجموعه نیز از یک عملگر جدید استفاده کردیم.
سومین مثال یک آرایه دوبعدی به نام myDoubles است. آرایهها میتوانند چند بعدی باشند و هر بعد با یک ویرگول از دیگری مجزا میشود. همچنین مقداردهی اولیه آن نیز باید با یک عملگر جدید انجام شود.
یکی از تفاوتهای بین آرایههای ناهموار مثل [][]myBools و آرایههای چند بعدی مثل [,]myDoubles این است که، یک آرایه چند بعدی برای همه عناصر در هر بعد حافظه اختصاص میدهد، در حالی که آرایه ناهموار فقط برای سایز هر آرایه در هر بعدی که تعریف میکنید، حافظه اختصاص میدهد.
اکثر مواقع، در برنامهنویسی به چندین بعد نیاز خواهید داشت و میتوانید به راحتی از آرایههای چند بعدی استفاده کنید، اما فقط در شرایط خیلی خاصی میتوانید از آرایه ناهموار استفاده کنید، یعنی زمانی که امکان ذخیره میزان زیادی از حافظه با مشخص سازی دقیق سایزهای آرایهها در هر بعد وجود داشته باشد.
در آخر، آرایههای تک بعدی از نوعهای رشته مانند آرایه myStrings نیز داریم.
در هر مورد، مشاهده میکنید که عناصر درون آرایهها با شناسایی شاخص integer برای آیتمی که قصد اشاره به آن را دارید، مورد دسترسی قرار میگیرند. سایزهای آرایهها میتوانند دارای مقادیر int باشند. شاخصهای آرایهها از صفر آغاز میشوند.
خلاصه
متغیر یک عنصر شناسایی کننده با یک نوع میباشد که مقداری از آن نوع را درون خود نگهداری میکند. نوعهای ساده عبارتاند از integralها، floating pointها، Decimal و bool. زبان #C دارای چندین عملگر ریاضی و منطقی است که در نوشتن معادلات مورد استفاده قرار میگیرند.
#C همچنین دارای انواع آرایههای تک بعدی، چند بعدی و ناهموار نیز میباشد.
در این جلسه، یاد گرفتید که چگونه میتوانید یک عبارت خبری یا دستوری بنویسید و برنامهای نوشتید که به صورت خطی از آغاز تا انتها پیش برود.
به هر حال، این برنامههای ساده چندان مفید نیستند، چون شما باید بتوانید تصمیمگیریهای سخت کنید و بسته به شرایط مختلفی که در آنها قرار میگیرد باید قطعه کدهای متفاوتی نیز بنویسید.
در جلسه سوم در مورد چند شعبه کردن منطق کد نویسی صحبت میکنیم تا بتوانید تصمیمگیریهای عالی و قدرتمند انجام دهید.
منبع: C#-station
جلسه بعد جلسه قبل
آخرین مطالب

دستور UPDATE در SQL Server برای تغییر دادههای موجود در یک جدول، از دستور UPDATE به شکل زیر استفاده ...

دستور DROP TABLE در SQL Server گاهی، لازم است یک جدول که دیگر استفادهای ندارد را حذف کنید. برای ...

بخش اول از آخرین مبحث دوره جامع آموزش SQL Server در جلسه قبلی بررسی شد. این مبحث که ...
دیدگاه خود را درباره این پست بنویسید