0

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

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

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

 

7-4 عبارت تكرار while

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

While there are more items on my shopping list

      Purchase next item and cross it off my list

شرط " there are more items on my shopping list " ممكن است برقرار يا برقرار نباشد. اگر شرط برقرار باشد عمل " Purchase next item " و " Cross it off my list " به ترتيب اجرا خواهند شد. اين عمل مي‌تواند تا زماني كه شرط برقرار است انجام شود. عبارت موجود در ساختار تكرار while تشكيل دهنده بدنه while است. سرانجام، زمانيكه شرط برقرار نباشد، تكرار پايان يافته و اولين دستور قرار گرفته پس از عبارت تكرار به اجرا در مي‌آيد .

مثالي كه در زير آورده شده از عبارت while استفاده كرده و اولين توان 3 بزرگتر از 100 را پيدا مي‌كند. در ابتداي كار متغير product با 3 مقدار دهي اوليه شده است :

int product = 3;  

 

while (product <= 100)

product = product * 3;

هنگامي كه برنامه وارد عبارت while مي‌شود، مقدار متغير product برابر 3 است. متغير product بصورت مكرر در 3 ضرب مي‌شود و مقادير 9 ، 27 ، 81 و 243 بدست مي‌آيند. زمانيكه مقدار product برابر 243 شود، شرط product<=100 در عبارت while برقرار نخواهد شد. در چنين حالتي تكرار با مقدار 243 براي product پايان مي‌پذيرد. اجراي برنامه با عبارت بعد از while دنبال مي‌شود. [نكته: اگر شرط يك عبارت while در همان ابتدا برقرار نباشد، عبارات قرار گرفته در بدنه عبارت تكرار اجرا نخواهند شد.]

 

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

شرط عبارت تكرار را به نوعي تنظيم نمائيد كه برنامه براي هميشه در داخل حلقه قرار نگيرد، در غير اينصورت برنامه در حلقه بي‌نهايت “infinite loop” گرفتار مي‌شود.

 

دياگرام فعاليت UML به نمايش درآمده در شكل 6-4 نشاندهنده روند كنترلي است كه متناظر با عبارت while مطرح شده در قسمت فوق مي‌باشد. مجدداً نمادهاي موجود در اين دياگرام نشاندهنده يك وضعيت عمل و يك تصميم‌گيري هستند. همچنين اين دياگرام مبادرت به معرفي نماد ادغام UML كرده است، كه دو روند يا جريان فعاليت را به يك فعاليت متصل مي‌كند. UML نماد ادغام و تصميم‌گيري را بصورت لوزي نشان مي‌دهد. در اين دياگرام، نماد ادغام مبادرت به پيوند انتقال‌ها از وضعيت اوليه و از وضعيت عمل كرده است، از اينرو هر دو جريان وارد بخش تصميم شده‌اند كه تعيين مي‌كند آيا حلقه مجدداً بايد تكرار شود يا خير. مي‌توان نمادهاي تصميم و ادغام را توسط تعداد فلش‌هاي انتقال «واردشونده» و «خارج‌شونده» تشخيص داد. نماد تصميم داراي يك فلش انتقال اشاره‌كننده به لوزي داشته و داراي دو يا چند فلش انتقال اشاره‌كننده به خارج از لوزي است كه نشاندهنده انتقالات ممكنه از اين نقطه هستند. علاوه بر اين، هر فلش انتقال اشاره‌كننده به خارج از نماد تصميم داراي يك نگهبان شرط در كنار خود است. در طرف ديگر، نماد ادغام قرار دارد كه داراي دو يا چند فلش انتقال اشاره‌كننده به لوزي است و فقط يك فلش انتقال از آن خارج مي‌شود و نشان مي‌هد كه چندين روند با يكديگر براي انجام فعاليت ادغام شده‌اند. توجه كنيد، كه برخلاف نماد تصميم، نماد ادغام داراي يك رونوشت در كد C++ نيست.

دياگرام شكل 6-4 بوضوح عمليات تكرار در عبارت while مطرح شده در ابتداي اين بخش را نشان مي‌دهد. فلش انتقال از وضعيت عمل به حالت ادغام اشاره مي‌كند، كه انتقال را به تصميم باز مي‌گرداند تا تستي داير بر اينكه آيا حلقه دوباره بايد صورت گيرد يا خير انجام دهد، اين حلقه زماني شكسته مي‌شود كه شرط product>100 برقرار گردد. پس از خاتمه عمليات while ، كنترل به عبارت بعدي در برنامه انتقال مي‌يابد (در اين مورد وضعيت پاياني).

مي‌توانيد دياگرام‌هاي فعاليت UML خالي عبارت تكرار while را تصور كنيد كه برنامه‌نويسان مي‌توانند هر تعداد از آنها را به روش پشته‌اي يا تودرتو با ساير دياگرام‌هاي فعاليت عبارات كنترلي بكار گيرند تا بخشي از الگوريتم را پياده‌سازي كنند.

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

8-4 فرموله كردن الگوريتم: شمارنده-كنترل تكرار

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

از كلاسي با ده دانش‌آموز آزموني بعمل آمده است. نمرات اين آزمون در اختيار شما قرار دارد (نمرات در محدودة 0 تا 100 هستند). مجموع نمرات دانش‌آموزان و ميانگين نمرات اين كلاس را بدست آوريد.

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

الگوريتم شبه‌كد با شمارنده-كنترل تكرار

اجازه دهيد تا از شبه‌كد استفاده كرده و ليستي از فعاليت‌هاي اجرائي تهيه و ترتيب اجرا را مشخص سازيم. از روش شمارنده-كنترل تكرار براي دريافت تك تك نمرات بعنوان ورودي استفاده مي‌كنيم. در اين تكنيك از متغيري بنام شمارنده (counter) براي تعيين تعداد دفعات مجموعه‌اي از عبارات كه اجرا خواهند شد، استفاده مي‌شود. روش شمارنده-كنترل تكرار، روش تكرار تعريف شده نيز ناميده مي‌شود چرا كه تعداد تكرار قبل از اينكه حلقه آغاز شود، مشخص است. در اين مثال، اجراي حلقه با رسيدن شمارنده به 10 خاتمه مي‌يابد. در اين بخش به معرفي الگوريتم شبه‌كد (شكل 7-4) و نسخه‌اي از كلاس GradeBook (شكل‌هاي 8-4 و 9-4) مي‌پردازيم كه الگوريتم را توسط يك تابع عضو C++ پياده‌سازي مي‌كند . در بخش ‌9-4 با توسعه الگوريتم‌ها با استفاده از شبه‌كد آشنا خواهيد شد.

به نقش total و counter در الگوريتم شبه‌كد دقت كنيد (شكل 7-4). در واقع total متغيري است كه از آن براي محاسبه مجموع مقادير استفاده مي‌شود و counter متغيري است كه نقش شمارنده بر عهده دارد، در اين برنامه، شمارنده تعداد نمرات وارد شدة توسط كاربر را ثبت مي‌كند.

Set total to zero

Set grade counter to one

While grade counter is less than or equal to 10

      Input the next grade

      Add the grade to the total

      Add one to the grade counter

Set the class average to the total divided by 10

Print the class average

شكل7-4      | الگوريتم شبه‌كد با استفاده از روش شمارنده-كنترل تكرار براي حل مسئله ميانگين كلاس.

1       // Fig. 4.8: GradeBook.h

2       // Definition of class GradeBook that determines a class average.

3       // Member functions are defined in GradeBook.cpp

4        include <string> // program uses C++ standard string class

5       using std::string;

6        

7       // GradeBook class definition

8       class GradeBook

9       {

10    public:

11       GradeBook( string ); // constructor initializes course name

12       void setCourseName( string ); // function to set the course name

13       string getCourseName(); // function to retrieve the course name

14       void displayMessage(); // display a welcome message

15       void determineClassAverage(); // averages grades entered by the user

16    private:

17       string courseName; // course name for this GradeBook

18    }; // end class GradeBook

شكل 8-4      | مسئلهميانگينكلاسبااستف اده از روش شمارنده-كنترل تكرار:سرآيند فايل GradeBook .

1       // Fig. 4.9: GradeBook.cpp

2       // Member-function definitions for class GradeBook that solves the

3       // class average program with counter-controlled repetition.

4        include <iostream>

5       using std::cout;

6       using std::cin;

7       using std::endl;

8        

9        include "GradeBook.h" // include definition of class GradeBook

10     

11    // constructor initializes courseName with string supplied as argument

12    GradeBook::GradeBook( string name )

13    {

14       setCourseName( name ); // validate and store courseName

15    } // end GradeBook constructor

