0

آموزش ++C - بخش هشتم

 
reza1371
reza1371
کاربر برنزی
تاریخ عضویت : مهر 1388 
تعداد پست ها : 168
محل سکونت : لرستان

آموزش ++C - بخش هشتم
شنبه 1 خرداد 1389  4:48 PM

قبل از نوشتن يك برنامه كه بتواند مسئله‌اي را به طور دقيق حل كند، ضروري است كه درك صحيحي از مسئله داشته باشيم و بوسيله يك طراحي دقيق به آن اقدام كنيم. به هنگام نوشتن يك برنامه، سازماندهي انواع بلوك‌هاي ايجاد كننده برنامه به منظور بهبود قوانين عملي ساخت برنامه بسيار مهم است. در اين فصل و فصل بعدي در مورد تئوري و قواعد علمي برنامه‌نويسي ساخت‌يافته بحث خواهيم كرد. تكنيك‌هاي معرفي شده در اين فصل در اكثر زبان‌هاي سطح بالا نظير كاربرد دارند. با معرفي مفاهيم مطرح شده در اينجا متوجه مزيت عبارتهاي كنترل در ايجاد و دستكاري شي‌ها خواهيد شد. عبارتهاي كنترل معرفي شده در اين فصل در ايجاد سريع و آسانتر شي‌ها كمك كننده هستند.

در اين فصل به معرفي عبارات if ، if..else و while در زبان C++ خواهيم پرداخت. سه بلوك سازنده كه به برنامه‌نويسان امكان مي‌دهند تا منطق مورد نياز توابع عضو را براي انجام وظايف مشخص كنند. بخشي از اين فصل و فصل‌هاي 5 و 7 را براي توسعه دادن كلا س GradeBook معرفي شده در فصل سوم اختصاص داده‌ايم. در واقع، يك تابع عضو به كلاس GradeBook اضافه مي‌كنيم كه از عبارات كنترلي براي محاسبه ميانگين نمرات دانشجويان استفاده مي‌كند. مثال ديگر به معرفي روش‌هاي تركيب عبارات كنترلي براي حل مسئله مشابه است. همچنين به معرفي عملگرهاي تخصيص‌دهنده و عملگرهاي افزاينده و كاهنده در C++ خواهيم پرداخت. اين عملگرها سبب كوتاه شدن عبارات و گاهاً سادگي كار مي‌شوند.

2-4 الگوريتم

هر مسئله ‌محاسباتي و كامپيوتري مي‌تواند با يك سري از اعمال اجرائي كه به ترتيب اجرا مي‌شوند، حل شود. از روال‌ها براي حل مسائل كمك گرفته مي‌شود و عبارات:

1- فعاليت‌ها از نوع اجراي هستند و

2- فعاليت‌ها به ترتيب اجرا مي‌شوند،

تعريف الگوريتم مي‌باشند. با ذكر مثالي كه در زير آمده مي‌توانيد ترتيب اجرا و فعاليت‌ها را ببينيد و متوجه شويد كه ترتيب اجرا چقدر مهم است. الگوريتم “rise - and - shine” در ارتباط با مراحلي است كه يك شخص از هنگام برخواستن از خواب تا رفتن به سركار انجام مي‌دهد، مراحل: (1) برخواستن از تختخواب، (2) پوشيدن لباس راحتي، (3) دوش گرفتن، (4) پوشيدن لباس، (5) خوردن صبحانه، (6) رفتن به محل كار. اين روتين در مورد نحوه انجام كار و ضوابط تصميم‌گيري مي‌تواند موثر باشد حال اگر ترتيب اجرا به صورت زير جابجا شود:

(1) برخواستن از تختخواب، (2) پوشيدن لباس راحتي، (3) پوشيدن لباس، (4) دوش گرفتن، (5) خوردن صبحانه، (6) رفتن به محل كار. در اين حالت شخص مورد نظر، بايستي به محل كار با لباس خيس برود.

مشخص كردن عبارات اجرائي در يك برنامه كامپيوتري، كنترل برنامه (program control) ناميده شود، كه به اجراي صحيح و مرتب عبارات گفته مي‌شود.

3-4 شبه‌كد

شبه‌كد (pseudocode) يك زبان مصنوعي و فرمال است كه به برنامه‌نويس كمك مي‌كند تا الگوريتم خود را توسعه دهد. شبه‌كد مخصوصاً براي ايجاد الگوريتم‌هاي مفيد است كه مي‌خواهيم آنها را تبديل به برنامه‌هاي ساخت يافته كنيم شبه‌كد، همانند زبان روزمره انگليسي است و مزيت آن درك آسان توسط كاربر است، اگر چه جزء زبان‌هاي برنامه‌نويسي اجرائي نيست. برنامه‌هاي شبه‌كد توسط كامپيوتر قابل اجرا نيستند. با اين همه، شبه‌كدها، مي‌توانند قبل از نوشتن يك برنامه به زبان اجراي مانند C++ ، برنامه‌نويس را در راه صحيح قرار دهند.

 

 

مهندسي نرم‌افزار

شبه‌كد به برنامه‌نويسان كمك مي‌كند تا در زمان فرآيند طراحي برنامه يك مفهوم منطقي از برنامه بدست آورند. برنامه شبه‌كد مي‌تواند در مرحله بعد به زبان ++ C برگردانده شود.

 

 

