بسم الله الرحمن الرحيم
الدرس الرابع
الحلقات loops
الحلقات هي من المواضيع المهمة والعملية في البرمجة، فهي تعني الإستمرار في تنفيذ جزء معين من العبارات بوجود شرط معين. وعندما ينتهي أو ينتفي هذا الشرط تتوقف الحلقة عن الدوران.
حلقة for
يمكن تكرار عبارة معينة بعدد معين بإستخدام for كما في المثال التالي:
والكتابة العامة لها هي
for < variable-name > := < initial_value > to [down to] < final_value > do S;
مثالها
var
i: Integer;
Count: Integer;
begin
Write('How many times? ');
Readln(Count);
for i:= 1 to Count do
Writeln('Hello there');
Write('Press enter key to close');
Readln;
end.
نستخدم في حلقات for متغير صحيح يسمى متغير الحلقة، وهو في هذا المثال المتغير i، وقيمته تبدأ في الدورة الأولى بالقيمة الإبتدائية التي حددها المبرمج، في هذه الحالة هو الرقم 1 ثم يزيد هذا المتغير في كل دورة حتى يتنهي في الدورة الأخيرة بالقيمة الأخيرة، وهي التي يحددها المستخدم بإدخالة لقيمة Count
يمكن إظهار قيمة متغير الحلقة كما في التعديل التالي للمثال السابق:
var i: Integer;
Count: Integer;
begin
Write('How many times? ');
Readln(Count);
for i:= 1 to Count do
begin
Writeln('Cycle number: ', i);
Writeln('Hello there');
end;
Write('Press enter key to close');
Readln;
end.
نلاحظ هذه المرة أننا قمنا تنفيذ عبارتين، لذلك إحتجنا لأن نوحدهما في شكل عبارة واحدة بإستخدام begin end.
جدول الضرب بإستخدام for loop
لو قارنا بين برنامج جدول الضرب السابق والتالي الذي سوف نستخدم فيه عبارة for سوف نجد أن الأخير ليس فيه تكرار كالأول:
program MultTableWithForLoop;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
{$IFDEF WINDOWS}{$R first.rc}{$ENDIF}
var
x, i: Integer;
begin
Write('Please input any number: ');
Readln(x);
for i:= 1 to 12 do
Writeln(x, ' * ', i, ' = ', x * i);
Writeln('Press enter key to close');
Readln;
end.
نجد أننا بدلاً عن كتابة إجراء إظهار حاصل الضرب 12 مرة فقد تمت كتابته مرة واحدة فقط وتولت حلقة for تكرار هذا اﻹجراء 12 مرة.
يمكن جعل الحلقة تدور بالعكس، من القيمة الكبرى إلى القيمة الصغرى وذلك بإستخدام downto وذلك بتغيير سطر واحد في المثال السابق لجدول الضرب:
for i:= 12 downto 1 do
برنامج المضروب Factorial
المضروب هو مجموع حاصل ضرب الرقم مع الرقم الذي يسبقه إلى الرقم واحد:
مضروب 3 يساوي 3 * 2 * 1 وتنتج عنه القيمة: 6
var
Fac, Num, i: Integer;
begin
Write('Please input any number: ');
Readln(Num);
Fac:= 1;
for i:= Num downto 1 do
Fac:= Fac * i;
Writeln('Factorial of ', Num ,' is ', Fac);
Writeln('Press enter key to close');
Readln;
end.
حلقة Repeat Until
بخلاف حلقة for loop التي تتميز بأنها تدور بعدد مين فإن Repeat loop تدور إلى أن يتحقق شرط معين، فمادام هذا الشرط غير مُحقق فهي تعيد الدوران، فإذا تحقق الشرط فسوف يخرج مؤشر التنفيذ من هذه الحلقة ويتم تنفيذ مابعدها. لذلك نجد أن هذه الحلقة غير محددة بعدد معين من الدورات، فعددها يعتمد على أن الشرط تحقق بعد كم من الدورات.
var
Num : Integer;
begin
repeat
Write('Please input a number: ');
Readln(Num);
until Num <= 0;
Writeln('Finished, please press enter key to close');
Readln;
end.
في البرنامج السابق يقوم البرنامج بالدخول للحلقة أولاً ثم سؤال المستخدم أن يدخل عدداً، ثم يقوم في نهاية الحلقة بفحص قيمة هذا العدد فإذا ساوي الصفر أو عدد أقل منه فإن الشرط يكون قد تحقق وتتنتهي الحلقة، أما إذا أدخلنا فيها أرقام أكبر من الصفر فإن الحلقة تستمر في الدوران.
برنامج المطعم بإستخدام Repeat Until
var
Selection: Char;
Price: Integer;
Total: Integer;
begin
Total:= 0;
repeat
Writeln('Welcome to Pascal Restaurant. Please select your order');
Writeln('1 - Chicken (10 Geneh)');
Writeln('2 - Fish (7 Geneh)');
Writeln('3 - Meat (8 Geneh)');
Writeln('4 – Salad (2 Geneh)');
Writeln('5 - Orange Juice (1 Geneh)');
Writeln('6 - Milk (1 Geneh)');
Writeln('X - nothing');
Writeln;
Write('Please enter your selection: ');
Readln(Selection);
case Selection of
'1': begin
Writeln('You have ordered Chicken, ',
'this will take 15 minutes');
Price:= 10;
end;
'2': begin
Writeln('You have ordered Fish, ',
' this will take 12 minutes');
Price:= 7;
end;
'3': begin
Writeln('You have ordered meat, ',
' this will take 18 minutes');
Price:= 8;
end;
'4': begin
Writeln('You have ordered Salad, '
' this will take 5 minutes');
Price:= 2;
end;
'5': begin
Writeln('You have ordered Orange juice, ',
'this will take 2 minutes');
Price:= 1;
end;
'6': begin
Writeln('You have ordered Milk, ',
'this will take 1 minute');
Price:= 1;
end;
else
begin
Writeln('Wrong entry');
Price:= 0;
end;
end;
Total:= Total + Price;
until (Selection = 'x') or (Selection = 'X');
Writeln('Total price = ', Total);
Write('Press enter key to close');
Readln;
end.
في البرنامج السابق هناك عدة أشياء جديدة وهي:
-
إضافة begin end مع case وذلك لأن تنفيذ الشرط لابد أن يكون عبارة واحدة، وكما سبق ذكره فإن begin end تقوم بتحويل عدة عبارات إلى عبارة واحدة. الفريق العربي للبرمجةارة
Writeln('You have ordered..تمت إضافة عبارة جديدة معها وهي price:= 2 وهي لمعرفة قيمة الطلب وإضافته لاحقاً لمعرفة الحساب الكلي.
-
تم إستخدام المتغير selection من النوع الحرفي char وهو يتميز بإمكانيته في إستقبال أي رمز من لوحة المفاتيح، فمثلاً يمكن أن يستقبل رقم (خانة واحدة فقط) أو حرف. وقد إستخدمنا الحرف x للدلالة على نهاية الطلبات.
-
قمنا بوضع صفر في المتغير Total والذي سوف نقوم بتجميع قيمة الطلبات فيه ثم نعرضه في النهاية. وقد إستخدمنا هذه العبارة للتجميع:
Total:= Total + Price;
-
وضعنا خيارين لإدخال الحرف x فإذا قام المستخدم بإدخال x كبيرة X أو صغيرة x فإن الحلقة تتوقف. علماً بأن قيمة الحرف x تختلف عن قيمته بالصيغة الكبيرة X.
حلقة while do
والكتابة العامة لها هي
while (condition) do S;
تتشابه حلقة while مع حلقة repeat بإرتباط الإستمرار في الدوران مع شرط معين، إلا أن while تختلف إختلافين:
-
يتم فحص الشرط أولاً ثم الدخول إلى الحلقة
-
حلقة repeat يتم تنفيذها مرة واحدة على الأقل، وبعد الدورة الأولى يتم فحص الشرط، أما while فهي تمنع البرنامج من دخول الحلقة إذا كان الشرط غير صحيح من البداية.
-
إذا كانت الحلقة تحتوي على أكثر من عبارة فلابد من إستخدام begin end. أما حلقة repeat فإنها لاتحتاج، لأن الحلقة حدودها تبدأ من كلمة repeat وتنتهي بـ until.
مثال:
var
Num: Integer;
begin
Write('Input a number: ');
Readln(Num);
while Num > 0 do
begin
Write('From inside loop: Input a number : ');
Readln(Num);
end;
Write('Press enter key to close');
Readln;
end.
يمكننا إعادة كتابة برنامج المضروب بإستخدام while do
برنامج المضروب بإستخدام حلقة while do
var
Fac, Num, i: Integer;
begin
Write('Please input any number: ');
Readln(Num);
Fac:= 1;
i:= Num;
while i > 1 do
begin
Fac:= Fac * i;
i:= i - 1;
end;
Writeln('Factorial of ', Num ,' is ', Fac);
Writeln('Press enter key to close');
Readln;
end.
بما أن حلقة while ليس لديها متغير حلقة مثل for loop فقد قمنا بإستخدام المتغير i ليكون متغير الحلقة. لذلك قمنا بإنقاص قيمة المتغير i حتى يصلى إلى واحد وهو شرط عدم الدخول مرة أخرى في الحلقة.
الحلقات من نوع while او من نوع repeat يجب الحذر فيها لأمر واحد وهو أن تجعل لها غاية تنتهي إليها إذا لم تكن تريد البقاء في الحقلة
ومعنى ذلك أن تجعل الحقات تنتهي إلى ذلك الشرط الذي وضعته للحقلة مثل
while i > 10 do
فلا بد أن تزود i ب 1 أو أكثر في كل مرة تدور بها الحلقة وإلا بقيت تدور ما دام البرنامج مشتغلا وذلك يعد عند المبرمجين خطأ منطقيا
والصواب أنه سيكون خطأ منطقيا إذا لم ترد أنت البقاء في الحلقة إلى ما لا نهاية وإنما قلت ذلك لأنه في بعض البرامج يحتاج أن تبقى في حلقة لا منتهية إلى غاية نهاية البرنامج
مثال ذلك برنامج bash أو الطرفية فهو برنامج مؤسس من حلقة لا متناهية وهي كل مرة تدور فيها تنتظر من المستخدم أن يدخل أمرا لتنفذه
يستخدم الأمر breakوالأمر continueمع حلقات forوآافة حلقات التكرار
الأخرى مثل while , repeatوآما يلي :
.1الأمر breakويستخدم للسيطره على تدفق تكرار العبارات وهي تؤدي الى أنهاء
أو توقف التكرار ,مثال
For i: = 1 to 10 do begin ;( Readln( x If x < 0 then Break Else ;( ( Writeln( sqrt( x ;End
في هذه الحاله يتوقف التنفيذ عند ورود عدد سالب لعدم أمكانية أيجاد الجذر التربيعي
للعدد السالب .
.2الأمر continueويستخدم أيضا مع حلقات التكراروهو يعني أستمر مع حلقة
تكرار جديده أي أهمل تنفيذ الأوامر التي بعد الأمر continueعند تحقق شرط
معين حيث سيعيد المؤشر الى الأمر ) , forمثال
For i: = 1 to 10 do Begin ;(Readln(x If x < 0 then Continue Else ;((Writeln( sqrt(x ;End
في هذه الحاله عند ورود عدد سالب فأن الأمر continueسيمنع متابعة تنفيذ
العبارات الأخرى في حلقة التكرار والمتمثله بأمر الطباعه في هذا المثال ويعيد المؤشر
الى الأمر forليبدأ بتكرار جديد .
=================================================
الدورة منقولة من كتاب الأستاذ الفاضل معتز عبد العظيم وما تراه باللون الأخضر فمن زياداتي