16     

17    // function to set the course name;

18    // ensures that the course name has at most 25 characters

19    void GradeBook::setCourseName( string name )

20    {

21       if ( name.length() <= 25 ) // if name has 25 or fewer characters

22          courseName = name; // store the course name in the object

23       else // if name is longer than 25 characters

24       { // set courseName to first 25 characters of parameter name

25          courseName = name.substr( 0, 25 ); // select first 25 characters

26         cout << "Name \"" << name << "\" exceeds maximum length (25).\n"

27    << "Limiting courseName to first 25 characters.\n" << endl;

28       } // end if...else

29    } // end function setCourseName

30     

31    // function to retrieve the course name

32    string GradeBook::getCourseName()

33    {

34       return courseName;

35    } // end function getCourseName

36     

37    // display a welcome message to the GradeBook user

38    void GradeBook::displayMessage()

39    {

40       cout << "Welcome to the grade book for\n" << getCourseName() << "!\n"

41    << endl;

42    } // end function displayMessage

43     

44    // determine class average based on 10 grades entered by user

45    void GradeBook::determineClassAverage()

46    {

47       int total; // sum of grades entered by user

48       int gradeCounter; // number of the grade to be entered next

49       int grade; // grade value entered by user

50       int average; // average of grades

51     

52       // initialization phase

53       total = 0; // initialize total

54       gradeCounter = 1; // initialize loop counter

55     

56       // processing phase

57       while ( gradeCounter <= 10 ) // loop 10 times

58       {

59          cout << "Enter grade: "; // prompt for input

60          cin >> grade; // input next grade

61           total = total + grade; // add grade to total

62          gradeCounter = gradeCounter + 1; // increment counter by 1

63       } // end while

64     

65       // termination phase

66       average = total / 10; // integer division yields integer result

67     

68       // display total and average of grades

69       cout << "\nTotal of all 10 grades is " << total << endl;

70       cout << "Class average is " << average << endl;

71    } // end function determineClassAverage

شكل 9-4 | مسئلهميانگينكلاسبااستفادهازروششمارنده - كنترلتكرار : كدمنبعفايل GradeBook .

افزايش قابليت اعتبارسنجي GradeBook

قبل از اينكه به بحث پياده‌سازي الگوريتم ميانگين كلاس بپردازيم، اجازه دهيد به بهبود كارائي انجام گرفته بر روي كلاس GradeBook توجه كنيم. در برنامه 16-3، تابع setCourseName مبادرت به اعتبارسنجي نام دوره با تست طول نام دور مي‌كرد، كه بايد كمتر يا برابر 25 كاراكتر باشد (با استفاده از يك عبارت if ). اگر شرط برقرار بود، نام دوره بكار گرفته مي‌شد. سپس اين كد با يك عبارت if ديگر دنبال مي ‌شد كه مبادرت به تست طول نام دوره مي‌كرد كه آيا بزرگتر از 25 كاراكتر است يا خير. دقت كنيد كه شرط عبارت if دوم كاملاً متضاد شرط if اول است. اگر شرطي با true ارزيابي گردد، بايستي شرط‌هاي ديگر با false ارزيابي شوند. پياده‌سازي چنين وضعيتي توسط عبارت if..else بهتر خواهد بود، از اينرو كد خود را با جايگزين كردن دو عبارت if با يك عبارت if..else اصلاح كرده‌ايم (خطوط 21-28 از برنامه شكل 9-4).

1       // Fig. 4.10: fig04_10.cpp

2       // Create GradeBook object and invoke its determineClassAverage function.

3        include "GradeBook.h" // include definition of class GradeBook

4        

5       int main()

6       {

7          // create GradeBook object myGradeBook and

8          // pass course name to constructor

9          GradeBook myGradeBook( "CS101 C++ Programming" );

10     

11       myGradeBook.displayMessage(); // display welcome message

12       myGradeBook.determineClassAverage (); // find average of 10 grades

13       return 0; // indicate successful termination

14    } // end main

 

شكل10-4| برنامه ميانگين كلاس با شمارنده-كنترل تكرار:ايجاد يك شي از كلاس GradeBook (شكل 8-4 و 9-4) و فراخواني تابع عضو determineClassAverage .

پياده‌سازي شمارنده-كنترل تكرار در كلاس GradeBook

كلاس GradeBook (شكل 8-4 و 9-4) حاوي يك سازنده (اعلان شده در خط 11 از شكل 8-4 و تعريف شده در خطوط 12-15 از شكل 9-4) است كه مبادرت به تخصيص مقداري به متغير نمونه كلاس courseName مي‌كند (اعلان شده در خط 17 از شكل 8-4). در خطوط 19-29 ، 32-35 و 38-42 از شكل 9-4 توابع عضو setCourseName ، getCourseName و displayMessage تعريف شده‌اند. در خطوط 45-71 تابع عضو determineClassAverage تعريف شده است كه پياده ‌سازي‌كننده الگوريتم ميانگين كلاس توضيح داده شده در شبه كد شكل 7-4 است.

در خطوط 47-50 متغيرهاي محلي total ، gradeCounter ، grade و average از نوع int اعلان شده‌اند. در متغير grade ورودي كاربر ذخيره مي‌شود. توجه كنيد كه اعلان‌هاي فوق در بدنه تابع عضو determineClassAverage قرار دارند.

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

 

 

 

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

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

در خطوط 53-54 متغير total با 0 و gradeCounter با 1 مقداردهي اوليه شده‌اند.دقت كنيد كه متغيرهاي totoal و gradeCounter قبل از اينكه در محاسبات بكار گرفته شوند، مقداردهي اوليه شده‌اند. معمولاً متغيرهاي شمارنده را با يك يا صفر و بر اساس نياز مقداردهي اوليه مي‌كنند. يك متغير مقداردهي نشده حاوي يك مقدار اشغال (يا مقدار تعريف نشده) است، آخرين مقداري كه در مكان حافظه رزرو شده براي متغير از قبل وجود داشته است. در اين برنامه متغيرهاي grade و average كه مقدار خود را از طرف ورودي كاربر و محاسبه ميانگين بدست مي‌آورند، نيازي به مقداردهي اوليه ندارند.

خط 57 مشخص مي‌كند كه عبارت while تا زمانيكه مقدار gradeCounter كمتر يا معادل 10 باشد، تكرار خواهد شد. تا زمانيكه شرط برقرار باشد، ساختار while عبارات قرار گرفته مابين براكت‌هاي بدنه خود را تكرار خواهد كرد.

 عبارت بكار رفته در خط 59 ، جمله "Enter grade:" را بنمايش در مي‌آورد. اين خط معادل عبارت شبه‌كد “Prompt the user to enter the next grade.” هستند. خط 60 مقدار وارد شده توسط كاربر را خوانده و آنرا در متغير grade ذخيره مي‌كند. اين خط معادل شبه‌كد "Input the next grade." است. بخاطر داريد كه متغير grade در ابتداي برنامه مقداردهي اوليه نشده است، به اين دليل كه برنامه مقدار grade را از كاربر و در هر بار تكرار حلقه اخذ مي‌كند. سپس، برنامه مقدار total را با مقدار جديد grade كه توسط كاربر وارد شده به روز مي‌كند (خط 61 ) . مقدار grade با مقدار قبلي total جمع شده و نتيجه به total تخصيص مي‌يابد.

در خط 62 متغير gradeCounter   يك واحد افزايش مي‌يابد تا نشان دهد يك نمره مورد پردازش قرار گرفته است. اينكار تا زمانيكه شرط موجود در عبارت while برقرار نشود، ادامه مي‌يابد. پس از اتمام حلقه، در خط 66 نتيجه محاسبه ميانگين به متغير average تخصيص مي‌يابد. خط 69 پيغام "Total of all 10 grades is" و بدنبال آن مقدار متغير total را بنمايش در مي‌آورد. سپس در خط 70 پيغامي حاوي رشته “Class average is” كه بدنبال آن مقدار متغير average آورده شده، به نمايش در مي‌آيد. تابع عضو determineClassAverage ، كنترل را به تابع فراخوان برگشت مي‌دهد (تابع main در شكل 10-4).

توصيف كلاس GradeBook