شبه‌كدهايي كه از آنها استفاده مي‌كنيم، فقط از كاراكترها تشكيل شده‌اند و برنامه‌نويس مي‌تواند آنها را در يك برنامه ويرايشگر، تايپ كند. شبه‌كد، فقط شامل عبارات اجرائي است. زماني كه شبه‌كد تبديل به كدهاي C++ شود، برنامه حالت اجرايي پيدا خواهد كرد. اعلان‌ها جزء عبارات اجرائي نيستند. براي مثال، اعلان

int i;

فقط به كامپايلر نوع متغير i را نشان داده و كامپايلر مكاني در حافظه به اين متغير اختصاص مي‌دهد. اما اين اعلان‌ها هيچ عمل اجرائي نظير ورودي، خروجي يا يك عمل محاسباتي را در زماني كه برنامه اجرا مي‌شود، از خود نشان نمي‌دهند. تعدادي از برنامه‌نويسان ليستي از متغيرها تهيه كرده و منظور از كاربرد هر متغير را در ابتداي شبه‌كد قرار مي‌دهند.

اكنون به مثالي از شبه كد نگاه مي‌كنيم كه مي‌تواند براي كمك به برنامه‌نويس در ايجاد يك برنامه جمع معرفي شده در شكل 5-2 (فصل دوم) نوشته شده باشد. اين شبه كد (شكل 1-4) متناظر با الگوريتمي است كه دو عدد صحيح از كاربر دريافت، آنها را با هم جمع و مجموع آنها را به نمايش در مي‌آورد. با اينكه ليست كامل شبه كد را به نمايش درآورده‌ايم، اما شما را با نحوه ايجاد يك شبه كد از صورت مسئله آشنا خواهيم كرد.

1     Prompt the user to enter the first integer

2     Input the first integer

3      

4     Prompt the user to enter the second integer

5     Input the second integer

6      

7     Add first integer and second integer

8     Display result

شكل 1-4 | شبه كد برنامه جمع شكل 5-2.

خطوط 1-2 متناظر با عبارات موجود در خطوط 13-14 از شكل 5-2 هستند. دقت كنيد كه عبارات شبه كد، عبارات ساده انگليسي هستند كه هر وظيفه در C++ را بيان مي‌كنند. به همين ترتيب، خطوط 4-5 متناظر با عبارات موجود در خطوط 16-17 و خطوط 7-8 متناظر با عبارات موجود در خطوط 19 و 21 از شكل 5-2 هستند.

چندين نكته مهم در شبه كد شكل 1-4 وجود دارد. دقت كنيد كه شبه كد فقط متناظر با كد موجود در تابع main است، به اين دليل كه معمولاً از شبه كد براي الگوريتم‌ها استفاده مي‌شود، نه براي كل برنامه. در اين مورد، از شبه كد براي عرضه الگوريتم استفاده شده است. تابع موجود در اين كد به اندازه خود الگوريتم مهم نيست. به همين دليل، خط 23 از شكل 5-2 (عبارت return ) در شبه كد وارد نشده است. عبارت return در انتهاي هر تابع main قرار دارد و در الگوريتم اهميتي ندارد. سرانجام، خطوط 9-11 از شكل 5-2 در شبه كد وجود ندارد چرا كه اعلان متغيرها جزء عبارات اجرايي نيستند.

4-4  عبارات كنترل

معمولاً، عبارات موجود در يك برنامه يكي پس از ديگري و به ترتيبي كه نوشته شده‌اند اجرا مي‌شوند، كه به اينحالت اجراي ترتيبي مي‌گويند. انواع متفاوتي از عبارات كه بزودي درباره آنها بحث خواهيم كرد، برنامه‌نويسان را قادر مي‌سازند تا با مشخص كردن عبارتي كه بايستي قبل از عبارت ديگري اجرا شود، اين توالي اجرا را در دست گيرند، كه به اينحالت، كنترل انتقال مي‌گويند.

در دهه 1960، به دليل وجود مشكلات فراوان در ايجاد نرم‌افزارهاي كاربردي، استفاده از روش‌هاي كنترل انتقال به عنوان يك زمينه بكار گرفته شد و نشانه آن عبارت goto بود. اين عبارت به برنامه‌نويس  اجازه مي‌دهد تا كنترل را به يك مكان ويژه در كل برنامه انتقال دهد. عقيده‌اي كه برنامه‌نويسي ساخت يافته نام گرفته بود، تقريباً با برنامه‌نويسي حذف ‌ goto يا كاهش آن (goto-less) مترادف شده است.

با تحقيقات Jacopini و Bohm كه نشان داد كه برنامه‌ها بايستي بدون goto نوشته شوند، دعوت از برنامه‌نويسان به طرف برنامه‌نويسي كاهش استفاده از goto آغاز گرديد. اما تا سال 1970 برنامه‌نويسي ساخت يافته جدي گرفته نشد. در نتيجه بكار بردن اين روش، توسعه نرم‌افزار و كاهش بودجه‌هاي ساخت آن مشخص شد. كليد تمام اين موفقيت‌ها برنامه‌هاي ساخت يافته‌اي بودند كه هم وضوح بالاتر و خطاگيري آسانتري داشتند.

