LESSON 1
شروع کار با #C
در اين درس با ارائه چند برنامه و مثال ساده به طرز کار زبان #C ميپردازيم. اهداف اين درس عبارتند از :
• فهم ساختار پايهاي يک برنامه #C
• آشنايي با Namespace
• آشنايي با کلاس class( )
• آشنايي با عملکرد متد main( )
• آشنايي با ورودي/خروجي يا I/O
ليست 1-1، يک برنامة ساده با عنوان Welcome در زبان #C
Code |
// Namespace
اعلان |
برنامة ليست 1-1 داراي 4 پارامتر اصلي است، اعلان Namespace، کلاس، متد main( ) و يک دستور زبان #C.
در همين جا بايد به يک نکته اشاره کنم، براي زبان #C همانند بيشتر زبانهاي برنامهسازي دو نوع کامپايلر وجود دارد. يک نوع کامپايلر که به کامپايلر Command Line معروف است و نوع ديگر کامپايلر Visual است. کامپايلرهاي Command Line محيطي شبيه به محيط DOS دارند و با دادن يک سري دستورات به اجرا در ميآيند. کامپايلرهاي Visual محيطي همانند ويندوز دارند که با دارا بودن محيط گرافيکي و ابزارهاي خاص، برنامهنويس را در امر برنامهسازي کمک ميکنند. از نمونههاي هر يک از کامپايلرها، ميتوان به Microsoft C# Command Line Compiler که يک کامپايلر Command Line و Microsoft Visual C# که يک کامپايلر Visual است، اشاره کرد. البته در حال حاضر بيشتر از کامپايلرهاي ويژوال استفاده ميشود.
من سعي ميکنم در آينده به توضيح محيط Visual C# و Visual Studio.Net بپردازم. اما فعلاً براي اجراي برنامهها ميتوانيد از Visual Studio.Net استفاده کنيد. پس از نصب آن، وارد محيط #C شده و در قسمت انتخاب برنامة جديد گزينة Console را جهت اجراي برنامهها انتخاب نماييد.
براي اين درس، فعلاً به توضيحات بيشتر دربارة محيط ويژوال نميپردازم اما در آينده به توضيح کامل محيط Visual Studio.Net خواهم پرداخت.
براي اجراي کد بالا در صورتيکه از محيط ويژوال استفاده ميکنيد بايد بر روي دکمة Run کليک کنيد و در صورتيکه کامپايلر Command Line داريد با دستور زير ميتوانيد برنامه را اجرا کنيد : csc Welcome.cs
پس از اجراي برنامه، کامپايلر براي شما يک فايل قابل اجرا(Executable) تحت نام Welcome.exe توليد ميکند.
نکته : در صورتيکه از Visual Studio.Net(VS.Net) استفاده کنيد، پس از اجراي برنامه، يک صفحه براي نمايش خروجي به سرعت باز شده و بسته ميشود و شما قادر به ديدن خروخي نخواهيد بود. براي اينکه بتوانيد خروجي برنامه را ببينيد، در انتهاي برنامه دستور زير را وارد نماييد :
Code |
Console.ReadLine( ); |
استفاده از اين دستور باعث ميشود تا برنامه منتظر دريافت يک ورودي از کاربر بماند، که در اين حالت شما ميتوانيد خروجي برنامه خود را ديده و سپس با زدن کليد Enter برنامه را خاتمه دهيد.
نکتة ديگري که در مورد زبان برنامهنويسي #C بايد مورد توجه قرار دهيد اينست که اين زبان Case Sensitive است، بدين معنا که به حروف کوچک و بزرگ حساس است يعني براي مثال ReadLine با readLine متفاوت است به طوريکه اولي جزو دستورات زبان #C و دومي به عنوان يک نام براي متغير يا يک تابع که از طرف کاربر تعريف شده است در نظر گرفته ميشود.
اعلان Namespace به سيستم اعلان مينمايد که شما از توابع کتابخانهاي System جهت اجراي برنامهها خود استفاده مينماييد. دستوراتي مانند WriteLine و ReadLine جزو توابع کتابخانهاي System ميباشند. اغلب دستورات و توابع مهم و کليدي استفاده از کنسول ورودي/خروجي در اين کتابخانه ميباشد. در صورتيکه در ابتداي برنامه از using System استفاده نکنيد، يابد در ابتداي هر يک از دستورات برنامه که مربوط اين کتابخانه است، از کلمة System استفاده نماييد. بعنوان مثال در صورت عدم استفاده از using System بايد از دستور System.Console. writeLine( ) به جاي Console. writeLine( ) استفاده نماييد.
تعريف کلاس،Class Welcome CSS، شامل تعريف دادهها(متغيرها) و متدها جهت اجراي برنامه است. يک کلاس، جزو معدود عناصر زبان #C است که بوسيلة آن ميتوان به ايجاد يک شي (Object) از قبيل واسط ها (Interfaces) و ساختارها(Structures)، پرداخت. توضيحات بيشتر در اين زمينه در درسهاي آينده ذکر ميشوند. در اين برنامه کلاس هيچ داده و متغيري ندارد و تنها شامل يک متد است. اين متد، رفتار(Behavior) اين کلاس را مشخص ميکند.
متد درون اين کلاس بيان ميکند که اين کلاس چه کاري را پس از اجرا شدن انجام خواهد داد. کلمة کليدي main( ) که نام متد اين کلاس نيز ميباشد جزو کلمات رزرو شده زبان #C است که مشخص ميکند برنامه از کجا بايد آغاز به کار نمايد. وجود متدmain( ) در تمامي برنامههاي اجرايي ضروري است. در صورتيکه يک برنامه حاوي متد main( ) نباشد بعنوان توابع سيستمي همانند dll هاي ويندوز در نظر گرفته ميشود.
قبل از کلمة main( ) کلمه ديگري با عنوان static آورده شده است. اين کلمه در اصطلاح Modifier ميگويند. استفاده از static براي متد main( ) بيان ميدارد که اين متد تنها در در همين کلاس قابل اجراست و هيچ نمونهاي (Instance) ديگري از روي آن قابل اجرا نميباشد. استفاده از static براي متد main( ) الزامي است زيرا در ابتداي آغاز برنامه هيچ نمونهاي از هيچ کلاس و شياي موجود نميباشد و تنها متدmain( ) است که اجرا ميشود. (در صورتيکه با برخي اصطلاحات اين متن از قبيل کلاس، شي، متد و نمونه آشنايي نداريد، اين به دليل آنست که اين مفاهيم جزو مفاهيم اولية برنامهنويسي شيگرا (OOP) هستند. سعي ميکنم در درسهاي آينده به توضيح اين مفاهيم نيز بپردازم، ولي فعلاً در همين حد کافي ميباشد.)
هر متد بايد داراي يک مقدار بازگشتي باشد، يعني بايد مقداري را به سيستم بازگرداند، در اين مثال نوع بازگشتي void تعزيف شده است که نشان دهنده آنست که اين متد هيچ مقداري را باز نميگرداند يا به عبارت بهتر خروجي ندارد. همچنين هر متد ميتواند داراي پارامترهايي نيز باشد که ليست پارامترهاي آن در داخل پرانتزهاي جلوي آن قرار ميگيرد. براي سادگي کار در اين برنامه متد ما داراي هيچ پارامتري نيست ولي در ادامة همين درس به معرفي پارامترها نيز ميپردازم.
متد main( ) رفتار و عمل خود را بوسيله Console.WriteLine(…) مشخص مينمايد. Console کلاسي در System است و writeLine( ) متدي در کلاس Console. در زبان #C از اپراتور "." (نقطه dot) جهت جداسازي زيرروتينها و زيرقسمتها استفاده ميکنيم. همانطور که ملاحظه ميکنيد چون writeLine( ) يک متد درون کلاس Console است به همين جهت از "." جهت جداسازي آن استفاده کردهايم.
در زبان C# ، براي قرار دادن توضيحات در کد برنامه از // استفاده ميکنيم. بدين معنا که کامپايلر در هنگام اجراي برنامه توجهي به اين توضيحات نميکند و اين توضيحات تنها به منظور بالا بردن خوانايي متن و جهت و کمک به فهم بهتر برنامه قرار ميگيرند. استفاده از // تنها در مواردي کاربرد دارد که توضيحات شما بيش از يک خط نباشد. در صورت تمايل براي استفاده از توضيحات چند خطي بايد در ابتداي شروع توضيحات از /* و در انتها آن از */ استفاده نماييد. در اين حالت تمامي مطالبي که بين /* */ قرار ميگيرند به عنوان توضيحات (Comments) در نظر گرفته ميشوند.
تمامي دستورات (Statements) با ";"، سمي کولون، پايان مييابند. کلاسها و متدها با } آغاز شده و با { خاتمه مييابند. تمامي دستورات بين { } يک بلوک را ميسازند.
بسياري از برنامهها از کاربر ورودي دريافت ميکنند. انواع گوناگوني از اين وروديها ميتوانند به عنوان پارامتري براي متد main( ) در نظر گرفته شوند. ليست 2-1 برنامهاي را نشان ميدهد نام کاربر را از ورودي دريافت کرده و آن را بر روي صفحه نمايش ميدهد. اين ورودي به صورت پارامتري براي متد main( ) در نظر گرفته شده است.
ليست 2-1 : برنامهاي که ورودي را از کاربر، بعنوان پارامتر main( ) ، دريافت ميکند.
Code |
// Namespace
اعلان |
توجه داشته باشيد که اين برنامه، ورودي را به صورت Command-Line دريافت ميکند و در هنگام اجراي برنامه بايد ورودي را در Command-Line وارد نماييد. در صورتيکه ورودي را وارد ننماييد برنامه دچار مشکل شده و متوقف خواهد شد.
همان طور که در ليست 2-1 مشاهده مينماييد، پارامتر متد main( ) با عنوان args مشخص شده است. با استفاده از اين نام در داخل متد ميتوان آن استفاده نمود. نوع اين پارامتر از نوع آرايهاي از نوع رشته (string[ ]) در نظر گرفته شده است. انواع(types) و آرايهها را در درسهاي بعدي بررسي ميکنيم. فعلاً بدانيد که آرايه رشتهاي جهت نگهداري چندين کاراکتر مورد استفاده قرار ميگيرد. [ ] مشخص کننده آرايه هستند که مانند يک ليست عمل ميکند.
همانطور که ملاحظه ميکنيد در اين برنامه دو دستور Console.WriteLine(…) وجود دارد که اولين دستور مقداري با دستور دوم متفاوت است. همانطور که مشاهده ميکنيد داخل دستور Console.WriteLine(…) عبارتي به شکل {0} وجود دارد. اين آرگومان، نشان ميدهد که به جاي آن چه مقداري بايد نمايش داده شود که در اين جا args[0] نشان داده ميشود. عبارتي که داخل " " قرار دارد عيناً در خروجي نمايش داده ميشود، به جاي آرگومان {0}، مقداري که پس از " قرار دارد، قرار ميگيرد. حال به آرگومان بعدي يعني args[0] توجه کنيد. مقدار صفر داخل [ ] نشان ميدهد که کدام عنصر از آرايه مورد استفاده است. در #C انديس آرايه از صفر شروع ميشود به همين جهت براي دسترسي به اولين عنصر آرايه بايد از انديس صفر استفاده کنيم.(همانطور که قبلاً نيز کفتم آرايهها را در درسهاي آينده توضيح خواهم داد، هدف از اين درس تنها آشنايي با #C است.!)
مجدداً به آرگومان {0} بازگرديم. اين آرگومان نشان مي دهد که يک مقدار بايد در رشته خروجي قرار گيرد، اين مقدار همان args[0] است. اگر شما اين برنامه را از طريق Command-Line اجرا نماييد خروجي شبيه به زير خواهيد گرفت :
Code |
Hello!, Meysam! Welcome to C# Persian Tutorial! |
همان گونه که ميبينيد، پس از اجراي برنامه نام شما که از طريق
Command-Line
آنرا وارد نمودهايد در خروجي ظاهر ميشود. استفاده از آرگومان {n}،
که در آن n
يک مقدار عددي است، جهت فرمت دادن به متن خروجي است که بر روي صفحه به نمايش در
ميآيد. مقدار n
از صفر آغاز شده و به ترتيب افزايش ميبايد. به مثال زير توجه کنيد :
Console.WriteLine("Hello! ,{0} ,{1}, {2}",args[0],args[1],args[2]);
اين خط از برنامه سه مقدار args[0],args[1],args[2] را در خروجي به ترتيب نمايش ميدهد. ملاحظه مينماييد که چون 3 مقدار را ميخواهيم نمايش دهيم، سه بار از آرگومان {n} استفاده کردهايم و هر بار يک واحد به مقدار قبلي افزودهايم. در آينده بيشتر با اين مفاهيم آشنا ميشويم.
مطلبي که بايد در مورد ليست 2-1 به آن توجه شود آنست که اين برنامه تنها از طريق Command-Lineقابل اجراست و در صورتيکه کاربر از اين مطلب که برنامه بايد داراي ورودي به صورت Command-Line باشد، بي اطلاع باشد و ورودي را در Command-Line وارد نکند، برنامه متوقف شده و اجرا نميشود. پس براي رفع چنين مشکلي بايد از روش بهتري جهت دريافت ورودي از کاربر استفاده کرد.
ليست 3-1 : يک برنامه که قابليت محاوره با کاربر را دارد.
Code |
// Namespace
اعلان |
همانطوريکه در اين برنامه ديده مي شود، متد ( )main داراي پارامتر نيست. در عوض يک خط به متن برنامه ليست 2-1 اضافه شده است. در اولين خط از اين برنامه، متني با عنوان اينکه نام شما چيست؟ بر روي صفحه ظاهر ميشود. سپس در خط بعدي پس از نوشتن کلمه Hello, ، برنامه منتظر دريافت ورودي از کاربر ميشود. بدين معني که اين بار تا زمانيکه کاربر متني را به عنوان نام خود وارد نکند اجراي برنامه به پيش نخواهد رفت و خط بعدي اجرا نميشود. اين برنامه روش ايجاد ارتباط از طريق برنامه با کاربر را نمايش ميدهد. در اين مثال کاربر دقيقاً متوجه ميشود که چه زماني بايد اطلاعات را وارد نمايد و اين اطلاعات چه بايد باشد در حاليکه در مثال قبل چنين نبود. همانگونه که ميبينيد در اين برنامه آرگومان {0} مستقيماً از طريق دستور Console.ReadLine( ) دريافت ميشود و بلافاصله در خروجي نمايش داده ميشود. دستور ReadLine( ) نيز يکي از متدهاي کلاس Console است که بوسيله آن رشته ورودي خوانده ميشود.
خروجي برنامه فوق به شکل زير است :
Code |
What is your name?: |
(سپس برنامه منتظر دريافت متني از ورودي توسط کاربر ميماند)
(پس از اينکه کاربر رشتهاي را وارد کرد و کليدEnter را فشار داد، متن زير نمايش داده ميشود.)
Code |
Hello, Ahmad! |
(سپس اجراي برنامه به دستور بعدي منتقل ميشود)
Welcome to the C# Persian Tutorial!
خروجي کامل برنامه :
What is your name?:
Hello, Meysam! Welcome to the C# Persian Tutorial!
توجه کنيد که ReadLine( ) به عنوان يک متد، مقداري را به سيستم بازميگرداند. اين مقدار در اين برنامه به آرگومان {0} برگردانده ميشود. اين خط از برنامه را ميتوان طور ديگري هم نوشت :
Code |
string
myName=Console.ReadLine( );
|
در اين حالت ما يک متغير از نوع رشته با نام myName تعريف کردهايم که مقدار ورودي در آن ذخيره ميشود و سپس از اين مقدار به عنوان مقداري که {0} ميپذيرد استفاده کردهايم.
خلاصــه درس
در اين درس آموختيد که ساختار کلي يک برنامه #C چگونه است. هر برنامه #C از يک کلاس اصلي تشکيل ميشود که اين کلاس شامل دادهها و متغيرها و متدهايي ميباشد. متد آغازين برنامه که برنامه با آن شروع به اجرا ميکند، متد main( ) است. با استفاده از توابع کتابخانهاي مينوان به کلاسها و متدهاي #C دسترسي پيدا کرد. از جمله اين توابع System بود که يکي از کلاسهاي آن Console و چند متد اين کلاس، متدهاي writeLine( ) و ReadLine( ) بودند.
LESSON 2
عبارات، انواع و متغيرها در#C
در اين درس به معرفي عبارات، انواع و متغيرها در زبان #C ميپردازيم. هدف از اين درس بررسي موارد زير است :
• آشنايي با متغيرها
• فراگيري انواع(Types) ابتدايي در #C
• فراگيري و درک عبارات(Expressions) در #C
• فراگيري نوع رشتهاي(String) در زبان #C
• فراگيري چگونگي استفاده از آرايهها(Arrays) در زبان #C
متغيرها، به بيان بسيار ساده، مکانهايي جهت ذخيره اطلاعات هستند. شما اطلاعاتي را در يک متغير قرار ميدهيد و از اين اطلاعات بوسيله متغير در عبارات C# استفاده مينماييد. کنترل نوع اطلاعات ذخيره شده در متغيرها بوسيله تعيين کردن نوع براي هر متغير صورت ميپذيرد.
#C زباني بسيار وابسته به انواع است، بطوريکه تمامي عملياتي که بر روي دادهها و متغيرها در اين زبان انجام ميگيرد با دانستن نوع آن متغير ميسر ميباشد. قوانيني نيز براي تعيين اينکه چه عملياتي بر روي چه متغيري انجام شود نيز وجود دارد.(بسته به نوع متغير)
انوع ابتدايي زبان #C شامل : يک نوع منطقي(Boolean) و سه نوع عددي اعداد صحيح(integer)، اعداد اعشاري(Floating points) و اعداد دسيمال(Decimal) ميباشد.(به انواع Boolean از اينرو منطقي ميگوييم که تنها داراي دو حالت منطقي صحيح(True) و يا غلط(False) ميباشند.)
مثال 1 – نشان دادن مقادير منطقي (Boolean)
Code |
using System; |
در اين مثال، مقادير منطقي متغيرهاي Boolean به عنوان قسمتي از جمله در خروجي نمايش داده ميشوند. متغيرهاي bool تنها ميتوانند يکي از دو مقدار true يا false را داشته باشند، يعني همانند برخي از زبانهاي برنامهسازي مشابه، مانند C و يا ++C، مقدار عددي نميپذيرند، زيرا همانگونه که ميدانيد در اين دو زبان هر مقدار عددي صحيح مثبت بغير از صفر به عنوان true و عدد صفر به عنوان false در نظر گرفته ميشود و در حقيقت نوع bool در اين دو زبان نوعي integer ميباشند. اما در زبان #C انواع bool يکي از دو مقدار true يا false را ميپذيرند. خروجي برنامه بالا به صورت زير است :
Code |
It is True that C# Persian
provides C# programming language content. |
ليست زير تمامي انواع عددي صحيح C#، اندازه آنها و رنج قابل قبول آنها را نشان ميدهد.
نوع :sbyte
اندازه بر حسب بايت : 8
محدوده قابل قبول: 128- تا 127
نوع :byte
اندازه بر حسب بايت : 8
محدوده قابل قبول: 0 تا 255
نوع :short
اندازه بر حسب بايت : 16
محدوده قابل قبول: 32768- تا 32767
نوع :ushort
اندازه بر حسب بايت : 16
محدوده قابل قبول: 0 تا 65535
نوع :int
اندازه بر حسب بايت : 32
محدوده قابل قبول: 2147483648- تا 2147483647
نوع :uint
اندازه بر حسب بايت : 32
محدوده قابل قبول: 0 تا 4294967295
نوع :long
اندازه بر حسب بايت : 64
محدوده قابل قبول: 9223372036854775808- تا 9223372036854775807
نوع :ulong
اندازه بر حسب بايت : 64
محدوده قابل قبول: 0 تا 18446744073709551615
از اين انواع براي محاسبات عددي استفاده ميگردد. يک نوع ديگر را نيز ميتوان در اين جدول اضافه نمود و آن نوع char است. هر چند شايد از نظر بسياري از دوستاني که با زبانهاي ديگر برنامهسازي کار کردهاند اين تقسيم بندي غلط به نظر آيد، اما بايد گفت که در زبان #C نوع char نيز نوع خاصي از انواع عددي است که رنجي بين صفر تا 65535 دارد و اندازه آن نيز 16 بيتي است، اما به جاي نمايش دادن مقادير عددي تنها ميتواند بيان کننده يک کاراکتر باشد. در آينده در اين مورد بيشتر توضيح خواهم داد.
ليست زير تمامي انواع عددي اعشاري زبان #C را نمايش ميدهد.
نوع :float
اندازه بر حسب بايت : 32
دقت: 7 رقم
محدوده قابل قبول: 3.4×10 به توان 38 تا 1.5*10 به توان 45-
نوع :double
اندازه بر حسب بايت : 64
دقت: 16-15 رقم
محدوده قابل قبول: 1.7×10 به توان 308 تا 5*10 به توان 324-
نوع :decimal
اندازه بر حسب بايت : 128
دقت: 28-29 رقم دسيمال
محدوده قابل قبول: 7.9×10 به توان 28 تا 1.0*10 به توان 28-
انواعي از نوع floating point هنگامي استفاده ميشوند که محاسبات عددي به دقتهاي اعشاري نياز داشته باشند. همچنين براي منظورهاي تجاري استفاده از نوع decimal بهترين گزينه است. اين نوع تنها در زبان #C وجود دارد و در زبانهاي مشابه به آن نظير Java چنين نوعي در نظر گرفته نشده است.
در يک زبان برنامهسازي نتايج بوسيله ايجاد يک سري عبارت توليد ميگردند. عبارات از ترکيب متغيرها و عملگرها در دستورالعملهاي يک زبان ايجاد ميگردند.(توجه نماييد که عبارت معادل expression و دستورالعمل معادل statement ميباشد که ايندو با يکديگر متفاوت ميباشند.) ليست زير عملگرهاي موجود در زبان #C، حق تقدم آنها و شرکتپذيري آنها را نشان ميدهد.
نوع عمل :عمليات ابتدايي
عملگر(ها): (x) x.y f(x) a[x] x++ x--
new type of size of checked unchecked
شرکتپذيري:از چپ
نوع عمل :عمليات يکاني
عملگر(ها): + - ! ~ ++x --x (T)x
شرکتپذيري:از چپ
نوع عمل :عمليات جمعي
عملگر(ها): - +
شرکتپذيري:از چپ
نوع عمل :عمل شيفت
عملگر(ها): << >>
شرکتپذيري:از چپ
نوع عمل :عمليات رابطهاي
عملگر(ها): < > <= >= is
شرکتپذيري:از چپ
نوع عمل :عمليات تساوي
عملگر(ها): == !=
شرکتپذيري:از راست
نوع عمل :عمل AND منطقي
عملگر(ها): &
شرکتپذيري:از چپ
نوع عمل :عمل OR منطقي
عملگر(ها): |
شرکتپذيري:از چپ
نوع عمل :عمل XOR منطقي
عملگر(ها): ^
شرکتپذيري:از چپ
نوع عمل :عمل AND شرطي
عملگر(ها): &&
شرکتپذيري:از چپ
نوع عمل :عمل OR شرطي
عملگر(ها): ||
شرکتپذيري:از چپ
نوع عمل :عمل انتساب
عملگر(ها): = *= /= %= += -= <<= >>= &= ^= |=
شرکتپذيري:از راست
نوع عمل :عمل شرطي
عملگر(ها): ?:
شرکتپذيري:از چپ
شرکتپذيري از چپ بدين معناست که عمليات از چپ به راست محاسبه ميشوند. شرکتپذيري از راست بدين معناست که تمامي محاسبات از راست به چپ صورت ميگيرند. به عنوان مثال در يک عمل تساوي، ابتدا عبارات سمت راست تساوي محاسبه شده و سپس نتيجه به متغير سمت چپ تساوي تخصيص داده ميشود.
مثال 2- عملگرهاي يکاني (Unary)
Code |
using System; |
به هنگام محاسبه عبارات، دو عملگر x++ و x—(که در اينجا کاراکتر x بيان کننده آن است که عملگرهاي ++ و – در جلوي عملوند قرار ميگيرند post-increment و post-decrement) ابتدا مقدار فعلي عملوند (operand) خود را باز ميگرداند و سپس به عملوند خود يک واحد اضافه کرده يا از آن يک واحد ميکاهند. عملگر ++ يک واحد به عملوند خود اضافه ميکند و عملگر – يک واحد از عملوند خود ميکاهد. بدين ترتيب عبارت x++ معادل است با عبارت x=x+1 و يا x+=1 اما همانطور که گفته شد بايد توجه داشته باشيد که اين عملگرها(++ و --) ابتدا مقدار فعلي عملوند خود را برگشت ميدهند و سپس عمل خود را روي آنها انجام ميدهند. بدين معني که در عبارت x=y++ در صورتيکه در ابتداي اجراي برنامه مقدار x=0 و y=1 باشد، در اولين اجراي برنامه مقدار x برابر با 1 يعني مقدار y ميشود و سپس به متغير y يک واحد افزوده ميشود، در صورتيکه اگر اين عبارت را بصورت x=++y بنويسيم در اولين اجراي برنامه، ابتدا به مقدار متغير y يک واحد افزوده ميشود و سپس اين مقدار به متغير x تخصيص داده ميشود که در اين حالت مقدار متغير x برابر با 2 ميشود.(در مورد عملگر – نيز چنين است.) پس با اين توضيح ميتوان گفت که دو عملگر ++x و –x ابتدا به عملوند خود يک واحد اضافه يا يک واحد از آن کم ميکنند و سپس مقدار آنها را باز ميگردانند.
در مثال 2، مقدار متغير unary در قسمت اعلان برابر با 0 قرار گرفته است. هنگاميکه از عملگر ++x استفاده ميکنيم، به مقدار متغير unary يک واحد افزوده ميشود و مقدارش برابر با 1 ميگردد و سپس اين مقدار، يعني 1، به متغير preIncrement تخصيص داده ميشود. عملگر –x مقدار متغير unary را به 0 باز ميگرداند و سپس اين مقدار را به متغير preDecrement نسبت ميدهد.
هنگاميکه از عملگر x-- استفاده ميشود، مقدار متغير unary، يا همان مقدار صفر، به متغير postDecrement تخصيص داده ميشود و سپس از مقدار متغير unary يک واحد کم شده و مقدار اين متغير به 1- تغيير ميکند. سپس عملگر x++ مقدار متغير unary، يعني همان 1-، را به متغير postIncrement تخصيص ميدهد و سپس يک واحد به مقدار متغير unary ميافزايد تا مقدار اين متغير برابر با 0 (صفر) شود.
مقدار متغير bitNot در هنگام اعلان برابر با صفر است. با استفاده از عملگر نقيض بيتي (~) (يا عملگر مکملگيري) متغير bitNot بعنوان يک بايت در نظر گرفته ميشود و مقدار آن منفي يا نقيض ميشود. در عمليات بيتي نقيض بدين معناست که تمامي يکها به صفر و تمامي صفرها به يک تبديل شوند. در اين حالت نمايش باينري عدد صفر يا همان 00000000 به نقيض آن يعني 11111111 تبديل ميگردد.
در اين مثال به عبارت (sbyte)(~bitNot) توجه نماييد. هر عملي که بر روي انواع short،unshort ، byte و sbyte انجام شود، مقداري از نوع int را باز ميگرداند. بمنظور اينکه بتوانيم نتيجه دلخواه را به متغير bitNot تخصيص دهيم بايد از فرمت (Type) operator استفاده نماييم که در آن Type نوعي است ميخواهيم نتيجه ما به آن نوع تبديل شود و operator عملي است که بر روي متغير صورت ميپذيرد. به بيان ديگر چون ميخواهيم مقدار متغير bitNot بصورت بيتي در نظر گرفته شود، پس بايد نتيجه عمل ما بصورت بيتي در آن ذخيره شود که استفاده از نوع sbyte باعث ميشود تا نتيجه به فرم بيتي (يا بايتي) در متغير ما ذخيره شود. بايد توجه نماييد که استفاده از فرمت (Type) يا در اصطلاح عمل Casting، در مواقعي که ميخواهيم تغييري از يک نوع بزرگتر به نوع کوچکتر ايجاد نماييم، مورد استفاده قرار گيرد، چرا که در اين حالات ممکن است با از دست دادن اطلاعات مواجه باشيم. در اين مثال چون ميخواهيم نوع بزرگتر int را به(32 بيتي) به نوع کوچکتر sbyte (8 بيتي) تبديل نماييم، بدين منظور بايد بطور صريح از عمل Casting استفاده نماييم تا اطلاعاتي در اين تبديل از بين نرود. در مورد تبديل انواع کوچکتر به انواع بزرگتر(مثلا تبديل sbyte به int) نيازي به استفاده از عمل Casting نيست چرا که امکان از بين رفتن اطلاعات وجود ندارد. در ضمن بايد به يک نکته مهم توجه نماييد و آن تبديل انواع علامتدار(Signed) و بدون علامت(Unsigned) به يکديگر است. در اين حالت خطر بسيار مهمي دادههاي شما را تهديد مينمايد. بحث در مورد مسائل پيچيدهتر در مورد تبديل انواع علامتدار و و بدون علامت به يکديگر در اينجا نميگنجد و سعي ميکنم تا آنها را در مطالب بعدي و در جاي لازم مورد بحث و بررسي قرار دهم.(در صورتيکه برخي از مطالب اين قسمتها براي شما به خوبي قابل درک نيست، نگران نباشيد چراکه در آينده در مثالهايي که خواهيد ديد تمامي اين مطالب را در عمل نيز حس کرده و با آنها آشنا خواهيد شد.)
عملگر بعدي که در اين برنامه مورد استفاده قرار گرفته است، عملگر نقيض منطقي يا همان "!" است که امکان تغيير مقدار يک متغير Boolean را از true به false و بالعکس را فراهم ميآورد. در مثال بالا(مثال شماره 2) مقدار متغير logNot پس از استفاده از عملگر "!" از false به true تغيير کرده است. با توجه به توضيحات اخير خروجي زير از برنامه مثال 2 مورد انتظار است :
Code |
Pre-Increment: 1 |
مثال 3 – عملگرهاي دوتايي
Code |
using System; |
خروجي اين برنامه به فرم زير است :
Code |
x+y: 12 |
مثال 3 استفادههاي متفاوتي از عملگرهاي دوتايي را نشان ميدهد.(منظور از عملگر دوتايي، عملگري است که داراي دو عملوند ميباشد مانند عملگر جمع "+"). بسياري از عملگرهاي مورد استفاده در اين مثال عملگرهاي رياضي هستند و نتيجه عمل آنها مشابه عملي است که از آنها در رياضيات ديدهايد. از نمونه اين عملگرها ميتوان به عملگرهاي جمع "+"، تفريق "-"، ضرب "*" و تقسيم "/" اشاره نمود.
متغير floatResult از نوع اعشاري يا float تعريف شده است. در اين مثال نيز صريحاً از عمل Casting جهت اسفاده از دو متغير x و y که از نوع int هستند، براي انجام عملي که نتيجهاش از نوع float است، استفاده کردهايم.
در اين مثال از عملگر "%" نيز استفاده کردهايم. اين عملگر در عمليات تقسيم کاربرد دارد و باقيمانده تقسيم را برميگرداند. يعني دو عملوند خود را بر يکديگر تقسيم ميکند و باقيمانده اين تقسيم را برميگرداند.
در اين مثال همچنين فرم جديدي از عمل انتساب را بصورت result+=x مشاهده مينماييد. استفاده از عملگرهاي انتسابي که خود ترکيبي از دو عملگر هستند، جهت سهولت در امر برنامهنويسي مورد استفاده قرار ميگيرند. عبارت فوق معادل result = result+x ميباشد. يعني مقدار قبلي متغير result با مقدار متغير x جمع ميشود و نتيجه در متغير result قرار ميگيرد.
يکي ديگر از انواعي که تا کنون با آن سر و کار داشتهايم نوع رشتهاي (string) است. يک رشته، از قرار گرفتن تعدادي کاراکتر در کنار يکديگر که داخل يک زوج کوتيشن " " قرار گرفتهاند، ايجاد ميگردد. بعنوان مثال "Hi This is a string type". در اعلان متغيرها نيز در صورت تعريف متغيري از نوع رشتهاي، در صورت نياز به تخصيص مقدار به آن، حتماً کاراکترهايي که ميخواهيم بعنوان يک رشته به متغيرمان نسبت دهيم را بايد داخل يک زوج کوتيشن " " قرار دهيم. به مثال زير توجه نماييد.
Code |
string Name; |
همانطور که در اين مثال مشاهده مينماييد، متغيري از نوع رشتهاي تحت نام Name تعريف شده است و سپس در جايي از برنامه که نياز به تخصيص مقدار براي اين متغير وجود دارد، عبارت مورد نظر را داخل دو کوتيشن قرار داده و به متغير خود تخصيص دادهايم. رشتهها از پر کاربرد ترين انواع در زبانهاي برنامهسازي جهت ايجاد ارتباط با کاربر و دريافت اطلاعات از کاربر ميباشند.(همانطور که در درس قبل اول نيز گفته شد، دستور Console.ReadLine( )يک رشته را از ورودي دريافت مينمايد.) در مثالهايي که در طي درسهاي اين سايت خواهيد ديد، نمونههاي بسياري از کاربرد انواع مختلف و نيز نوع رشتهاي را خواهيد ديد.
آرايهها (Arrays)
يکي ديگر از انواع دادهاي در زبان #C، آرايهها (Arrays) ميباشند. يک آرايه را به عنوان مخزني براي نگهداري اطلاعات در نظر ميگيريم که داراي ليستي از محلهايي است که در آنها اطلاعات ذخيره شده است و از طريق اين ليست ميتوان به اطلاعات آنها دسترسي پيدا نمود. به هنگام اعلان آرايهها بايد نوع، اندازه و تعداد بعد آنها را نيز معين نمود.
مثال 4- آرايهها و عمليات بر روي آنها
Code |
using System; |
خروجي مثال 4 بصورت زير است :
Code |
myInts[0]: 5, myInts[1]:
10, myInts[2]: 15 |
در اين مثال انواع مختلفي از آرايهها اعلان شدهاند. در ابتدا يک آرايه تک بعدي، سپس آرايهاي دندانهدار و در نهايت نيز يک آرايه دو بعدي در اين مثال اعلان شدهاند.
اولين اعلان در اين برنامه مربوط به اعلان آرايه تک بعدي myInts ميباشد که از نوع int بوده و داراي 3 عضو ميباشد که تعداد اين اعضا با اعلان چند مقدار در داخل { } معين شده است. همانطور که از اين اعلان دريافت ميشود، آرايه تک بعدي بصورت زير تعريف ميشود :
Code |
type[ ] arrayName; |
که در آن type نوع آرايه و arrayName نام آرايه ايست که تعريف مينمائيم.
اما در ابتدا گفته شد که به هنگام اعلان آرايهها اندازه آنها نيز بايد مشخص شود. براي تعيين اندازه آرايه، يعني تعدا عناصري که آرايه در خود جاي ميدهد، ميتوان به چند روش عمل نمود. اولين و سادهترين روش که در اين مثال نيز آورده شده است، تخصيص مقاديري به آرايه در داخل يک زوج { } است. بسته به نوع آرايه، تعداد عناصري که داخل اين زوج { } قرار ميگيرند، تعداد عناصر آرايه ميباشند و مقادير عناصر آرايه نيز همان مقاديري است که داخل { } قرار گرفته است. به عنوان مثال در مثال 4، اولين آرايه ما داراي 3 عنصر است که مقادير آنها به ترتيب برابر با 5، 10 و 15 ميباشد.
روش ديگر جهت تعيين اندازه آرايه استفاده از روش تعريف کامل آرايه است که به فرم کلي زير ميباشد.
Code |
type[ ] arrayName = new type[n]; |
که در اين تعريف، استفاده از کلمه کليدي new باعث ايجاد نمونهاي جديد از نوع مورد نظر، ميشود. n نيز تعداد عناصر آرايه است که ميخواهيم آنرا توليد نماييم. در اين حالت بايد توجه داشت که آرايهاي تهي را توليد نمودهايم و هيچ عنصري را در آرايه جاي ندادهايم و در برنامه بايد آرايه را مقدار دهي نماييم. به مثال زير توجه کنيد.
Code |
int[ ] myArray = new int[15]; |
اين مثال آرايهاي تک بعدي از نوع int را با اندازه 15 عنصر توليد مينمايد. يعني اين آرايه قادر است تا 15 عنصر از نوع int را در خود ذخيره نمايد.
گونه ديگري از آرايهها، آرايههاي چند بعدي (Multi Dimensional Arrays) هستند که براي نگهداري اطلاعات از چندين بعد استفاده ميکنند و بيشتر براي نگداري جداول و ماتريسها مورد استفاده قرار ميگيرند. فرم کلي اعلان اين آرايهها بصورت زير است :
Code |
type[ , , … , ] arrayName = new type[n1, n2, …. , nm]; |
که در آن تعداد ابعاد آرايه با ويرگول مشخص شده و n1 تا nm نيز تعداد عناصر هر يک از ابعاد است. بعنوان مثال تعريف يک آرايه سه بعدي به فرم زير است :
Code |
char[ , , ] charArray = new char[3,5,7]; |
در اين مثال يک آرايه سه بعدي از نوع char توليد کردهايم که ابعاد آن به ترتيب داراي 3، 5 و 7 عنصر ميباشند.
نوع ديگري از آرايهها، آرايههاي دندانهدار (Jagged Arrays) هستند. اين نوع آرايهها تنها در زبان C# وجود دارند و در صرفهجويي حافظه بسيار موثر ميباسند. يک آرايه دندانهدار، در حقيقت يک آرايه تک بعدي است که هر يک از اعضاي آن خود يک آرايه تک بعدي ميباشند. اندازه اين عناصر ميتواند متفاوت باشد و تفاوت اين آرايهها با آرايههاي چند بعدي در همين جا نمايان ميشود. استفاده از اين آرايهها در مواردي کاربرد دارد که نيازي نيست تا تمامي ابعاد آرايه داراي تعداد عناصر مساوي باشند. بعنوان مثال فرض کنيد ميخواهيد آرايهاي جهت نگهداري تعداد روزهاي ماههاي مختلف سال تهيه کنيد. در صورتيکه بخواهيد از آرايه چند بعدي استفاده نماييد، چون تعداد روزهاي تمامي ماههاي سال يکسان نيست، مجبوريد تا تعداد عناصر تمام بعدهاي آرايه را برابر با بزرگترين تعداد روز ماهها، يعني 31، تعريف نماييد. ولي چون تنها 6 ماه داراي 31 روز ميباشند، براي 6 ماه ديگر تعدادي از عناصر آرايه هيچگاه مورد استفاده قرار نميگيرند و حافظه را به هدر دادهايم. اما در صورتيکه براي اين مثال از آرايههاي دندانهدار استفاده نماييم، ميتوانيم يک آرايه دندانهدار 12 عنصري تعريف نماييم و سپس تعداد عناصر هر يک از اعضاي آنرا برابر با تعداد روزهاي ماه مورد نظر تعريف کنيم :
با استفاده از آرايه چند بعدي :
Code |
int[ , ] monthArray = new int[12,31]; |
با استفاده از آرايه دندانهدار :
Code |
nt[ ][ ] monthArray = new int[12][ ]; |
در تعريف اول که در آن از آرايه چند بعدي استفاده کرديم، مشاهده ميکنيد که آرايهاي دو بعدي تعريف کردهايم که بعد اول آن 12 عضو و بعد دوم آن 31 عضو دارد. اين عمل دقيقاً همانند ايجاد يک جدول براي نگهداري روزهاي ماههاي سال است.
اما در حالت دوم که در آن از آرايه دندانهدار بهره بردهايم، يک آرايه تعريف نمودهايم که بعد اول آن 12 عضو دارد ولي بعد دوم آنرا را تعريف نکردهايم که داراي چند عضو است و هر يک از عناصر بعد اول آرايه ميتواند داراي تعداد اعضاي متفاوتي باشد که با استفاده از اين روش ميتوان به هر يک از ماههاي سال تعداد روزهاي مورد نظر آن ماه را تخصيص داد و فضايي بلا استفاده ايجاد نخواهيم کرد. توجه نماييد که چون تعداد عناصر بعد ديگر اين آرايه معين نشده است در برنامه بايد اين تعداد عنصر را مشخص نماييم :
Code |
monthArray[1] = new
int[31]; |
مشاهده ميکنيد که به هر ماه، تعدا عنصر مورد نياز خود را تخصيص دادهايم. تنها بايد به تفاوت اعلان آرايههاي دندانهدار با آرايههاي چند بعدي توجه نماييد.
دسترسي به عناصر آرايه از طريق انديس امکان پذير است. انديس شماره محل ذخيرهسازي دادههاي ما ميباشد که با دادن اين شماره ميتوانيم به داده مورد نظر دسترسي پيدا کنيم. در #C همانند C و C++ انديس خانههاي آرايه از صفر آغاز ميگردد يعني اولين خانه آرايه داراي شماره صفر است و عناصر بعدي به ترتيب يک واحد به انديسشان اضافه ميگردد. پس شماره انديس آرايه هميشه يک واحد کمتر از تعداد عناصر آن است، يعني آرايهاي که 10 عضو دارد بزرگترين انديس خانههايش 9 ميباشد. دسترسي به عناصر هر يک از ابعاد آرايه با انديس امکان پذير است. معمولاً به بعد اول آرايه سطر و به بعد دوم آن ستون ميگويد. مثلاً monthArray[3,7] عنصر واقع در سطر 3 و ستون 7 آرايه را مشخص مينمايد.(توجه داشته باشيد که انديس دهي آرايه از صفر آغاز ميشود و بعنوان مثال intArray[12] به خانه شماره 12 آرايه اشاره ميکند اما فراموش نکنيد چون انديس آرايه از صفر آغاز ميشود خانه شماره 12 آرايه، سيزدهمين داده شما را در خود جاي ميدهد.)
12 11 10 9 8 7 6 5 4 3 2 1 0
اگر شکل فوق را آرايهاي تک بعدي تصور نماييد، مشاهده مينماييد که خانه شماره 5 آرايه حاوي اطلاعات مربوط به ششمين داده ورودي شما ميباشد.
LESSON 3
دستورالعمل های کنترلی و شرطی
در اين درس با دستورالعملهاي کنترل و انتخاب در #C آشنا ميشويد. هدف اين درس عبارتست از :
• يادگيري دستور if
• يادگيري دستور switch
• نحوه بکارگيري دستور break در دستور switch
• درک صحيح از نحوه بکارگيري دستور goto
بررسي دستور if و انواع مختلف آن
در درسهاي گذشته، برنامههايي که مشاهده ميکرديد از چندين خط دستور تشکيل شده بودند که يکي پس از ديگري اجرا ميشدند و سپس برنامه خاتمه مييافت. در اين برنامهها هيچ عمل تصميمگيري صورت نميگرفت و تنها دستورات برنامه به ترتيب اجرا ميشدند. مطالب اين درس نحوه تصميمگيري در يک برنامه را به شما نشان ميدهد.
اولين دستور تصميمگيري که ما آنرا بررسي مينماييم، دستورالعمل if است. اين دستور داراي سه فرم کلي : تصميمگيري ساده، تصميمگيري دوگانه، تصميمگيري چندگانه ميباشد.
مثال 1-3 – فرمهاي دستورالعمل if
Code |
using System; |
برنامه 1-3 از يک متغير myInt براي دريافت ورودي از کاربر استفاده مينمايد، سپس با استفاده از يک سري دستورات کنترلي، که همان دستور if در اينجاست، عمليات خاصي را بسته به نوع ورودي انجام ميدهد. در ابتداي اين برنامه عبارت Please enter a umber: در خروجي چاپ ميشود. دستو Console.ReadLine( )منتظر ميماند تا کاربر ورودي وارد کرده و سپس کليد Enter را فشار دهد. همانطور که در قبل نيز اشاره کردهايم، دستور Console.ReadLine( ) عبارت ورودي را به فرم رشته دريافت مينمايد پس مقدار ورودي کاربر در اينجا که يک عدد است به فرم رشتهاي در متغير myInput که از نوع رشتهاي تعريف شده است قرار ميگيرد. اما ميدانيم که براي اجراي محاسبات و يا تصميمگيري بر روي اعداد نميتوان از آنها در فرم رشتهاي استفاده کرد و بايد آنها را بصورت عددي مورد استفاده قرار داد. به همين منظور بايد متغير myInput را به نحوي به مقدار عددي تبديل نماييم. براي اين منظور از عبارت Int32.Parse( )استفاده مينماييم. اين دستور مقدار رشتهاي متغير داخل پرانتزش را به مقدار عددي تبديل کرده و آنرا به متغير ديگري از نوع عددي تخصيص ميدهد. در اين مثال نيز همانطور که ديده ميشود، myInput که تز نوع رشتهاي است در داخل پرانتز قرار گرفته و اين مقدار برابر با myInt که از نوع int است قرار گرفته است. با اين کار مقدار عددي رشته ورودي کاربر به متغير myInt تخصيص داده ميشود. (توضيح کاملتري در مورد Int32 و ساير تبديلات مشابه به آن در درسهاي آينده و در قسمت نوعهاي پيشرفته مورد بررسي قرار ميگيرند.)حال ما متغيري از نوع مورد نظر در دست داريم و ميتوانيم با استفاده از دستور if بر روي آن پردازش انجام داده و تصميمگيري نماييم.
دستور if
اولين دستور بصورت if (boolean expression) {statements} آورده شده است. دستور if با استفاده از کلمه کليدي if آغاز ميشود. سپس يک عبارت منطقي درون يک زوج پرانتز قرار ميگيرد . پس از بررسي اين عبارات منطقي دستورالعمل/دستورالعملهاي داخل کروشه اجرا ميشوند. همانطور که مشاهده مينماييد، دستور if يک عبارت منطقي را بررسي ميکند. در صورتيکه مقدار اين عبارات true باشد دستورهاي داخل بلوک خود را اجرا مينمايد(قبلا توضيح داده شد که دستورهايي که داخل يک زوج کروشه {} قرار ميگيرند در اصطلاح يک بلوک ناميده ميشوند.) و در صورتيکه مقدار آن برابر با false باشد اجراي برنامه به بعد از بلوک if منتقل ميشود. در اين مثال همانطور که ملاحظه مينماييد، عبارت منطقي دستور if به شکل if(myInt > 0) است. در صورتيکه مقدار myInt بزرگتر از عدد صفر باشد، دستور داخل بلوک if اجرا ميشود و در غير اينصورت اجراي برنامه به بعد از بلوک if منتقل ميگردد.
دومين دستور if دراين برنامه بسيار شبيه به دستور اول است، با اين تفاوت که در اين دستور، دستور اجرايي if درون يک بلوک قرار نگرفته است. در صورتيکه بخواهيم با استفاده از دستور if تنها يک دستورالعمل اجرا شود، نيازي به استفاده از بلوک براي آن دستورالعمل نميباشد. استفاده از بلوک تنها زماني ضروري است که بخواهيم از چندين دستور استفاده نماييم.
دستور if-else
در بيشتر موارد از تصميمگيريهاي دوگانه يا چندگانه استفاده ميشود. در اين نوع تصميمگيريها، دو يا چند شرط مختلف بررسي ميشوند و در صورت true بودن يکي از آنها عمل مربوط به آن اجرا ميگردد. سومين دستور if در اين برنامه نشان دهنده يک تصميمگيري دوگانه است. در اين حالت درصورتيکه عبارت منطقي دستور if برابر با true باشد دستور بعد از if اجرا ميشود و در غير اينصورت دستور بعد از else به اجرا در ميآيد. در حقيقت در اين حالت ميگوئيم " اگر شرط if صحيح است دستورات مربوط به if را انجام بده و درغير اينصورت دستورات else را اجرا کن".
فرم کلي دستور if-else بصورت زير است :
Code |
if (boolean expression) |
که در آن boolean expression عبارت منطقي است که صحت آن مورد بررسي قرار ميگيرد و statements دستور يا دستوراتي است که اجرا ميگردند.
دستور if-else if … else يا if تودرتو
در صورتيکه نياز باشد تا چندين حالت منطقي مورد بررسي قرار گيرد و دستورات مربوط به يکي از آنها اجرا شود، از فرم تصميمگيري چندگانه استفاده مينماييم. اين نوع استفاده از دستور if در اصطلاح به if تودرتو (Nested If) معروف است چراکه در آن از چندين دستور if مرتبط به يکديگر استفاده شده است. چهارمين دستور if در مثال 1-3 استفاده از if تودرتو را نشان ميدهد. در اين حالت نيز دستور با کلمه کليدي if آغاز ميگردد. شرطي بررسي شده و در صورت true بودن دستورات مربوط به آن اجرا ميگردد. اما اگر مقدار اين عبارت منطقي false بود آنگاه شرطهاي فرعي ديگري بررسي ميشوند.اين شرطهاي فرعي با استفاده از else if مورد بررسي قرار ميگيرند. هر يک از اين شرطها داراي عبارات منطقي مربوط به خود هستند که در صورت true بودن عبارت منطقي دستورات مربوط به آنها اجرا ميگردد و در غير اينصورت شرط بعدي مورد بررسي قرار ميگيرد. بايد توجه کنيد که در ساختار if تودرتو تنها يکي از حالتها اتفاق ميافتد و تنها يکي از شرطها مقدار true را بازميگرداند.
فرم کلي if تودرتو بشکل زير است :
Code |
if (boolean expression) |
عملگرهاي OR و AND (|| و &&)
نکته ديگري که بايد در اينجا بدان اشاره کرد، نوع شرطي است که در عبارت منطقي دستور if آخر مورد استفاده قرار گرفته است. در اين عبارت منطقي از عملگر || استفاده شده است که بيانگر OR منطقي است. عملگر OR زماني مقدار true بازميگرداند که حداقل يکي از عملوندهاي آن داراي مقدار true باشد. بعنوان مثال در عبارت (myInt < 0 || myInt == 0)، در صورتيکه مقدار متغير myInt کوچکتر يا مساوي با صفر باشد، مقدار عبارت برابر با true است. نکته قابل توجه آنست که در زبان C#، همانطور که در درس دوم به آن اشاره شد، دو نوع عملگر OR وجود دارد. يکي OR منطقي که با || نمايش داده ميشود و ديگري OR معمولي که با | نشان داده ميشود. تفاوت بين اين دو نوع OR در آنست که OR معمولي هر دو عملگر خود را بررسي مينمايد اما OR منطقي تنها در صورتيکه عملگر اول آن مقدار false داشته باشد به بررسي عملگر دوم خود ميپردازد.
عبارت منطقي (myInt > 0 && myInt <= 10) حاوي عملگر AND شرطي (&&) ميباشد. اين عبارت در صورتي مقدار true بازميگرداند که هر دو عملوند AND داراي مقدار true باشند. يعني در صورتيکه myInt هم بزرگتر از صفر باشد و هم کوچگتر از 10، مقدار عبارت برابر با true ميگردد. در مورد AND نيز همانند OR دو نوع عملگر وجود دارد. يکي AND معمولي (&) و ديگري AND شرطي (&&). تفاوت اين دو نيز در آنست که AND معمولي (&) هميشه هر دو عملوند خود را بررسي مينمايد ولي AND شرطي (&&) تنها هنگامي به بررسي عملوند دوم خود ميپردازد که مقدار اولين عملوندش برابر با true باشد. عملگرهاي منطقي (|| و &&) را در اصطلاح عملگرهاي ميانبر (short-circuit) مينامند چراکه تنها در صورت لزوم عملوند دوم خود را بررسي مينمايند و از اينرو سريعتر اجرا ميشوند.
بررسي دستور switch
همانند دستور if، دستور switch نيز امکان تصميمگيري را در يک برنامه فراهم مينمايد.
مثال 2-3 – دستورالعمل switch
Code |
using System; |
مثال 2-3 دو مورد استفاده از دستور switch را نشان ميدهد. دستور switch بوسيله کلمه کليدي switch آغاز شده و به دنبال آن عبارت دستور switch قرار ميگيرد. عبارت دستور switch ميتواند يکي از انواع زير باشد : sbyte, byte, short, ushort, int, uint, long, ulong, char, string, enum .(نوع enum در مبحث جداگانهاي مورد بررسي قرار خواهد گرفت.) در اولين دستور switch در مثال 2-3، عبارت دستور switch از نوع عددي صحيح (int) ميباشد. به دنبال دستور و عبارت switch، بلوک switch قرار ميگيرد که در آن گزينههايي قرار دارند که جهت منطبق بودن با مقدار عبارت switch مورد بررسي قرار ميگيرند. هر يک از اين گزينهها با استفاده از کلمه کليدي case مشخص ميشوند. پس از کلمه کليدي case خود گزينه قرار ميگيرد و به دنبال آن ":" و سپس دستوري که بايد اجرا شود. بعنوان مثال به اولين دستور switch در اين برنامه توجه نماييد. در اينجا عبارت دستور switch از نوع int است. هدف از استفاده از دستور switch آنست که از بين گزينههاي موجود در بلوک switch، گزينهاي را که مقدارش با مقدار عبارت switch برابر است پيدا شده و عمل مرتبط با آن گزينه اجرا شود. در اين مثال مقدار متغير myInt بررسي ميشود. سپس اگر اين مقدار با يکي از مقادير گزينههاي داخل بلوک switch برابر بود، دستور يا عمل مربوط به آن گزينه اجرا ميگردد. توجه نماييد که در اين مثال منظور ما از گزينه همان عدد پس از case است و منظور از دستور عبارتي است که پس از ":" قرار گرفته است. بعنوان مثال، در دستور زير :
Code |
case 1: |
عدد 1، گزينه مورد نظر ما و دستور Console.WriteLine(…)، عمل مورد نظر است. در صورتيکه مقدار myInt برابر با عدد 1 باشد آنگاه دستور مربوط به case 1 اجرا ميشود که همان Console.WriteLine("Your number is {0}.", myInt); است. پس از منطبق شدن مقدار عبارت switch با يکي از case ها، بلوک switch بايد خاتمه يابد که اين عمل بوسيله استفاده از کلمه کليدي break، اجراي برنامه را به اولين خط بعد از بلوک switch منتقل مينمايد.
همانطور که در ساختار دستور switch مشاهده مينماييد، علاوه بر case و break، دستور ديگري نيز در داخل بلوک وجود دارد. اين دستور يعني default، براي زماني مورد استفاده قرار ميگيرد که هيچ يک از گزينههاي بلوک switch با عبارت دستور switch منطبق نباشند. به عبارت ديگر درصورتيکه مقدار عبارت switch با هيچ يک از گزينههاي case برابر نباشد، دستور مربوط به default اجرا ميگردد. استفاده از اين دستور در ساختار بلوک switch اختياري است. همچنين قرار دادن دستور break پس از دستور default نيز اختياري ميباشد.
همانطور که قبلاً نيز گفته شد پس از هر دستور case، به منظور خاتمه دادن اجراي بلوک switch بايد از يک break استفاده نمود. دو استثنا براي اين موضوع وجود دارد. اول اينکه دو دستور case بدون وجود کد و دستورالعملي در بين آنها، پشت سر هم قرار گيرند و ديگري در زمانيکه از دستور goto استفاده شده باشد.
در صورتيکه دو دستور case بدون وجود کدي در بين آنها، پشت سر يکديگر قرار گيرند، بدين معناست که براي هر دو case مورد نظر يک عمل خاص در نظر گرفته شده است. به مثال زير توجه نماييد.
Code |
switch (myInt) |
در اين مثال، همانطور که مشاهده ميکنيد، سه دستور case بدون وجود کدي در بين آنها پشت سر يکديگر قرار گرفتهاند. اين عمل بدين معناست که براي تمامي گزينههاي 1، 2 و 3 دستور Console.WriteLine("Your number is {0}.", myInt); اجرا خواهد شد. يعني اگر مقدار myInt برابر با هر يک از مقادير 1، 2 و 3 باشد، يک دستور براي آن اجرا ميشود.
نکته قابل توجه ديگر در مورد بلوک switch آنست که، دستورات case حتماً نبايد يک دستور باشد بلکه ميتوان از يک بلوک دستور براي case استفاده نمود.
دومين استفاده از دستور switch در مثال 2-3، داراي عبارتي از نوع رشتهايست. در اين بلوک switch چگونگي استفاده از دستور goto نيز نشان داده شده است. دستور goto اجراي برنامه را به برچسبي (label) که معين شده هدايت مينمايد. در حين اجراي اين برنامه، اگر کاربر رشته continue وارد نمايد، اين رشته با يکي از گزينههاي دومين switch منطبق ميشود. چون دستور case مربوط به اين گزينه داراي دستور goto است، اجراي برنامه به برچسبي که اين دستور مشخص کرده فرستاده ميشود، بدين معني که اجراي برنامه به ابتداي جايي ميرود که عبارت begin: در آنجا قرار دارد (در اوايل متد Main( )). بدين صورت اجراي برنامه از بلوک switch خارج شده و به ابتداي برنامه و در جائيکه برچسب begin: قرار گرفته ارسال ميشود. در اين برنامه، استفاده از چنين حالتي استفاده از goto باعث ايجاد يک حلقه شده است که با وارد کردن عبارت quit اجراي آن به پايان ميرسد.
در صورتيکه هيچ يک از عبارات continue و يا quit وارد نشوند، اجراي switch به گزينه default ميرود و در اين گزينه ابتدا پيغام خطايي بر کنسول چاپ شده و سپس با استفاده از دستور goto پرشي به برچسب decide صورت ميگيرد. پس از پرش به برچسب decide، از کاربر پرسيده ميشود که آيا ميخواهد اجراي برنامه را ادامه دهد يا خير.( با وارد کردن گزينههاي continue يا quit) همانطور که ميبينيد در اينجا نيز حلقهاي توليد شده است.
استفاده از دستور goto در بلوک switch ميتواند موثر باشد اما بايد توجه نماييد که استفادههاي بي مورد از دستور goto باعث ناخوانا شدن برنامه شده و عيبيابي (Debug) برنامه را بسيار دشوار مينمايد. در برنامهنويسيهاي امروزي استفاده از دستور goto بغير از موارد بسيار لازم و ضروري منسوخ شده و به هيچ عنوان توصيه نميشود. براي توليد و ساخت حلقه نيز دستورات مفيد و سودمندي در زبان تعبيه شدهاند که استفاده از goto را به حداقل ميرسانند. دستورات حلقه در مبحث آينده مورد بررسي قرار خواهند گرفت.
نکته پاياني اين مبحث آنست که توجه نماييد که به جاي استفاده از دستور switch ميتوانيد از چندين دستور if-else استفاده نمايد. دو قطعه برنامه زير معادل يکديگر ميباشند.
Code |
switch(myChar)
if (myChar == 'A') |
همانطور که ملاحظه ميکنيد استفاده از بلوک دستور switch بسيار سادهتر از استفاده از if-else هاي تودرتو است.
خلاصه درس
در اين درس با نحوه تصميمگيري در برنامه بوسيله دستور if و switch آشنا شديد. با نحوه عملکرد و استفاده دستور goto نيز آشنايي پيدا کرديد. در پايان مجدداً يادآوري ميکنم که در استفاده از دستور goto با احتياط عمل نماييد و به جز در موارد ضروري از آن استفاده نکنيد.
LESSON 4
دستورالعمل های کنترلی ، حلقه ای
در اين درس نحوه استفاده از دستورالعملهاي کنترل حلقه در زبان #C را فرا خواهيد گرفت. هدف اين درس فهم و درک موارد زير ميباشد :
· حلقه while
· حلقه do-while
· حلقه for
· حلقه foreach
· مطالب تکميلي درباره دستورالعمل break
· فراگيري نحوه بکارگيري دستورالعمل continue
در درس قبل، نحوه ايجاد يک حلقه بسيار ساده را با استفاده از دستور goto را فرا گرفتيد. در همان مطلب نيز اشاره کرديم که اين روش، روش مناسبي جهت ايجاد حلقه نيست. در اين درس با نحوه صحيح ايجاد حلقهها در زبان #C آشنا خواهيد شد. اولين دستوري که با آن آشنا ميشويد نيز دستور while است.
حلقه while
ابتدا به مثال زير توجه نماييد.
Code |
using System; |
مثال 1-4 که در بالا ملاحظه ميکنيد، يک حلقه while ساده را نشان ميدهد. اين حلقه با کلمه کليدي while آغاز شده و سپس به دنبال آن يک عبارت منطقي قرار ميگيرد و مورد بررسي قرار ميگيرد. تمامي دستورالعملهاي کنترلي از يک عبارت منطقي بهره ميگيرند و اين بدين معناست که ابتدا اين عبارت بايد بررسي شود تا مشخص شود مقدار اين عبارت true است يا false. در اين مثال مقدار متغير myInt مورد بررسي قرار ميگيرد تا چک شود آيا مقدارش از 10 کوچکتر هست يا خير. چون در ابتداي برنامه به اين متغير مقدار صفر تخصيص داده شده است، عبارت منطقي مقدار true را باز ميگرداند و سپس بلوک قرار گرفته بعد از عبارت منطقي مورد اجرا قرار ميگيرد.
درون بلوک while ابتدا مقدار متغير myInt در کنسول نمايش داده ميشود و سپس يک واحد به مقدار اين متغير افزوده ميگردد. پس از اتمام بلوک while، عبارت منطقي مجددا کنترل ميشود و در صورتيکه اين عبارت مقدار true بازگرداند، حلقه while مجدداً اجرا ميشود. زمانيکه عبارت منطقي مقدار false برگرداند، اجرا برنامه به اولين دستور بعد از بلوک while منتقل ميشود. در اين مثال اعداد صفر تا 9 بر روي صفحه نمايش داده ميشوند و سپس يک خط خالي چاپ شده و اجراي برنامه خاتمه مييابد.
حلقه بعدي که بسيار شبيه به حلقه while ميباشد، حلقه do-while است.
حلقه do-while
ابتدا به مثال 2-4 توجه نماييد.
Code |
using System; |
مثال 2-4 نحوه استفاده از حلقه do-while را نشان ميدهد. ساختار نوشتاري اين دستور بصورت زير است :
Code |
do |