شكل 10-4 حاوي تابع main اين برنامه است، كه يك شي از كلاس GradeBook ايجاد و به توصيف قابليت‌هاي آن مي‌پردازد. در خط 9 از شكل10-4 يك شي جديد از GradeBook بنام myGradeBook ايجاد مي‌شود. رشته موجود در خط 9  به سازنده GradeBook ارسال مي‌شود (خطوط 15-12 از شكل 9-4). خط 11 از شكل10-4 تابع عضو displayMessage را براي نمايش پيغام‌ خوش‌آمدگويي به كاربر فراخواني مي‌كند. سپس خط 12 تابع عضو determineClassAverage را فراخواني مي‌كند تا كاربر بتواند 10 نمره را وارد كرده و سپس ميانگين را محاسبه و چاپ مي‌كند. تابع عضو، الگوريتم نشان داده شده در شبه كد شكل 7-4 را انجام مي‌دهد.

نكاتي در ارتباط با تقسيم صحيح و قطع كردن

محاسبه ميانگين توسط تابع عضو determineClassAverage صورت مي ‌گيرد كه در واكنش به فراخواني تابع در خط 12 از شكل10-4 فعال شده و يك عدد صحيح توليد مي‌كند. خروجي برنامه نشان مي‌دهد كه مجموع نمرات در اجراي نمونه برنامه 846 است كه به هنگام تقسيم بر 10 ، بايد 84.6 بدست آيد، عددي با نقطه اعشار. با اين همه، در نتيجه محاسبه total/10 عدد 84 بدست آمده است (خط 66 از شكل 9-4)، چرا كه total و 10 هر دو مقادير عددي صحيح هستند. نتيجه تقسيم دو عدد صحيح يك عدد صحيح است كه در آن بخش اعشاري بدست آمده از تقسيم حذف مي‌گردد (قطع مي‌شود). در بخش بعد با نحوه بدست آوردن نتايج اعشاري از محاسبات آشنا خواهيد شد.

 

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

فرض اينكه تقسيم صحيح مبادرت به گرد كردن (بجاي قطع كردن) مي‌كند مي‌تواند نتايج اشتباهي بدنبال داشته باشد. براي مثال، 7 ¸ 4 حاصل 1.75 را در رياضي بدست مي‌دهد، در حاليكه در يك تقسيم صحيح 1 كوتاه شده و 2 در حالت گرد شده توليد مي‌كند.

در برنامه شكل 9-4، اگر در خط 66 از gradeCounter بجاي 10 در محاسبه استفاده شود، خروجي اين برنامه مقدار اشتباه 76 را نشان خواهد داد. دليل اينكار در آخرين تكرار عبارت while نهفته است كه gradeCounter به مقدار 11 در خط 62 افزايش يافته است.

 

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

استفاده از متغير شمارنده حلقه، در يك عبارت محاسباتي پس از حلقه، معمولاً سبب توليد خطاي منطقي بنام off-by-one-error مي‌شود.

9-4  فرموله كردن الگوريتم‌ها: مراقبت-كنترل تكرار

اجازه دهيد تا به مسئله ميانگين كلاس بازگرديم و آنرا مجدداً و اينبار بصورت زير و كلي‌تر تعريف كنيم:

"برنامه محاسبه ميانگين كلاس را به نحوي توسعه دهيد تا در هر بار اجراي برنامه، به تعداد اختياري نمره دريافت كرده و محاسبه ميانگين بر روي آنها اعمال شود."

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

يك راه‌حل براي رفع اين مشكل، استفاده از يك مقدار ويژه بنام مقدار مراقبتي (sentinel value) است كه پايان ورود داده‌ها را مشخص مي‌كند (همچنين به اين مقدار، مقدار سيگنال، مقدار ساختگي يا پرچم نيز مي‌گويند). در اين روش كاربر اقدام به وارد كردن نمره‌ها كرده و در پايان مقدار مراقبتي تعيين شده را به عنوان اينكه داده‌هاي ورودي به اتمام رسيده‌اند، وارد مي‌سازد. روش مراقبت-كنترل تكرار، روش تكرار-تعريف‌نشده نيز ناميده مي‌شود چرا كه تعداد دفعات تكرار قبل از اجراي حلقه مشخص نيست.

واضح است كه مقدار مراقبتي بايد به نحوي انتخاب شود كه به عنوان يك ورودي معتبر مورد قبول واقع نشود. بدليل اينكه نمرات امتحان معمولاً منفي نيستند، مي‌توانيم از مقدار -1 به عنوان مقدار مراقبتي در اين برنامه استفاده كنيم. بنابراين به هنگام اجراي برنامه، نمرات كلاس، مي‌توانند ترتيبي مانند -1 و 84 ، 74 ، 75 ، 96 ، 93 داشته باشند. برنامه بايد نمره ميانگين كلاس را با استفاده از مقادير 93 ، 96 ، 75 ، 74 و 84 محاسبه كرده و به نمايش درآورد ( -1 يك مقدار مراقبتي است و نبايد در محاسبه ميانگين وارد شود).

 

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

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

الگوريتم شبه‌كد به روش مراقبت كنترل تكرار به روش از بالا به پايين، اصلاح گام‌به‌گام: اولين اصلاح

به هنگام بررسي مسائل پيچيده‌اي همانند اين برنامه، عرضه الگوريتم شبه‌كد به آساني امكان پذير نمي‌باشد. از اينرو به برنامه ميانگين كلاس با استفاده از تكنيكي بنام، از بالا به پايين، اصلاح گام‌به‌گام نزديك مي‌شويم كه براي ساخت و توسعه برنامه‌هاي ساخت‌يافته مناسب و ضروري است. شبه‌كدي كه در بالاترين سطح (top) ارائه مي‌شود، عبارت است از:

Determine the class average for the quiz.

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

Initialize Variables

Input, sum and count the quiz grades

Calculate and print the total of all student grades and the class average

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

اصلاح گام‌به‌گام مرحله دوم

مرحله بعدي تجزيه برنامه به جزئيات بيشتر (مرحله دوم)، در ارتباط با متغيرها مي‌باشد به يك متغير بنام total نياز است كه مجموع اعداد را در خود نگهداري كند و به يك متغير ديگر بنام count كه نشان دهد، چه تعدادي از اين اعداد مورد پردازش قرار گرفته‌اند. يك متغير براي دريافت هر نمره از طريق ورودي و يك متغير براي نگهداري ميانگين محاسبه شده مورد نياز است. عبارت شبه‌كد:

Initialize variable

را مي‌توان به عبارات جزئي‌تر زير تقسيم كرد:

Initialize total to zero

Initialize counter to zero

توجه كنيد كه فقط متغيرهاي total و counter نياز به مقداردهي اوليه قبل از بكارگيري دارند. متغيرهاي average و grade (اين متغيرها براي محاسبه ميانگين و ورودي كاربر استفاده شده است)، نيازي به مقداردهي اوليه ندارند. عبارت شبه‌كد:

Input, sum and count the quiz grades

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

Prompt the user to enter the first grade

Input the first grade (possibly the sentinel)

While the user has not yet entered the sentinel

      Add this grade to the running total

      Add one to the grade counter

      Input the next grade (possibly the sentinel)

عبارت شبه‌كد زير

Calculate and print the total of all student grades and the class average

مي‌تواند به صورت عبارات جزئي‌تر زير نوشته شود:

If the counter is not equal to zero

        Set the average to the total divided by the counter

Print the total of all student grades in the class

      Print the average

Else

   Print “No grades were entered”

توجه كنيد كه در اين قسمت براي جلوگيري از بروز خطاي منطقي تقسيم بر صفر، يك تست بكار برده شده است كه اگر در برنامه تشخيص داده نشود، مي‌تواند مشكل ساز شود. شبه‌كد كامل برنامه ميانگين در شكل 11-4 آورده شده است.

 

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

نتيجه تقسيم بر صفر خطاي عظيم در زمان اجرا است.

 

 

 

اجتناب از خطا

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

Initialize total to zero

Initialize counter to zero

Input the first grade (possibly the sentinel)

While the user has not as yet entered the sentinel

      Add this grade to the running total

      Add one to the grade counter

      Input the next grade (possibly the sentinel)

If the counter is not equal to zero

      Set the average to the total divided by the counter

      Print the average

Else

      Print “No grades were entered”

شكل 11-4  | الگوريتم شبه‌كد با استفاده از روش مراقبت-كنترل تكرار براي حل مسئله ميانگين كلاس.

 

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

با قراردادن خطوط خالي در برنامه‌هاي شبه‌كد خوانائي آنها افزايش مي‌يابد. خطوط خالي موجب مي‌شوند تا عبارتهاي كنترلي شبه‌كد و فازهاي برنامه از هم متمايز شوند.

 

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

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

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

 

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

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

پياده‌سازي كلاس GradeBook به روش مراقبت-كنترل تكرار