Bohm و Jacopini نشان دادند كه تمام برنامه‌ها در سه عبارت كنترلي مي‌توانند نوشته شوند:

·          عبارت توالي (sequence structure)

·          عبارت انتخاب (selection structure)

·          عبارت تكرار (repetition structure)

ساختار توالي در C++

ساختار توالي بصورت توكار در C++ وجود دارد. مگر اينكه آن را به نحوه ديگري هدايت كنيد. كامپيوتر مبادرت به اجراي عبارات C++ يكي پس از ديگري و به ترتيبي كه نوشته شده‌اند مي‌كند، كه اين حالت اجراي ترتيبي يا متوالي است. دياگرام فعاليت UML (Unified Modeling language) به نمايش درآمده در شكل 2-4 نشاندهنده يك ساختار توالي است كه در آن دو محاسبه به ترتيب انجام مي‌شود. زبان C++ اجازه مي‌دهد تا به هر اندازه كه لازم داريم از ساختار توالي استفاده كنيم. همانطوري كه بزودي مشاهده خواهيد كرد، در هر كجا كه يك عمل مي‌تواند موجود باشد، مي‌توانيم چندين عمل را به صورت توالي جايگزين كنيم.

در اين شكل، دو عبارت مبادرت به افزودن يك نمره به متغير مجموع (total) و مقدار 1 به متغير counter مي‌كنند. چنين عباراتي را مي‌توان در يك برنامه محاسبه ميانگين نمره چند دانشجو مشاهده كرد. براي محاسبه ميانگين، مجموع نمرات به تعداد نمرات تقسيم مي‌شود. از متغير شمارنده (counter) براي نگهداري تعداد نمرات وارد شده استفاده مي‌شود. در بخش 8-4 با عبارات مشابهي مواجه خواهيد شد.

دياگرام‌هاي فعاليت بخشي از UML هستند. يك دياگرام فعاليت مبادرت به مدل‌سازي روندكار (فعاليت) يك بخش از سيستم نرم‌افزاري مي‌كند. چنين روندهايي مي‌توانند در برگيرنده بخشي از يك الگوريتم، همانند يك ساختار توالي در شكل2-4 باشند.دياگرام‌هاي فعاليت‌ مركب از نمادهاي معني‌دار، همانند نمادهاي وضعيت عمل (يك مستطيل كه گوشه‌هاي چپ و راست آن به سمت بيرون انحناء داده شده‌اند)، لوزي‌ها و دايره‌هاي كوچك است. اين نمادها توسط فلش‌هاي انتقال به يكديگر متصل مي‌شوند كه نشاندهنده روند فعاليت مي‌باشند.

همانند شبه كد، دياگرام‌هاي فعاليت به برنامه‌نويسان در توسعه و عرضه الگوريتم‌ها كمك مي‌كنند، اگر چه برخي از برنامه‌نويسان شبه كد را ترجيح مي‌دهند. دياگرام‌هاي فعاليت به وضوح نحوه عملكرد ساختارهاي كنترل را نشان مي‌دهند.

به دياگرام فعاليت ساختار متوالي در شكل 2-4 توجه كنيد. اين دياگرام حاوي دو نماد وضعيت عمل است كه نشاندهنده اعمالي هستند كه اجرا مي‌شوند. هر وضعيت عمل حاوي يك بيان‌كننده عمل است، "add grade to total" و "add 1 to counter" كه مشخص‌كننده عملي هستند كه انجام خواهند شد. ساير اعمال مي‌توانند محاسباتي يا ورودي/ خروجي باشند.

 

 

انجمن برنامه نويسي راسخون |‌‌ www.rasekhoon.net |

شكل 2-4 | دياگرام فعاليت يك ساختار توالي.

فلش‌‌ها در دياگرام فعاليت، بنام فلش‌هاي انتقال‌ شناخته مي‌شوند. اين فلش‌ها نشاندهنده انتقال هستند و بر اين نكته دلالت دارند كه ترتيب اجراي اعمال به چه صورتي است. براي مثال در شكل 2-4 ابتدا grade با total جمع شده و سپس 1 به counter افزوده مي‌شود.

دايره توپر ساده كه در بالاي دياگرام فعاليت قرار گرفته نشاندهنده وضعيت اوليه فعاليت است، ابتداي روندكار قبل از اينكه برنامه عمليات مدل شده را انجام دهد. دايره توپر احاطه شده با يك دايره توخالي كه در پايين دياگرام فعاليت ديده مي‌شود، نشاندهنده وضعيت پاياني است، پايان روندكار پس از اينكه فعاليت‌هاي خود را انجام داده است.

