البرمجة بلغة C/ف3:بنى التكرار
المفهوم
عدلبنية التكرار، وتُسمَّى أيضاً الحلقة[هوامش 1]، هي جزء من البرنامج المكتوب بلغة C، يُنقل فيه تسلسل التنفيذ ليعيد تكرار عدد من العبارات تُسمى جسم الحلقة[هوامش 2]، ويتحدد تكرار التنفيذ بشرط يُسمَّى شرط التكرار. طالما كان الشرط محققاً، فإن تسلسل التنفيذ سيُعاد إلى بداية البنية لتنفيذها مجدداً.
ما يهم في بنى التكرار هو عدد مرات التكرار. بما بنى التكرار مرتبطة بشرط يحدد نهاية التكرار، فهذا يعني أن عدد مرات التكرار يتحدد بقيمة متغير واحد أو أكثر، يُسمَّى متغيير الحلقة، ويلزم عادة:
- ضبط القيمة الابتدائية لمتغير الحلقة، يلزم أن يُضبط المتغير قبل البدء بتنفيذ الحلقة.
- ضبط الطريقة التي تتغير فيها قيمة المُتغير، والتي تُسمى خطوة التغيير، وعادة تكون الخطوة ضمن جسم الحلقة، وهذا يعني أن التغيير سيطال المُتغير مع كل تكرار للحلقة.
- ضبط الشرط النهائي لإيقاف التكرار.
لو أريد مثلاً تكرار حلقة 50 مرة، يمكن أن تُضبط مُحددات الحلقة كما يأتي:
- التصريح عن متغير الحلقة، وليكن
i
مثلاً، وضبط قيمته الابتدائية إلى 0. - خطوة التغير الذي يُصيب المتغير، وليكن مثلاً +2.
- شرط النهاية وليكن مثلاً
i < 100
.
يعني هذا قيمة i
ستكون على الترتيب: 0 2 4 6 ... 100، وعدد هذه القيم 51 قيمة! وهي تضمن تنفيذ الحلقة 50 مرة فقط لأن القيمة الأخيرة لا تحقق الشرط.
ليس الضبط السابق هو الضبط الوحيد، فيمكن مثلاً ضبط خطوة التغيير إلى +1 وشرط النهاية إلى i < 50
، أو ضبط القيمة الابتدائية إلى 50 خطوة التغيير إلى -1 والشرط i > 0
، وما يهم في الحالات الثلاثة هو عدد مرات التكرار، وقيمته 51 في كل حالة.
تدعم لغة C ثلاثة بنى تكرار هي حلقة التكرار ذات الشرط المسبق while، وبنية التكرار ذات الشرط اللاحق do/while وبنية التكرار السياقية for. تفحص بنية التكرار ذات الشرط المسبق شرطها قبل البدء بتنفيذ جسم الحلقة، أما بنية التكرار ذات الشرط اللاحق do/while، فتفحص الشرط بعد تنفيذ جسم الحلقة، وهذا يعني أن الحلقة ستنفَّذ مرة واحد على الأقل أياً كان الشرط. أما بنية التكرار السياقية for، فلها سياق محدد لابد من ضبطه قبل البدء باستعمالها، يشمل هذا السياق تحدد المتغير الذي المرتبط بالحلقة وشرط الحلقة والتغيير الذي يحصل عليه مع كل دورة فيها.
بنية التكرار ذات الشرط المسبق while
عدلتتألف بنية التكرار ذات الشرط المسبق من الكلمة المحجوزة while
يليها تعبير شرطي يُسمى تعبير التحكم[هوامش 3] يوضع بين قوسين (
و)
وهو يضم متغير الحلقة عادةً، يلي ذلك جسم الحلقة الذي يُعاد تنفيذه من كل دورة تكرار، وعادة ما يحتوي على الخطوة التي تحدد كيفية تغير قيمة المُتغير.
يبدأ تنفيذ الحلقة بفحص تعبير التحكم، لو كانت قيمته مساوية للصفر، نُفِّذ جسم الحلقة مرة واحدة، ثُم أعيد فحص الشرط مجدداً، ويستمر التكرار حتى الحالة التي يُفحص فيها الشرط ولا تكون قيمته مساويةً للصفر، فيُنقل تسلسل التنفيذ إلى ما بعد جسم الحلقة. يمكن أيضاً كسر هذا التكرار والخروج من الحلقة باستعمال عبارات القفز: break وgoto وreturn، أما العبارة continue فإنها تسبب إهمال ما تبقى من جسم الحلقة والعودة إلى بدايتها لفحص الشرط مباشرةً، ولكن هذا لا يعني مغادرة الحلقة بالضرورة.
Statements A;
while (Control expression){
Statements B;
}
Statements C;
عدم ضبط قيمة المتغير المستعمل في تعبير التحكم هو من الأخطاء الشائعة عند استعمال بنية التكرار ذات الشرط المسبق، ويلزم دائماً التأكد من أن للمتغير قيمة ابتدائية محددة. عدم تغيير قيمة المتغير عند التكرار، أو تغيرها بطريقة لا تسبب جعل تعبير التحكم صفرياً يؤديان إلى جعل الحلقة غير نهائية، وهي حلقة لا يمكن الخروج منها وستتكرر نظرياً إلى الأبد، وهذان من الأخطاء الشائعة التي يلزم تجنبها.
- مثال
- برنامج يطبع الأعداد الصحيحة بين 1 و10.
#include <stdio.h>
int main () {
int x = 1;
while (x <= 10){
printf ("%d ", x);
x=x+1;
}
return 0;
}
الجمع التراكمي
عدل- طريقة لإيجاد مجموع الأرقام باستخدام حلقة while، يجب عليك تحديد:
- متغير لتخزين المواد المضافة المتراكمة (يجب ضبطه على 0)*
- نطاق الأرقام (القيمة الأولى والأخيرة)
- لا يوجد تغيير في النطاق مع كل تكرار
- للضرب التراكمي يجب أن تكون هذه القيمة 1.
- مثال 1
- مجموع الأعداد الزوجية بين 50 و 100:
- متغير لتخزين المجموع التراكمي
- نطاق الأعداد
- بدون تغيير
#include <stdio.h>
int main () {
int x = 50, s=0;
while (x <= 100){
s = s+ x;
x=x+2;
}
printf ("the sum is%d ", s);
return 0;
}
الضرب التراكمي
عدل- مثال 2
- عامل الضرب لعدد معين
- متغير لحفظ العدد المدخل المراد الحصول على العامل للضرب له
- نطاق الأعداد (بين 1 و N)
- بدون تغيير
#include <stdio.h>
int main () {
int N, fact=1;
printf ("Enter N\n");
scanf ("%d",&N);
while (N >= 1){
fact = fact * N;
N=N-1;
}
printf ("the production is %d ", fact);
return 0;
}
بنية التكرار ذات الشرط اللاحق while/do
عدلتبدأ بنية التكرار ذات الشرط اللاحق بالكلمة المحجوزة do
يليها جسم الحلقة ثُمَّ التعبير الشرطي. يعني هذا أن التنفيذ يبدأ بجسم الحلقة، أي Statements B
في الشكل، فيُنفَّذ مرة واحدة على الأقل، ثُمَّ يُفحص تعبير التحكم، فلو كانت قيمته مساوية للصفر، نُفِّذ جسم الحلقة مرة أخرى ثُم أعيد فحص الشرط مجدداً، ويستمر التكرار حتى الحالة التي يُفحص فيها الشرط ولا تكون قيمته مساويةً للصفر، فيُنقل تسلسل التنفيذ إلى ما بعد التعبير الشرطي، أي Statements C
.
يُمكِن، كما هو الحال في بنية التكرار ذات الشرط اللاحق، كسر التكرار والخروج من الحلقة باستعمال عبارات القفز: break
وgoto
وreturn،
أما العبارة continue
فإنها تسبب إهمال ما تبقى من جسم الحلقة والعودة إلى نهايتها لفحص الشرط مباشرةً، ولكن هذا لا يعني مغادرة الحلقة بالضرورة.
Statements A;
do {
Statements B;
} while (condition);
Statements C;
يلزم الانتباه إلى أن التعبير الشرطي في بنية التكرار ذات الشرط اللاحق يكون متبوعاً بفاصلة منقوطة ;
ويؤدي غياب هذه الفاصلة إلى حدوث خطأ عن تصريف البرنامج.
بنية التكرار السياقية for
عدل- حلقة تكرارية بشرط وحيد، بنية الحلقة:
for(متغير;الشرط;بدون تغيير){}
- يُفحص شرط الحلقة أولاً، إن كان محققاً، ينفذ تعليمات الحلقة ويعيد التحقق من الشرط مرّة أخرى.
- بمجرد التحقق من الشرط واكتشاف عدم صحته، يتوقف تكرار الحلقة.
- مثال
For (int i=0; i < 10 ; i++){ }
- اكتب برنامجاً يطبع الأعداد الزوجية بين 50 و100.
#include <stdio.h>
int main () {
for (int i=50; i <=100; i=i+2)
{
printf ("%d ", i);
}
return 0;
}
الحلقات المتداخلة
عدل- حلقتين أو أكثر، واحدة ضمن الأخرى.
- تتكرر الحلقة الداخلية كاملةً لكل تكرار للحلقة الخارجية.
- البنية:
for (متغير1; الشرط1; التغيير1){
for ((متغير2; الشرط2; التغيير2){
التعليمات البرمجية
- مثال
جدول الضرب للأعداد بين 1 و 9.
#include <stdio.h>
int main () {
int i, j, k;
for (int i=1; i<10; i++){
for (int j=1; j<10; j++){
k = i * j;
printf("%d=%d * %d"
"\n",k,i,j); }
printf("\n" );
}
return 0;
}