شكل‌هاي 12-4 و 13-4 كلاس GradeBook را به نحوي نشان مي‌دهند كه حاوي تابع عضو determineClassAverage است كه الگوريتم شبه كد شكل 11-4 را پياده‌سازي مي‌كند (اين كلاس در شكل 14-4 توصيف شده است). اگر چه هر نمره وارد شده يك عدد صحيح است، امكان توليد يك عدد اعشاري به هنگام محاسبه ميانگين وجود دارد، به عبارتي يك عدد حقيقي يا عدد با نقطه اعشار (همانند 7.33 ، 0.0975  يا 1000.12345 ). نوع داده int نمي ‌تواند چنين اعدادي را عرضه كند، از اينرو اين كلاس بايد از نوع داده ديگري استفاده كند. زبان C++ داراي چندين نوع داده براي ذخيره‌سازي اعداد اعشاري در حافظه است، نوع‌هاي همانند float و double . تفاوت اصلي مابين اين نوع در اين است كه در مقايسه با متغيرهاي float ، متغيرهاي double قادر به نگهداري اعداد بزرگتر و دقيق‌تر در سمت نقطه اعشار هستند، در نتيجه دقت عدد بيشتر خواهد بود. اين برنامه مبادرت به معرفي يك عملگر ويژه بنام عملگر cast است كه محاسبه ميانگين را مجبور مي‌كند تا نتيجه را بصورت عدد اعشاري توليد كند. اين ويژگي به هنگام بررسي برنامه توضيح داده خواهد شد.

در اين مثال مشاهده مي‌كنيد كه عبارات كنترلي مي‌توانند به صورت پشته يكي بر روي ديگري قرار داده شوند (بصورت متوالي). عبارت while در خطوط 67-75 از شكل13-4 بلافاصله پس از عبارات if..else قرار گرفته است و حالت توالي دارد. قسمت اعظم كد بكار رفته در اين مثال با كد برنامه 9-4 يكسان است، از اينرو تمركز خود را بر روي ويژگي‌ها و مباحث جديد متمركز مي‌كنيم.

1       // Fig. 4.12: GradeBook.h

2       // Definition of class GradeBook that determines a class average.

3       // Member functions are defined in GradeBook.cpp

4       #include <string> // program uses C++ standard string class

5       using std::string;

6        

7       // GradeBook class definition

8       class GradeBook

9       {

10    public:

11       GradeBook( string ); // constructor initializes course name

12       void setCourseName( string ); // function to set the course name

13       string getCourseName(); // function to retrieve the course name

14       void displayMessage(); // display a welcome message

15       void determineClassAverage(); // averages grades entered by the user

16    private:

17       string courseName; // course name for this GradeBook

18    }; // end class GradeBook

شكل 12-4 | برنامهميانگينكلاسبار وش مراقبت-كنترل تكرار: فايل سرآيند GradeBook

1       // Fig. 4.13: GradeBook.cpp

2       // Member-function definitions for class GradeBook that solves the

3       // class average program with sentinel-controlled repetition.

4       #include <iostream>

5       using std::cout;

6       using std::cin;

7       using std::endl;

8       using std::fixed; // ensures that decimal point is displayed

9        

10    #include <iomanip> // parameterized stream manipulators 

11    using std::setprecision; // sets numeric output precision

12     

13    // include definition of class GradeBook from GradeBook.h

14    #include "GradeBook.h"

15     

16    // constructor initializes courseName with string supplied as argument

17    GradeBook::GradeBook( string name )

18    {

19       setCourseName( name ); // validate and store courseName

20    } // end GradeBook constructor

21     

22    // function to set the course name;

23    // ensures that the course name has at most 25 characters

24    void GradeBook::setCourseName( string name )

25    {

26       if ( name.length() <= 25 ) // if name has 25 or fewer characters

27          courseName = name; // store the course name in the object

28       else // if name is longer than 25 characters

29       { // set courseName to first 25 characters of parameter name

30          courseName = name.substr( 0, 25 ); // select first 25 characters

31          cout << "Name \"" << name << "\" exceeds maximum length (25).\n"

32    << "Limiting courseName to first 25 characters.\n" << endl;

33       } // end if...else

34    } // end function setCourseName

35     

36    // function to retrieve the course name

37    string GradeBook::getCourseName()

38    {

39       return courseName;

40    } // end function getCourseName

41     

42    // display a welcome message to the GradeBook user

43    void GradeBook::displayMessage()

44    {

45       cout << "Welcome to the grade book for\n" << getCourseName() << "!\n"

46    << endl;

47    } // end function displayMessage

48     

49    // determine class average based on 10 grades entered by user

50    void GradeBook::determineClassAverage()

51    {

52       int total; // sum of grades entered by user

53       int gradeCounter; // number of grades entered

54       int grade; // grade value

55       double average; // number with decimal point for average

56     

57       // initialization phase

58       total = 0; // initialize total

59       gradeCounter = 0; // initialize loop counter

60     

61       // processing phase

62       // prompt for input and read grade from user 

63       cout << "Enter grade or -1 to quit: ";       

64       cin >> grade; // input grade or sentinel value

65     

66       // loop until sentinel value read from user  

67       while ( grade != -1 ) // while grade is not -1

68       {                 

69          total = total + grade; // add grade to total

70          gradeCounter = gradeCounter + 1; // increment counter

71     

72          // prompt for input and read next grade from user

73          cout << "Enter grade or -1 to quit: ";          

74          cin >> grade; // input grade or sentinel value  

75       } // end while

76     

77       // termination phase

78    if ( gradeCounter != 0 ) // if user entered at least one grade...

79       {

80          // calculate average of all grades entered             

81          average = static_cast< double >( total ) / gradeCounter;

82     

83          // display total and average (with two digits of precision)

84          cout << "\nTotal of all " << gradeCounter << " grades entered is "

85    << total << endl;

86          cout<< "Class average is" << setprecision( 2 ) << fixed << average

87    << endl;

88       } // end if

89       else // no grades were entered, so output appropriate message

90          cout << "No grades were entered" << endl;

91    } // end function determineClassAverage

شكل 13-4 | برنامهميانگينكلاسباروشمراقبت - كنترلتكرار : فايل كد منبع GradeBook

1       // Fig. 4.14: fig04_14.cpp

2       // Create GradeBook object and invoke its determineClassAverage function.

3        

4       // include definition of class GradeBook from GradeBook.h

5       #include "GradeBook.h"

6        

7       int main()

8       {

9          // create GradeBook object myGradeBook and

10       // pass course name to constructor

11       GradeBook myGradeBook( "CS101 C++ Programming" );

12     

13       myGradeBook.displayMessage(); // display welcome message

14       myGradeBook.determineClassAverage(); // find average of 10 grades

15       return 0; // indicate successful termination

16    } // end main

 

 

شكل14-4|برنامه ميانگين كلاس با روش مراقبت-كنترل تكرار: ايجاد يك شي از كلاس GradeBook (شكل12-4 و 13-4) و فراخواني تابع عضو determineClassAverage .

در خط 55 متغير average از نوع double اعلان شده است. اين نوع به محاسبه ميانگين امكان مي‌دهد تا بصورت يك عدد اعشاري در متغير ذخيره گردد. در خط 59 متغير gradeCounter با صفر مقداردهي شده چرا كه هنوز نمره‌اي وارد نشده است، به ياد داشته باشيد كه اين برنامه از روش مراقبت-كنترل‌ تكرار استفاده مي‌كند. به منظور ثبت دقيق تعداد نمرات وارد شدة، متغير gradeCounter فقط به هنگام وارد شدن يك نمره معتبر بعنوان ورودي، افزايش مي‌يابد.

تفاوت‌هاي موجود مابين روش‌هاي مراقبت-كنترل تكرار و شمارنده-كنترل تكرار