همچنين شكل 2-4 شامل مستطيل‌هاي با گوشه‌هاي خم شده به داخل (سمت راست-بالا) است. اين مستطيل‌ها، در UML ، نكته (note) ناميده مي‌شوند. نكته‌ها توضيحات اضافي در ارتباط با هدف نمادها در دياگرام ارائه مي‌كنند. از نكته‌ها مي‌توان در هر دياگرام UML و نه تنها در دياگرام‌هاي فعاليت استفاده كرد. در شكل 2-4 از نكته‌هاي UML براي نمايش كد C++ مرتبط با هر وضعيت عمل در دياگرام فعاليت استفاده شده است. خط نقطه ‌چين مبادرت به متصل نمودن هر نكته با عنصري مي‌كند كه در ارتباط با آن توضيح ارائه مي‌نمايد. معمولاً دياگرام‌هاي فعاليت، كد C++ پياده‌سازي كننده فعاليت را عرضه نمي‌كنند. اما از اين نكته‌ها به اين منظور در اينجا استفاده كرده‌ايم تا رابطه دياگرام با كد C++ مربوطه را بهتر نشان دهيم. براي كسب اطلاعات بيشتر در مورد UML به بخش مبحث آموزشي مهندسي نرم‌افزار كه در انتهاي فصل 1 الي 7، 9، 10، 12 و 13 قرار دارند مراجعه كرده يا از وب سايت www.uml.org بازديد نماييد.

 

عبارات انتخاب در C++

زبان C++ سه نوع عبارت انتخاب تدارك ديده است كه در مورد آنها در اين فصل و فصل بعدي توضيح خواهيم داد. در عبارت انتخاب if اگر شرط برقرار باشد عبارت يا عبارات داخل بدنه اجرا شده و در صورتيكه شرط برقرار نباشد از روي آن عبارات بدون اجراي آنها عبور خواهد شد. عبارت if..else در صورتيكه شرط برقرار باشد، عبارت (يا دنباله‌اي از عبارات) را انجام داده و در صورتيكه شرط برقرار نباشد، عمل اجراي متفاوتي را به انجام مي‌رساند (يا اجراي توالي از عبارات). عبارت switch كه در فصل 5 به بررسي آن خواهيم پرداخت با توجه به ارزش يك عبارت، يكي از چندين عمل اجرائي را به اجرا در مي‌آورد.

عبارت if را عبارت تك انتخابي (single-selection) مي‌نامند، چرا كه يك عمل را انتخاب و اجرا يا آنرا رد مي‌كند. عبارت if..else را عبارت دو انتخابي (double-selection) مي‌نامند، چرا كه انتخابي مابين دو حالت متفاوت انجام مي‌دهد. عبارت switch ، عبارت چند انتخابي (multiple-selection) ناميده مي‌شود، چرا كه از ميان موارد متفاوت انتخاب خود را انجام مي‌دهد.

عبارات تكرار در C++

C++ سه نوع عبارت تكرار بنام‌هاي زير تدارك ديده است:

·            while

·            do..while

·            for

عبارت تكرار while ، در اين فصل معرفي خواهد شد و عبارات do..while ، و for در قسمت هاي بعدي  توضيح داده خواهند شد. كلمات if ، else ، switch ، while ، do و for همگي جزء كلمات كليدي C++ هستند ( جدول شكل 3-4). با بسياري از اين كلمات كليدي در اين آموزش آشنا خواهيد شد.

 

خطاي برنامه‌نويسي

استفاده از كلمه كليدي بعنوان يك شناسه خطاي نحوي خواهد بود.

 

خطاي برنامه‌نويسي

نوشتن يك كلمه كليدي با حروف بزرگ خطاي نحوي است تمام كلمات كليدي در C++ فقط شامل حروف كوچك هستند.

 

 

C++ Keywords

Keywords common to the C and C++ programming languages

auto

break

case

char

const

continue

default

do

double

else

enum

extern

float

for

goto

if

int

long

register

return

short

signed

sizeof

static

struct

switch

typedef

union

unsigned

void

volatile

while

 

 

 

C++ only keywords

asm

bool

catch

class

const_cast

delete

dynamic_cast

explicit

false

friend

inline

mutable

namespace

new

operator

private

protected

public

reinterpret_cast

and

static_cast

template

this

throw

true

try

typeid

typename

using

virtual

wchar_t

and_eq

bitand

bitor

export

not

not_eq

or

or_eq

xor_eq

شكل 3-4 | كلمات كليدي C++

خلاصه‌اي بر عبارات كنترلي در C++

C++ داراي سه عبارت كنترلي است، كه از اين به بعد از آنها بعنوان عبارات كنترلي ياد خواهيم كرد: عبارت توالي، عبارات انتخابي (سه نوع- if, if..else و switch ) و عبارات تكرار(سه نوع- while, for و do..while ) . هر برنامه C++ از تركيب اين عبارات كنترلي ايجاد مي‌شود. همانند عبارت توالي در شكل 2-4، مي‌توانيم هر عبارت كنترلي را بصورت يك دياگرام فعاليت مدل‌سازي كنيم. هر دياگرام حاوي يك حالت اوليه و يك حالت پاياني است، كه به ترتيب نشاندهنده نقطه ورودي (entry point) به عبارت كنترلي و نقطه خروجي (exit point) آن مي‌باشند. عبارات كنترلي تك‌ورودي/تك‌خروجي ايجاد آسانتر برنامه‌ها را ممكن مي‌سازند. نقطه خروجي يك عبارت كنترلي را مي‌توان به نقطه ورودي عبارت كنترلي ديگري متصل كرد و به همين ترتيب ادامه داد. اين فرآيند همانند قرار دادن بلوك‌هاي بر روي هم است، از اينرو اين روش، عبارت كنترلي پشته (control structure stacking) نام دارد. اين روش يكي از روش‌هاي موجود براي متصل كردن عبارات كنترلي به يكديگر است. يك روش ديگر عبارت كنترلي تودرتو يا آشيانه‌اي (control structure nesting) مي‌باشد كه در آن يك عبارت كنترلي مي‌تواند در درون عبارت ديگري قرار گيرد. بنابر اين الگوريتم‌ها در برنامه‌هاي C++ فقط متشكل از سه نوع عبارت كنترلي تركيب شده با اين دو روش هستند.

 

مهندسي نرم‌افزار

هر برنامه را مي‌توان با هفت نوع عبارت كنترلي ايجاد كرد (توالي، if ، if.. else ، switch ، while ، do..while و for ) كه به دو روش با هم تركيب مي‌شوند (عبارت كنترلي پشه‌اي و تو در تو يا آشيانه‌اي).

 

5-4  عبارت انتخاب if

در يك عبارت انتخاب، هدف برگزيدن يكي از گزينه‌هاي موجود براي انجام آن است. براي مثال، فرض كنيد كه شرط قبولي در يك امتحان نمره 60 است از ( 100 ). عبارت شبه‌كد آن بصورت زير مي‌باشد:

If student’s grade is greater than or equal to 60

                Print “Passed”

شرط “student’s grade is greater than or equal to 60” مي‌تواند برقرار باشد يا نباشد. اگر شرط برقرار باشد عبارت “Passed” به معني قبول شدن به نمايش در مي‌آيد و عبارت پس از شبه‌كد به ترتيب اجرا مي‌شود (بياد داشته باشيد كه شبه‌كد يك زبان برنامه‌نويسي واقعي نيست). اگر شرط برقرار نباشد عبارت چاپ ناديده گرفته مي‌شود و عبارت شبه‌كد بعدي به ترتيب اجرا خواهد شد. عبارت موجود در بدنه عبارت if رشته " Passed " را ب ه چاپ مي‌رساند. همچنين به دندانه‌دار بودن اين عبارت در اين عبارت انتخاب دقت كنيد. دندانه‌ گذاري امري اختياري است، اما بكارگيري آن بسيار توصيه مي‌شود چرا كه ارتباط عبارتهاي مختلف برنامه را بخوبي نشان مي‌دهند. كامپايلر C++ كاراكترهاي whitespace يعني كاراكترهاي فاصله، tab و خطوط جديد بكار رفته در ايجاد دندانه‌ها و فاصله‌گذاري عمودي را بجز كاراكترهاي whitespace بكار رفته در رشته‌ها، در نظر نمي‌گيرد.

 

برنامه‌نويسي ايده‌ال

سعي كنيد از روش دندانه‌گذاري ثابتي در برنامه‌هاي خود استفاده كنيد تا خوانايي برنامه‌ افزايش يابد.

 

مي‌توان اين عبارت شبه‌كد if را در زبان C++ بصورت زير نوشت

if (grade >= 60 )

          cout << “Passed”;

اگر به كد C++ دقت كنيد متوجه شباهت نزديك آن با شبه‌كد خواهيد شد و نقش شبه‌كد به عنوان يك ابزار توسعه برنامه بخوبي آشكار مي‌شود.

در شكل 4-4 دياگرام فعاليت عبارت تك‌انتخابي if نشان‌داده شده است. اين دياگرام حاوي يكي از مهمترين نمادها در يك دياگرام فعاليت است. نماد لوزي يا نماد تصميم نشان مي‌دهد كه بايد در آن نقطه تصميمي اتخاذ گردد. نماد تصميم‌گيري بر اين نكته دلالت دارد كه روند كار در امتداد مسيري به كار ادامه خواهد داد كه توسط نماد وابسته نگهبان شرط تعيين مي‌شود (آيا شرط برقرار است يا خير). هر فلش يا بردار انتقال خارج شده از يك نماد تصميم داراي يك نگهبان شرط است (در درون براكت‌هاي مربعي در بالا يا كنار فلش انتقال جاي مي‌گيرد). اگر شرط يك نگهبان شرط برقرار باشد، روند كار وارد وضعيت عملي مي‌شود كه فلش انتقال به آن اشاره مي‌كند. در شكل 4-4 اگر grade بزرگتر يا برابر 60 باشد، برنامه كلمه "Passed" را بر روي صفحه نمايش چاپ كرده و سپس انتقال به وضعيت پاياني در اين فعاليت مي‌رسد. اگر grade كوچكتر از 60 باشد، بلافاصله برنامه به وضعيت پاياني منتقل مي‌شود، بدون اينكه پيغامي چاپ كند.

 

 

انجمن برنامه نويسي راسخون |‌‌ www.rasekhoon.net |

شكل 4-4 | دياگرام فعاليت عبارت if .

در فصل اول آموختيم، تصميم‌گيري مي‌تواند براساس شرط‌هايي صورت گيرد كه حاوي عملگرهاي رابطه‌اي يا برابري هستند. در واق ع ، در C++ يك شرط مي‌تواند بر پايه هر عبارتي ارزيابي گردد، اگر عبارت با صفر ارزيابي شود، با آن همانند false (عدم برقراري شرط ) رفتار خواه د شد و اگر عبارت با مقداري غير از صفر ارزيابي گردد، با آن همانند true (برقراري شرط) رفتار مي‌شود. زبان C++ داراي نوع داده بولي ( bool) براي متغيرهايي است كه فقط قادر به نگهداري مقادير true و false هستند، كه هر دو جزء كلمات كليدي در C++ مي‌باشند.

 