به تفاوت‌هاي موجود ميان روش مراقبت-كنترل تكرار در اين برنامه و شمارنده-كنترل تكرار در برنامه 9-4 توجه كنيد. در روش شمارنده-كنترل تكرار، در هر بار تكرار عبارت while (خطوط 57-63 از شكل 9-4) يك مقدار از سوي كاربر دريافت مي‌گرديد. در روش مراقبت-كنترل تكرار، قبل از اينكه برنامه به عبارت while برسد، يك مقدار (خطوط 63-64 از شكل 13-4) ) دريافت مي‌شود. اين مقدار تعيين مي‌كند كه آيا جريان كنترل برنامه وارد بدنه عبارت while شود يا خير. اگر شرط عبارت while برقرار نباشد (كاربر مقدار مراقبتي وارد كرده باشد)، بدنه عبارت while اجرا نخواهد شد (هيچ نمره‌اي وارد نمي‌شود). از سوي ديگر، اگر شرط برقرار شود، بدنه اجرا شده و مقدار وارد شدة كاربر بكار گرفته مي‌شود (به total افزوده مي‌شود، خط 69 ). پس از پردازش مقدار، مقدار بعدي قبل از اينكه برنامه به انتهاي بدنه عبارت while برسد توسط كاربر وارد مي‌شود (خطوط 73-74 ) . زمانيكه برنامه به  } در خط 75 مي‌رسد، اجرا با تست بعدي در شرط عبارت while ادامه مي‌يابد (خط 67 ) . مقدار جديد وارد شده تعيين مي‌كند كه آيا عبارت بدنه while مجدداً اجرا شود يا خير. دقت كنيد كه مقدار بعدي هميشه قبل از اينكه شرط عبارت while ارزيابي شود، بلافاصله توسط كاربر وارد مي‌شود. در اينحالت برنامه مي‌تواند قبل از اينكه اقدام به پردازش مقداري نمايد، تعيين كند كه آيا آن مقدار، مقدار مراقبتي است يا خير. اگر مقدار مراقبتي باشد، عبارت while خاتمه مي‌يابد و مقدار به total افزوده نمي‌شود.

پس از خاتمه حلقه، عبارت if..else در خطوط 78-90 اجرا مي‌شود. شرط موجود در خط 78 تعيين مي‌كند كه آيا نمره‌اي وارده شده است يا خير. اگر نمره‌اي وارد نشده باشد، بخش else (خطوط 89-90 ) از عبارت if..else اجرا شده و پيغام "No grades were entered" را به نمايش درآورده و تابع عضو كنترل را به تابع فراخوان برگشت مي‌دهد.

به بلوك موجود در حلقه while شكل 13-4 دقت كنيد. بدون حضور براكت‌ها، سه عبارت آخر در بدنه حلقه در خارج از حلقه جاي مي‌گرفتند و اين سبب مي‌شد كه كامپيوتر اين كد را بصورت زير و نادرست تفسير كند:

// loop until sentinel value read from user  

while ( grade != -1 )

total = total + grade; // add grade to total

gradeCounter = gradeCounter + 1; // increment counter

 

   // prompt for input and read next grade from user

cout<< "Enter grade or -1 to quit: ";

cin>> grade;

در اين حالت برنامه دچار يك حلقه بي‌نهايت مي‌شود در صورتيكه كاربر 1 - را به عنوان اولين نمره وارد نكند (خط 64 ).

 

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

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

 

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

در حلقه كنترل مقدار مراقبتي، كه مقداري از كاربر تقاضا مي‌كند، بايد مقدار مراقبتي به كاربر نشان داده شود.

دقت اعداد اعشاري و نياز حافظه

متغيرهاي از نوع float عرضه‌كننده اعداد با دقت منفرد در نقطه اعشار هستند و داراي هفت رقم معني‌دار در سيستم‌هاي 32 بيتي مي‌باشند. متغيرهاي از نوع double عرضه‌كننده دقت مضاعف در نقطه اعشار هستند. اين دقت مستلزم دو برابر حافظه مورد نياز براي يك متغير float است و داراي 15 رقم معني‌دار در سيستم‌هاي 32 بيتي است (تقريباً دو برابر دقيق‌تر از متغيرهاي float ). براي اكثر محاسبات صورت گرفته در برنامه‌ها نوع float مي‌تواند كافي باشد، اما مي‌توانيد با استفاده از double دقت را تضمين كنيد. در برخي از برنامه‌ها، حتي متغيرهاي از نوع double هم كافي نيستند، برنامه‌هايي كه خارج از قلمرو بحث اين كتاب هستند. اكثر برنامه‌نويسان براي عرضه اعداد اعشاري از نوع double استفاده مي‌كنند. در واقع C++ بطور پيش‌فرض با تمام اعداد اعشاري كه در كد منبع برنامه تايپ مي‌كنيد (همانند 7.33 و 0.0975 ) همانند مقادير double رفتار مي‌كند. چنين مقاديري در كد منبع بعنوان ثابت‌هاي اعشاري شناخته مي‌شوند.

غالبا اعداد اعشاري در انجام عمليات تقسيم گسترش زيادي پيدا مي‌كنند. براي مثال با تقسيم 10 بر 3 ، نتيجه 3.333333... با دنباله‌اي از 3 هاي نامتناهي خواهد بود. كامپيوتر فضاي ثابتي براي نگهداري چنين مقاديري در اختيار دارد، از اينرو ذخيره سازي مقادير اعشاري فقط بصورت تخميني صورت مي‌گيرد.

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

 

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

استفاده از اعداد اعشاري با فرض اينكه اين اعداد نشاندهنده مقدار كاملاً دقيق هستند (بويژه در عبارات مقايسه‌اي) مي‌تواند نتايج اشتباهي بدنبال داشته باشد. اعداد اعشاري تقريبا در تمام كامپيوترها نشان‌دهنده يك مقدار تقريبي هستند.

تبديل مابين نوع‌هاي بنيادين بصورت صريح و ضمني

متغير average بصورت double (خط 55 از شكل 13-4) اعلان شده تا نتيجه اعشاري محاسبه انجام گرفته را در خود ذخيره سازد. با اين همه، متغيرهاي total و gradeCounter هر دو از نوع صحيح مي‌باشند. بخاطر داريد كه نتيجه تقسيم دو عدد صحيح يك عدد صحيح است كه در آن بخش اعشاري جواب از بين مي‌رود (قطع مي‌شود). در عبارت زير

average = total / gradeCounter;

ابتدا تقسيم انجام مي‌شود، از اينرو بخش اعشاري نتيجه قبل از تخصيص به average از بين مي‌رود. براي انجام يك محاسبه اعشاري با مقادير صحيح، بايستي مقادير موقتي كه اعداد اعشاري هستند براي محاسبه ايجاد كنيم. زبان C++ داراي عملگر غيرباينري cast است كه اين وظيفه را انجام مي‌دهد. در خط 81 از عملگر cast بصورت static_cast<double>(total) براي ايجاد يك كپي موقت اعشاري از عملوند موجود در درون پرانتزها يعني total استفاده شده است. به استفاده از يك عملگر cast به اين روش، تبديل صريح مي‌گويند. هنوز مقدار ذخيره شده در total يك عدد صحيح است.

اكنون محاسبه متشكل از يك مقدار اعشاري (نسخه double موقت از total ) است كه بر يك عدد صحيح در gradeCounter تقسيم مي‌شود. كامپايلر C++ فقط از نحوه ارزيابي عباراتي كه در آن نوع داده‌هاي عملوندها يكسان هستند، اطلاع دارد. براي اطمينان از اينكه عملوندها از نوع مشابه هستند، كامپايلر مبادرت به انجام عملي بنام ترفيع كه تبديل ضمني نيز ناميده مي‌شود بر روي عملوندهاي انتخابي مي‌كند. براي مثال، در يك عبارت كه حاوي مقاديري از نوع داده int و double است، C++ مبادرت به ترفيع عملوندهاي int به مقادير double مي‌كند. در اين مثال با total همانند يك نوع داده double رفتار مي‌كنيم (با استفاده از عملگر cast )، از اينرو كامپايلر مبادرت به ترفيع gradeCounter به double كرده و به محاسبه اجازه انجام مي‌دهد و نتيجه تقسيم اعشاري به average تخصيص مي‌يابد. در فصل ششم، در مورد نوع داده‌هاي بنيادين و نحوه ترفيع آنها توضيح خواهيم داد.

 

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

مي‌توان از عملگر cast براي تبديل مابين نوع‌هاي بنيادين عددي همانند int و double و مابين نوع كلاس‌هاي مرتبط استفاده كرد (در فصل سيزدهم با اين موضوع آشنا خواهيد شد). تبديل به يك نوع اشتباه مي‌تواند خطاي كامپايلر يا خطاي زمان اجرا بوجود آورد.

 

عملگرهاي cast براي استفاده در هر نوع داده و همچنين نوع‌هاي كلاس در دسترس هستند. بدنبال عملگر static_cast يك جفت كاراكتر > و < كه نوع داده را احاطه كرده‌اند آورده مي‌شود. عملگر cast يك عملگر غيرباينري است. عملگري كه فقط يك عملوند اختيار مي‌كند. در فصل دوم، با عملگرهاي محاسباتي باينري آشنا شده‌ايد. همچنين C++ از نسخه‌هاي عملگرهاي غيرباينري جمع ( + ) و منفي ( - ) پشتيباني مي‌كند، از اينرو برنامه‌نويس مي‌تواند عبارتي مثل -7 يا +5 بنويسد. عملگر cast از ساير عملگرهاي غيرباينري همانند + و - از تقدم بالاتري برخوردار است. اين تقدم بالاتر از عملگرهاي * ، / و % و پايين‌تر از پرانتز است. در جدول شكل 22-4 اين عملگر را با نماد static_cast<type>() عرضه كرده‌ايم.