قابليت حمل

براي حفظ سازگاري با نسخه‌هاي قبلي C كه از اعداد صحيح براي مقادير بولي استفاده مي‌كردند، مي‌توان براي عرضه يك مقدار بولي true از هر مقدار غيرصفري استفاده كرد (معمولاً كامپايلرها از 1 استفاده مي‌كنند). براي عرضه يك مقدار بولي false نيز مي‌توان از مقدار صفر استفاده كرد.

 

دقت كنيد كه عبارت if يك عبارت تك‌ورودي / تك‌خروجي است. همچنين دياگرام‌هاي مابقي عبارات كنترلي نيز حاوي نمادهاي وضعيت اوليه، فلش‌هاي انتقال، وضعيت اجرا، تصميم‌گيري و وضعيت پاياني هستند. به اين نحوه نمايش عبارات كنترلي روش مدل برنامه‌نويسي اجرائي/تصميم‌گيري گفته مي‌شود.

مي‌توانيم هفت صندوق را تصور كنيم كه هر كدام فقط حاوي دياگرام‌هاي فعاليت UML خالي از يكي از هفت نوع عبارت (ساختار) كنترلي است. وظيفه برنامه‌نويس جفت‌وجور كردن برنامه با سرهمبندي كردن دياگرام فعاليت به هر تعداد از هر نوع عبارت كنترلي تصريح شده در الگوريتم است كه فقط به دو روش قابل انجام است، روش پشته‌اي و تودرتو. در ادامه وضعيت‌هاي عمل و تصميم‌گيري را با عبارات اجرايي و نگهبانان شرط به روش مقتضي پر مي‌كند. در ارتباط با نوشتن انواع روش‌هايي كه مي‌تواند در عبارات اجرايي و تصميم‌گيري بكار گرفته شوند، صحبت خواهيم كرد.

 

 

انجمن برنامه نويسي راسخون |‌‌ www.rasekhoon.net |

شكل 4-4 | دياگرام فعاليت عبارت تك انتخابي if .

 

6-4 عبارت انتخاب if..else

همانطوري كه گفته شد عبارت انتخاب if فقط در صورت برقرار بودن شرط، عملي را به اجرا در مي‌آورد، در غير اينصورت از روي عبارت يا عبارات پرش مي‌كند. عبارت انتخاب if..else اين امكان را به برنامه‌نويس مي‌دهد كه تعيين كند چه اعمالي در برقرار بودن شرط اجرا شوند و چه اعمالي در حالت برقرار نبودن شرط به اجرا در آيند. براي مثال، در شبه‌كد زير

If Student’s grade is greater than or equal to 60

              Print “Passed”

Else

              Print “Failed”

اگر نمره دانش‌آموز برابر 60 يا بالاتر باشد، عبارت “Passed” به نمايش در مي‌آيد و اگر كمتر از آن باشد عبارت " Failed ". در هر دو حالت پس از انجام عمل چاپ، عبارت شبه‌كد بعدي به اجرا گذاشته خواهد شد.

عبارت شبه‌كد if..else مطرح شده را مي‌توان در زبان C++ و به فرم زير نوشت:

if (grade >= 60 )

          cout << “Passed”;

else

          cout << “Failed”;

به دندانه‌دار بودن بدنه شرط else دقت كنيد كه با خطوط بالاي خود در شرط if يكسان قرار گرفته‌اند.

 

 

برنامه‌نويسي ايده‌ال

دندانه‌دار نوشتن هر دو قسمت بدنه عبارت if..else خوانائي برنامه را افزايش مي‌دهد.

 

در شكل 5-4 روند كنترل جريان در يك عبارت (ساختار) if..else نشان داده شده است. مجدداً توجه كنيد (در كنار وضعيت اوليه، فلش‌هاي انتقال و وضعيت پاياني) كه نمادهاي بكار رفته در اين دياگرام فعاليت عبارتند از نمادهاي عمل و تصميم‌گيري و تاكيد ما بر مدل‌سازي عمل/ تصميم‌گيري است. مجدداً به صندو‌ق‌هاي خالي از دياگرام‌هاي فعاليت عبارات انتخاب دوگانه فكر كنيد كه برنامه‌نويس مي‌تواند به روش پشته‌اي يا تودرتو با ساير دياگرام‌هاي فعاليت ساختارهاي كنترلي بكار گيرد تا مبادرت به پياده‌سازي الگوريتم كند.

 

 

شكل 5-4 دياگرام فعاليت عبارت دو انتخابي if..else

عملگر شرطي (?:)

زبان C++ حاوي عملگر شرطي (?:) ، است كه قرابت نزديكي با عبارت if..else دارد. عملگر شرطي C++ تنها عملگر ternary است، به اين معني كه سه عملوند دريافت مي‌كند. عملوندها به همراه عملگر شرطي تشكيل عبارت شرطي را مي‌دهند. عملوند اول نشاندهنده شرط مي‌باشد، عملوند دوم مقداري است كه در صورت true بودن شرط انتخاب مي‌شود و عملوند سوم مقداري است كه در صورت برقرار نبودن شرط يا false بودن آن انتخاب مي‌شود. براي مثال عبارت زير

cout << (grade >= 60 ? ”Passed” : ”Failed” );

حاوي يك عبارت شرطي، ا ست كه در صورت برقرار بودن شرط grade >= 60 رشته “Passed” ارزيابي مي‌شود، اما اگر شرط برقرار نباشد، رشته “Failed” بكار گرفته خواهد شد. از اينرو عملكرد اين عبارت شرطي دقيقا همانند عملكرد عبارت if..else قبلي است. عملگر شرطي از تقدم پايين‌تري برخوردار است و از اينرو معمولا كل عبارت شرطي را در درون پرانتزها قرار مي‌دهند.

اجتناب از خطا

براي اجتناب از مشكل اولويت و روشن شدن مطلب، سعي كنيد عبارات شرطي (كه در عبارات بزرگ شركت مي‌كنند) را در درون پرانتزها قرار دهيد.

 مقادير موجود در يك عبارت شرطي قادر به اجرا شدن نيز هستند. براي مثال عبارت شرطي زير مبادرت به چاپ "Passed" يا "Failed" مي‌كند.

grade >= 60 ? cout << "Passed" : cout << "Failed";

اين عبارت به صورت زير تفسير مي‌شود «اگر grade بزرگتر يا مساوي 60 باشد، پس cout<<"Passed" ، در غير اينصورت ".cout<<"Faild" همچنين اين عبارت قابل مقايسه با عبارت if..else قبلي است. عبارات شرطي را مي‌توان در مكان‌هاي از برنامه‌ كه امكان استفاده از if..else وجود ندارد، بكار گرفت.

عبارات تودرتوي if..else

عبارت تودرتوي if..else براي تست چندين شرط با قرار دادن عبارتهاي if..else در درون عبارتهاي if..else ديگر است. براي مثال، عبارت شبه‌كد زير، حرف “A” را براي نمره‌هاي بزرگتر يا برابر 90 ، “B” را براي نمره‌هاي در محدودة 80-89 ، “C” را براي نمره‌هاي در محدودة 70-79 ، “D” را براي نمره‌هاي در محدودة 60-69 و “F” را ساير نمرات به چاپ مي‌رساند.

If student’s grade is greater then or equal to 90

          Print “A”

Else

          If student’s grade is greater than or equal to 80

                          Print “B”

          Else

                          If student’s grade is greater than or equal to 70

                                          Print “C”

                          Else

                                          If student’s grade is greater than or equal to 60

                                                          Print “D”

                       Else

                                                          Print “F”

عبارت شبه‌كد بالا را مي‌توان در زبان C++ و به فرم زير نوشت:

if (studentGrade>=90) // 90 and above gets "A"

    cout << “A”;

else

   if (studentGrade>=80) // 80-89 gets "B"

            cout << “B”;

   else

           if (strudentGrade>=70) // 70-79 gets "C"

              cout << “C”;

           else

              if (studentGrade>=60) // 60-69 gets "D"

                          cout << “D”;

              else // less than 60 gets "F"

                          cout << “F”;

                                         

اگر مقدار studentGrade بزرگتر يا مساوي 90 باشد، اولين شرط از پنج شرط برقرار شده و فقط عبارت cout قرار گرفته در بدنه اولين شرط به اجرا در مي‌آيد. پس از اجراي اين عبارت از بخش else خارجي عبارت if..else عبور خواهد شد.

برنامه‌نويسي ايده‌ال

قبل و بعد از هر عبارت كنترل يك خط خالي قرار دهيد تا بتوان عبارتهاي كنترل را از ساير نقاط برنامه تشخيص داد.

اكثر برنامه‌نويسان C++ ترجيح مي‌دهند كه عبارت if..else را با استفاده از كلمه كليدي else if و بصورت زير در برنامه‌هاي خود بنويسند:

if (studentGrade>=90) // 90 and above gets "A"

          cout << “A”;

else if (studentGrade>=80) // 80-89 gets "B"

          cout << “B”;

else if (studentGrade>=70) // 70-79 gets "C"

          cout << “C”;

else if (studentGrade>=60) // 60-69 gets "D"

          cout << “D”;

else // less than 60 gets "F"

          cout << “F”;

هر دو حالت معادل يكديگرند، اما نوع آخر در نزد برنامه‌نويسان از محبوبيت بيشتري برخوردار است. چرا كه از دندانه‌دار كردن عميق كد به طرف راست اجتناب مي‌شود.

كارائي

يك عبارت if..else تودرتو مي‌تواند بسيار سريعتر از يك سري عبارت if عمل كند، چرا كه احتمال دارد شرطي در ابتداي عبارت if..else برقرار شود و كنترل برنامه زودتر از اين قسمت خارج گردد.

 

كارائي

در يك عبارت if..else تودرتو، شرط‌هايي كه امكان برقرار شدن (true) آنها بيشتر است در ابتداي عبارت if..else تودرتو قرار دهيد. در اينحالت امكان اجراي سريعتر عبارت if..else فراهم مي‌آيد.

 

 

مشكل dangling-else

هميشه كامپايلر C++ يك else را با يك if در نظر مي‌گيرد، مگر اينكه خلاف آنرا با استفاده از براكت‌ها مشخص كنيد. به اين مشكل dangling-else  مي‌گويند. براي مثال،