قالب‌بندي اعداد اعشاري

قالب‌بندي بكار رفته در برنامه شكل13-4 را بطور خلاصه در اين بخش و بطور دقيق‌تر در فصل پانزدهم توضيح خواهيم داد. فراخواني تابع setprecision در خط 86 (با آرگومان 2 ) بر اين نكته دلالت دارد كه متغير average از نوع double بايستي با دو رقم معني‌دار در سمت راست نقطه اعشار چاپ شود (مثلاً 97.37 ) به اينحالت كنترل‌كننده جريان پارامتري شده (استريم) مي‌گويند (بدليل وجود 2 در درون پرانتز). برنامه‌هايي كه از اين فراخواني استفاده مي‌كنند بايد حاوي رهنمود دستور دهنده زير باشند (خط 10 )

#include <iomanip>

خط 11 تصريح‌كننده نام فايل سرآيند <iomanip> است كه در اين برنامه بكار گرفته خواهد شد. دقت كنيد كه endl يك كنترل‌كننده جريان پارامتري نشده است (چرا كه پس از آن مقدار يا عبارتي در درون پرانتزها وجود ندارد) و نيازمند فايل سرآيند <iomanip> نيست. اگر دقت تعيين نشود، معمولاً اعداد اعشاري با شش رقم معني‌دار چاپ مي‌شوند (دقت پيش‌فرض در اكثر سيستم‌هاي 32 بيتي). كنترل‌كننده جريان fixed بر اين نكته دلالت دارد كه مقادير اعشاري بايستي با خروجي كه فرمت نقطه ثابت ناميده مي‌شوند چاپ شوند، كه متضاد نماد علمي مي‌باشد. نماد علمي روشي براي نمايش يك عدد بصورت، عدد اعشاري مابين مقدار 1 الي 10 است كه در تواني از 10 ضرب مي‌شود. براي مثال، مقدار 3100 را مي‌توان در نماد علمي بصورت 3.1×103 به نمايش در آورد. به هنگام نمايش مقاديري كه بسيار بزرگ يا بسيار كوچك هستند، نماد علمي مي‌تواند ابزار مناسبي براي اينكار باشد در فصل پانزدهم با قالب‌بندي نماد علمي آشنا خواهيد شد. در طرف مقابل، قالب‌بندي نقطه ثابت قرار دارد كه يك عدد اعشاري را مجبور مي‌كند تا به تعداد مشخص شده مبادرت به نمايش ارقام كند. همچنين اين فرمت نقطه اعشار و دنباله صفرها در چاپ را كنترل مي‌كند، حتي اگر عدد يك عدد صحيح باشد، همانند 88.00 ، بدون قالب‌بندي نقطه ثابت چنين عددي در C++ بصورت 88 چاپ مي‌شود، بدون دنباله صفرها و نقطه اعشار. زمانيكه از كنترل‌كننده‌هاي جريان fixed و setprecision در برنامه‌اي استفاده مي‌شود، مقادير چاپ شده به تعداد نقاط ديسمال كه توسط مقدار ارسالي به setprecision مشخص مي‌شود، گرد مي‌شوند (همانند مقدار 2 در خط 86 )، اگرچه مقدار موجود در حافظه بدون تغيير باقي مي‌ماند. براي مثال، مقادير 87.946 و 67.543 بصورت 87.95 و 67.54 چاپ مي‌شوند. توجه كنيد كه مي‌توان نقطه اعشار را با استفاده از كنترل‌كننده جريان showpoint به نمايش درآورد. اگر showpoint بدون fixed بكار گرفته شود، دنباله صفحه‌ها چاپ نخواهد شد. همانند endl ، كنترل‌كننده‌هاي جريان fixed و showpoint پارامتري شده نبوده و نيازي به سرآيند فايل <iomanip> ندارند. هر دو آنها را مي‌توان در سرآيند <iostream> پيدا كرد.

خط 86 و 87 از شكل 13-4 خروجي ميانگين كلاس هستند. در اين مثال ميانگين كلاس گرد شده به نزديكترين صدم و دقيقاً با دو رقم در سمت راست نقطه اعشار به نمايش درآمده‌اند. كنترل‌كننده جريان پارامتري شده (خط 86 ) نشان مي‌دهد كه مقدار متغير average بايستي با دقت دو رقم در سمت راست نقطه اعشار به نمايش درآيد (setprecision(2)) . در اجراي نمونه‌اي برنامه سه نمره وارد برنامه 14-4 شده كه مجموع آنها 257 شده است و ميانگين حاصل از اين رقم عدد 85.666666 است. كنترل‌كننده جريان پارامتري شده setprecision سبب مي‌شود تا مقدار به تعداد رقم مشخص گرد شود. در اين برنامه، ميانگين به 85.67 گرد شده است.

10-4  فرموله كردن الگوريتم‌ها: عبارات كنترلي تودرتو

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

به صورت مسئله توجه نمائيد:

يك كالج با برگزاري دوره‌اي دانشجويان را آماده امتحان پايان ترم مي‌كند. سال گذشته، 10 تن از دانشجويان كه اين دوره را گذرانده بودند در امتحان پايان ترم شركت كردند. مديريت كالج مي‌خواهد از وضعيت دانشجويان شركت كرده در امتحان مطلع شود. از شما خواسته شده تا برنامه‌اي بنويسيد تا خلاصه‌اي از نتايج آزمون ارائه دهد. ليستي از 10 دانشجو دريافت كرده و سپس در كنار نام كساني كه در آزمون قبول شده‌اند 1 و كساني كه در آزمون مردود شده‌اند 2 چاپ شود.

اين برنامه بايد بصورت زير نتايج آزمون را تحليل نمايد:

1- وارد كردن نتيجه هر آزمون (براي مثال 1 يا 2 ). نمايش پيغام “Enter result” در هر بار كه برنامه درخواست نتيجه آزمون مي‌كند.

2- شمارش تعداد قبولي‌ها و مردودي‌ها.

3- نمايش خلاصه‌اي از نتايج آزمون، شامل تعداد دانشجويان كه موفق به گذراندن آزمون شده‌اند و تعدادي كه مردود شده‌اند.

4- اگر بيش از 8 دانشجواز آزمون با موفقيت عبور كرده‌اند. پيغام “Raise tuition” به نمايش درآيد.

پس از مطالعه صورت مسئله، تصميمات زير را براي حل آن اتخاذ مي‌كنيم:

1- برنامه بايد بر روي نتايج آزمون 10 دانشجو كار كند، از اينرو حلقه شمارنده - كنترل مي‌تواند بكار گرفته شود.

2- نتيجه هر آزمون عدد 1 يا 2 است. هر بار كه برنامه اقدام به خواندن نتيجه يك آزمون مي‌كند، برنامه بايد يك 1 يا 2 دريافت نمايد.

3- دو شمارنده به ذخيره‌سازي نتايج آزمون مي‌پردازند. يكي براي شمارش تعداد دانشجويان كه از آزمون با موفقيت عبور كرده‌اند و ديگري براي شمارش تعدادي كه در آزمون مردود شده‌اند.

4- پس از اينكه برنامه تمام نتايج را مورد پردازش قرار داد، بايد تعيين كند كه آيا تعداد قبولي‌ها بيش از هشت نفر است يا خير.

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

Analyze exam result and decide if tuition should be raised

مجدداً يادآوري مي‌كنيم كه عبارت top توصيف كلي در مورد برنامه است و قبل از اينكه بتوان شبه‌كد را به فرم يك برنامه C++   نوشت انجام چندين مرحله اصلاح گام‌به‌گام ضروري است. اولين اصلاح عبارت است از:

Initialize variables

Input the 10 exam grades and count passes and failures

Print a summary of the exam result and decideif tuition should be raised

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

Initialize variables

 

مي‌تواند بصورت زير اصلاح شود:

Initialize passes to zero

Initialize failures to zero

Initialize student counter to one

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

Input the 10 quiz grades and count passes and failures

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

While student counter is less than or equal to 10

        Prompt the user to enter the next exam result

      Input the next exam result

      If the student passed

                  Add one to passes

      Else

                  Add one to failures

      Add one to student counter

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

Print a summary of the exam results and decide if tuition should be raised