if ( x > 5 )

   if ( y > 5 )

       cout << "x and y are > 5";

else

       cout << "x is <=5";

به نظر مي‌رسد بر اين نكته دلالت دارد كه اگر x بزرگتر از 5 باشد، عبارت if تودرتو تعيين مي‌كند كه آيا y نيز بزرگتر از 5 است يا خير. اگر چنين باشد، رشته "x and y are > 5" در خروجي چاپ مي‌شود. در غير اينصورت اگر x بزرگتر از 5 نباشد، بخش else از عبارت if..else رشته "x is <=5" را چاپ خواهد كرد.

با اين همه امكان دارد عبارت if تودرتوي فوق مطابق با انتظار كار نكند. تفسير كامپايلر از عبارت بصورت زير خواهد بود

if ( x > 5 )

   if ( y > 5 )

      cout << "x and y are > 5";

   else

      cout << "x is <=5";

كه در آن بدنه اولين عبارت if يك عبارت if..else تودرتو است. اين عبارت مبادرت به تست بزرگتر بودن x از 5 مي‌كند. اگر چنين باشد، اجرا با تست y بزرگتر از 5 ادامه مي‌يابد. اگر شرط دوم برقرار باشد، رشته "x and y are >5" به نمايش در خواهد آمد. با اين همه اگر شرط دوم برقرار نباشد، رشته  "x  is <=5" به نمايش در مي‌آيد، حتي اگر بدانيم كه x بزرگتر از 5 است.

براي اينكه عبارت فوق بنحوي كار كند كه از انتظار داريم، بايستي كل عبارت بصورت زير نوشته شود:

if ( x > 5 )

{

   if ( y > 5 )

      cout << "x and y are > 5";

}

   else

      cout << "x is <=5";

براكت‌ها به كامپايلر نشان مي‌دهند كه دومين if در بدنه اولين if قرار دارد و else در ارتباط با اولين if مي‌باشد.

بلوك‌ها

معمولا عبارت انتخاب if فقط منتظر يك عبارت در بدنه خود است. به همين ترتيب، هر يك از بخش‌هاي else و if در يك عبارت if..else انتظار مقابله با يك عبارت در بدنه خود را دارند. براي وارد كردن چندين عبارت در بدنه يك if يا در بخش‌هاي if..else ، عبارات را در درون براكت‌ها ( { } ) قرار دهيد. به مجموعه‌اي از عبارات موجود در درون يك جفت براكت، بلوك مي‌گويند.

مهندسي نرم‌افزار

يك بلوك مي‌تواند در هر كجاي برنامه كه يك عبارت منفرد مي‌تواند در آنجا قرار داده شود، جاي گيرد.

مثال زير شامل يك بلوك در بخشي از else يك عبارت if..else است.

if (studentGrade>=60)

    cout << “Passed.\n”;

else

{

   cout << “Failed.\n”;

   cout << "You must take this course again.\n"

}

در اين مورد، اگر studentGrade كمتر از 60 باشد، برنامه هر دو عبارت موجود در بدنه else را اجرا كرده و پيغام‌هاي زير را چاپ مي‌كند.

Failed

You must take this course agein.

به براكت‌هاي احاطه‌كننده دو عبارت در ضابطه else دقت كنيد. اين براكت‌ها مهم هستند. بدون اين براكت‌ها، عبارت

cout << "You must take this course again.\n";

در خارج از بدنه بخش else قرار مي‌گيرد و صرفنظر از اينكه شرط برقرار باشد يا خير، اجرا خواهد شد. اين مثال نمونه‌اي از يك خطاي منطقي است.

 

خطاي برنامه‌نويسي

فراموش كردن يك يا هر دو براكت كه تعيين محدودة يك بلوك هستند، مي‌تواند موجب خطاي نحوي يا منطقي در برنامه شود.

 

برنامه‌نويسي ايده‌ال

هميشه از براكت‌ها در عبارت if..else (يا هر عبارت كنترلي) استفاده كنيد تا جلوي حوادث ناخواسته گرفته شود، بويژه به هنگام افزودن عباراتي به يك if يا ضابطه else در ادامه كار. براي اينكه جلوي فراموش‌كاري گرفته شود، برخي از برنامه‌نويسان در همان ابتداي كار و قبل از اينكه حتي عبارتي تايپ كرده باشد، براكت‌هاي شروع و پايين را تايپ مي‌كنند و سپس عبارات مورد نظر را در درون آنها قرار مي‌دهد.

 

همانند يك بلوك كه مي‌تواند در هر كجاي كه يك عبارت منفرد وجود دارد جايگزين گردد، همچنين امكان داشتن عبارت null (يا عبارت تهي) وجود دارد. عبارت تهي با جايگزين كردن يك سيمكولن ( ; ) بجاي يك عبارت مشخص مي‌شود.

 

 

 

خطاي برنامه‌نويسي

قرار دادن يك سيمكولن بلافاصله پس از شرط در يك عبارت if موجب رخ دادن خطاي منطقي در عبارات if تك انتخابي و خطاي نحوي در عبارات if..else دو انتخابي خواهد شد.

 

تشکرات از این پست
iman_karbala
دسترسی سریع به انجمن ها