مي‌تواند بصورت زير اصلاح شود:

Print the number of passes

Print the number of failures

If more than eight student passed

      Print “Raise tuition”

در شكل 15-4 دومين مرحله اصلاح بصورت كامل نشان داده شده است. به كاربرد خطوط خالي در ميان ساختار while   توجه كنيد ، كه باعث افزايش خوانائي برنامه مي‌شوند . اكنون اين شبه‌كد بقدر كافي براي تبديل به يك برنامه C++ آماده شده است.

Initialize passes to zero

Initialize failures to zero

Initialize student to zero

While student counter is less than or equal to ten

      Input the next exam result

      If the student passed

                  Add one to passes

      Else

                  Add one to failures

                  Add one to student counter

Print the number of passes

Print the number of failures

If more than eight students passed

      Print “Raise tuition”

شكل 15-4 | شبه‌كد برنامه نتيجه آزمون.

تبديل به كلاس Analysis

كلاس C++ كه مبادرت به پياده‌سازي الگوريتم شبه‌كد كرده است در شكل‌هاي 16-4 و 17-4 و دو اجراي نمونه در شكل 18-4 نشان داده است.

1       // Fig. 4.16: Analysis.h

2       // Definition of class Analysis that analyzes examination results.

3       // Member function is defined in Analysis.cpp

4        

5       // Analysis class definition

6       class Analysis

7       {

8       public:

9          void processExamResults(); // process 10 students' examination results

10    }; // end class Analysis

شكل 16-4 | برنامه بررسي نتيجه آزمون: فايل سرآيند Analysis .

1       // Fig. 4.17: Analysis.cpp

2       // Member-function definitions for class Analysis that

3       // analyzes examination results.

4       #include <iostream>

5       using std::cout;

6       using std::cin;

7       using std::endl;

8        

9       // include definition of class Analysis from Analysis.h

10    #include "Analysis.h"

11     

12    // process the examination results of 10 students

13    void Analysis::processExamResults()

14    {

15       // initializing variables in declarations

16       int passes = 0; // number of passes      

17       int failures = 0; // number of failures  

18       int studentCounter = 1; // student counter

19       int result; // one exam result (1 = pass, 2 = fail)

20     

21       // process 10 students using counter-controlled loop

22       while ( studentCounter <= 10 )

23       {

24          // prompt user for input and obtain value from user

25          cout << "Enter result (1 = pass, 2 = fail): ";

26          cin >> result; // input result

27     

28          // if...else nested in while                          

29          if ( result == 1 )          // if result is 1,        

30             passes = passes + 1;     // increment passes;      

31          else                        // else result is not 1, so

32             failures = failures + 1; // increment failures     

33     

34          // increment studentCounter so loop eventually terminates

35          studentCounter = studentCounter + 1;

36       } // end while

37     

38       // termination phase; display number of passes and failures

39       cout << "Passed " << passes << "\nFailed " << failures << endl;

40     

41       // determine whether more than eight students passed

42       if ( passes > 8 )

43          cout << "Raise tuition " << endl;

44    } // end function processExamResults

شكل 17-4 |برنامه بررسي نتيجه آزمون: عبارات كنترلي تودرتو در  فايل كد منبع Analysis

1       // Fig. 4.18: fig04_18.cpp

2       // Test program for class Analysis.

3       #include "Analysis.h" // include definition of class Analysis

4        

5       int main()

6       {

7          Analysis application; // create Analysis object                     

8          application.processExamResults(); // call function to process results

9          return 0; // indicate successful termination

10    } // end main

 

 

 

شكل 18-4 | برنامه تست كننده كلاس Analysis

خطوط 16-18 از برنامه17-4 متغيرهاي اعلان كرده‌اند كه تابع عضو processExamResults از كلاس Analysis از آنها براي پردازش نتايج آزمون استفاده مي‌كند. توجه كنيد كه از يكي از ويژگي‌هاي زبان C++ استفاده كرده‌ايم كه به مقداردهي اوليه متغير امكان مي‌دهد تا با بخش اعلان يكي شود ( passes با صفر، failures با صفر و studentCounter با 1 مقداردهي اوليه شده‌اند). امكان مقداردهي در ابتداي تكرار هر حلقه وجود دارد، معمولاً چنين مقداردهي‌هاي مجددي توسط عبارات تخصيصي بجاي اعلان‌ها يا انتقال اعلان‌ها بدرون بدنه حلقه صورت مي‌گيرند.

حلقه while  ده بار تكرار مي‌شود (خطوط 22-36 ). در هر تكرار، حلقه يك نتيجه آزمون دريافت و آن را پردازش مي‌كند. دقت كنيد كه عبارت if..else در خطوط 29-32 براي پردازش هر نتيجه در عبارت while بصورت تودرتو قرار گرفته است. اگر result برابر 1 باشد، عبارت if..else يك واحد به passes اضافه مي‌كند و در غير اينصورت فرض مي‌كند كه result برابر 2 بوده و يك واحد به failures اضافه مي‌نمايد. خط 35 مبادرت به افزايش studentCouunter قبل از اينكه شرط تست حلقه در خط 22 صورت گيرد مي‌كند. پس دريافت 10 مقدار، حلقه پايان يافته و خط 39 تعداد قبولي‌ها (passes) و مردودي‌ها (failures) را به نمايش در مي‌آورد. عبارت if در خطوط 42-43 تعيين مي‌كند كه آيا تعداد دانشجويان قبول شده بيش از هشت نفر است يا خير. اگر چنين باشد پيغام "Raise Tuition" به نمايش در مي‌آيد.

بررسي كلاس Analysis

در برنامه 18-4 يك شي Analysis ايجاد (خط 7 ) و تابع عضو processExamResults فراخواني مي‌شود (خط 8 ) تا مجموع نتايج آزمون وارد شده توسط كاربر پردازش شود. دو اجراي نمونه از برنامه 18-4 در خروجي نشان داده شده است. در انتهاي اولين اجرا، شرط موجود در خط 42 تابع عضو procesExamResults در شكل 17-4 برقرار شده (بيش از هشت دانشجو قبول شده‌اند) و از اينرو پيغام "Raise Tuition" به نمايش درآمده است.

11-4 عملگرهاي تخصيص‌دهنده

C++ داراي چندين عملگر تخصيص‌دهنده براي كاستن از طول عبارات تخصيصي است. براي مثال، عبارت

c = c + 3;

مي‌تواند بصورت زير و با استفاده از عملگر += نوشته شود

c += 3;

عملگر += مقدار عملوند قرار گرفته در سمت راست را به مقدار عملوند سمت چپ اضافه كرده و نتيجه آنرا در متغير عملوند سمت چپ ذخيره مي‌كند. هر عبارتي به فرم زير را

; عبارت عملگر متغير = متغير

مي‌توان به فرم زير نوشت:

; عبارت = عملگر    متغير

عملگر يكي از عملگرهاي باينري +، -، * ، / يا % و متغير يك مقدار سمت چپ (lvalue) است. مقدار سمت چپ، متغيري است كه در سمت چپ يك عبارت تخصيصي جاي مي‌گيرد. جدول شكل 19-4 حاوي عملگرهاي تخصيص دهنده محاسباتي و عبارات نمونه‌اي است كه از اين عملگرها استفاده مي‌كنند.

عملگر تخصيص دهنده

عبارت نمونه

معادل

تخصيص

با فرض c = 3 ، d=5 ، e=4 ، f=6 و g=12

+=

c += 7

c = c + 7

10 به c

-=

d -= 4

d = d - 4

1 به d

*=

e *= 5

e = e * 5

20 به e

/=

f /= 3

f = f / 2

2 به f

%=

g %= 9

g = g % 9

3 به g

شكل 19-4 | عملگرهاي تخصيص‌دهنده .

12 - 4 عملگرهاي افزاينده و كاهنده

علاوه بر عملگرهاي محاسباتي تخصيص دهنده، زبان C++   داراي عملگر افزاينده غيرباينري ++ و عملگر كاهنده غيرباينري -- است. اين عملگرها در جدول شكل 20-4 توضيح داده شده‌اند. اگر متغير c بخواهد يك واحد افزايش پيدا كند، عملگر افزاينده ++ را مي‌توان بجاي استفاده از عبارت c = c + 1 يا c += 1 بكار گرفت. اگر عملگر افزاينده يا كاهنده قبل از يك متغير قرار داده شود، به مفهوم پيش‌افزايش يافته يا پيش‌كاهش يافته خواهد بود. اگر عملگر افزاينده يا كاهنده پس از يك متغير بكار گرفته شود، به مفهوم پس‌افزايشي يا پس‌كاهشي خواهد بود.در هر دو حالت افزايشي يا كاهشي مقدار متغير يك واحد افزايش يا كاهش پيدا مي‌كند. پس از انجام كار، مقدار جديد متغير در عبارتي كه حاوي آن است بكار گرفته مي‌شود.

عملگر

عبارت نمونه

عنوان

توضيح

++

++a

پيش‌افزايشي

a يك واحد افزايش مي‌يابد، سپس مقدار جديد a در عبارتي كه

 حاوي a است بكار گرفته مي‌شود.

++

a++

پس‌افزايشي

از مقدار جاري a در عبارتي كه حاوي آن است استفاده شده،

سپس مقدار a يك واحد افزايش مييابد.

--

--b

پيش‌كاهشي

b يك واحد كاهش مي‌يابد، سپس مقدار جديد b

در عبارتي كه حاوي b است بكار گرفته مي‌شود.

--

b--

پس‌كاهشي

از مقدار جاري b در عبارتي كه حاوي آن است استفاده شده،

 سپس مقدار b يك واحد كاهش مييابد.

شكل 20-4 | عملگرهاي افزاينده و كاهنده.

برنامه شكل21-4 به توصيف تفاوت موجود مابين نسخه‌هاي پيش‌افزايش و پس‌افزايش عملگر افزاينده ++ مي‌پردازد. عملگر كاهنده -- نيز به طريق مشابهي كار مي‌كند. توجه كنيد كه اين مثال حاوي كلاس نمي‌باشد، اما فايل كد منبع با main تمام برنامه‌ها كار مي‌كند. در اين فصل و فصل سوم شاهد مثال‌هاي بوده‌ايد كه حاوي يك كلاس (شامل سرآيند و فايلهاي كد منبع براي اين كلاس بوده‌اند) به همراه فايل كد منبع ديگري براي تست كلاس بودند. اين فايل كد منبع حاوي تابع main است كه يك شي از كلاس ايجاد و توابع عضو خود را فراخواني مي‌كند. در اين مثال، فقط خواسته‌ايم تا مكانيزم عملگر ++ را به نمايش در آوريم، از اينرو فقط از يك فايل كد منبع با تابع main استفاده كرده‌ايم. خط 12 مبادرت به مقداردهي اوليه متغير c با 5 و خط 13 مقدار اوليه c را به نمايش در مي‌آورد. خط 14 مقدار عبارت c++ را چاپ مي‌كند. اين عبارت سبب پس‌افزايش متغير ‍ c شده و در نتيجه مقدار اوليه c يعني 5 چاپ مي‌گردد، سپس مقدار c افزايش مي‌يابد. از اينرو، خط 14 مقدار اوليه c يعني 5 را مجدداً چاپ مي‌كند. خط 15 مقدار جديد c يعني 6 را براي تاكيد بر اين نكته كه مقدار متغير براستي در خط 14 افزايش يافته است چاپ مي‌نمايد.

1       // Fig. 4.21: fig04_21.cpp

2       // Preincrementing and postincrementing.

3       #include <iostream>

4       using std::cout;

5       using std::endl;

6        

7       int main()

8       {

9          int c;

10     

11       // demonstrate postincrement

12       c = 5; // assign 5 to c

13       cout << c << endl; // print 5

14       cout << c++ << endl; // print 5 then postincrement

15       cout << c << endl; // print 6                    

16     

17       cout << endl; // skip a line

18     

19       // demonstrate preincrement

20       c = 5; // assign 5 to c 

21       cout << c << endl; // print 5                   

22       cout << ++c << endl; // preincrement then print 6

23       cout << c << endl; // print 6

24       return 0; // indicate successful termination

25    } // end main

 


شكل 21-4 |تفاوت مابين عملگرهاي
پيش‌افزايشي و پس‌افزايشي.

خط 20 مقدار متغير c را به 5 باز مي‌گرداند و خط 21 مقدار c را چاپ مي‌كند. خط 22 مبادرت به چاپ مقدار عبارت ++c را مي‌كند. اين عبارت سبب پيش‌افزايش c شده است، از اينرو مقدار آن افزايش يافته و سپس مقدار جديد يعني 6 چاپ مي‌شود. خط 23  مجدداً مقدار c را به نمايش در مي‌آورد تا نشان دهد كه مقدار c هنوز پس از اجراي خط 22 برابر 6 است.

عملگرهاي تخصيص رياضي و عملگرهاي افزاينده و كاهنده مي‌توانند عبارات برنامه‌نويسي را ساده‌تر كنند. سه عبارت تخصيصي در برنامه 17-4

passes = passes + 1;

failures = failures + 1;

studentCounter = studentCounter + 1;

را مي‌توان با استفاده از عملگرهاي تخصيصي بصورت زير هم نوشت

passes += 1;

failures += 1;

student += 1;

با عملگرهاي پيش‌افزايشي بصورت زير

++passes;

++failures;

++studentCounter;

با عملگرهاي پس‌افزايشي بصورت زير نوشت

passes++

failures++;

studentCounter++;

 

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

مبادرت به استفاده از عملگر افزاينده يا كاهنده بر روي عبارتي بجز نام يك متغير، همانند ++(x + 1) خطاي نحوي خواهد بود.

 

 

جدول شكل 22-4 نمايشي از تقدم و ارتباط عملگرهاي مطرح شده تا بدين‌جا را عرضه كرده است. نمايش عملگرها با تقدم آنها از بالا به پايين است. ستون دوم توصيف كننده ارتباط عملگرها در هر سطح تقدم است. دقت كنيد كه عملگر شرطي ( ?: ) ، عملگر غيرباينري پس‌افزايشي ( ++ ) ، پس‌كاهشي ( - - ) ، جمع ( + ) ، تفريق ( - ) ، و عملگرهاي = ، += ، *= ، /= و %= از چپ به راست ارزشيابي مي‌شوند. مابقي عملگرهاي جدول شكل 22-4 از راست به چپ مي‌باشند. ستون سوم اسامي عملگرها را نشان مي‌دهد.

 

 

 

عملگر

ارتباط

نوع

( )

چپ به راست

پرانتز

++ --  static_cast< type >()

چپ به راست

غيرباينري

++  --  +  -

راست به چپ

غيرباينري

*  /  %

چپ به راست

تعددي

+  -

چپ به راست

افزاينده كاهنده

<<>>  

چپ به راست

درج/استخراج

<<=   >>=

چپ به راست

رابطه‌اي

==  !=

چپ به راست

برابري

?:

راست به چپ

شرطي

=  +=  -=  *=  /=  %=

راست به چپ

تخصيصي

شكل 22-4 |تقدم و رابطه عملگرهاي مطرح شده تا اين مرحله.

 

 

یک شنبه 16 خرداد 1389  8:17 PM
تشکرات از این پست
iman_karbala rasekhoon_ravabet
j133719
j133719
کاربر طلایی1
تاریخ عضویت : فروردین 1389 
تعداد پست ها : 1228
محل سکونت : لرستان
دوشنبه 17 خرداد 1389  1:08 PM
تشکرات از این پست
mashhadizadeh
mashhadizadeh
کاربر طلایی1
تاریخ عضویت : اردیبهشت 1388 
تعداد پست ها : 25019
محل سکونت : بوشهر

پاسخ به:آموزش ++C - بخش نهم

با تشکر
عالی بود   

    حمید.bmp

 

 

چهارشنبه 19 خرداد 1389  11:49 AM
تشکرات از این پست
jazereyearam
jazereyearam
کاربر نقره ای
تاریخ عضویت : آذر 1387 
تعداد پست ها : 1313
محل سکونت : زنجان

پاسخ به:آموزش ++C - بخش نهم

سلام من واقعا از شما بابت همه پستهاي كه اموزش داديد تشكر ميكنم چون خيلي از انها استفاده ميكنم ممنونم و موفق باشيد
 
سه شنبه 5 مرداد 1389  1:15 PM
تشکرات از این پست
esfahaniran88
esfahaniran88
کاربر طلایی2
تاریخ عضویت : اردیبهشت 1388 
تعداد پست ها : 2290
محل سکونت : اصفهان

پاسخ به:آموزش ++C - بخش نهم

خسته نباشید

اگه pdf آموزش برنامه ها قرار دهید عالی می شود

کاش میدانستی که نباید حس کرد که نباید
دل بست در فضایی که بر از همهمه ی ادم هاست...من گرفتار ترین تنهایم!

 

 



 

یک شنبه 7 آذر 1389  9:51 PM
تشکرات از این پست
دسترسی سریع به انجمن ها