الـ Loops، عمليات تكرار الكود في البرمجة
السلام عليكم ورحمة الله وبركاته
الفهرس
المقدمة
سؤال سريع لو قلت لك أن تكتب برنامج يطبع الأرقام من 1
إلى 5
، كيف ستقوم بذلك ؟
الطريقة الأولى التي قد تتبادر إلى ذهنك هي كتابة الأرقام يدوياً:
cout << 1 << '\n';
cout << 2 << '\n';
cout << 3 << '\n';
cout << 4 << '\n';
cout << 5 << '\n';
حسنًا جيد ماذا عن من 1 إلى 10 ؟
cout << 1 << '\n';
cout << 2 << '\n';
cout << 3 << '\n';
cout << 4 << '\n';
cout << 5 << '\n';
cout << 6 << '\n';
cout << 7 << '\n';
cout << 8 << '\n';
cout << 9 << '\n';
cout << 10 << '\n';
حسنًا ... ماذا عن من 1
إلى 100
؟ أو انتظر لنجرب من 1
إلى 1000
، ما رأيك ؟
الأمر يبدو مملًا مكررًا وأيضًا يحتاج إلى وقت طويل للكتابة
لا تعتقد أن هناك شخص عاقل سيقوم بكتابة الأرقام من 1
إلى 1000
بهذه الطريقة أو من 1
إلى 10000
أكيد أصحاب ومخترعي لغات البرمجة قدموا لنا وسيلة تساعدنا في تكرار كود ما أومجموعة من الأكواد والأوامر
وبالفعل يوجد وسائل كثيرة لتكرار الكود في البرمجة وهي تسمى بالـ Loops
ومعناها حلقات تكرارية
أنواع الـ Loops
هناك العديد من الطرق لتكرار مجموعة من الأكواد واشهرها هي:
while
do-while
for
for-each
أوrange-based for
(يوجد اشكال ومسميات مختلفة لها في كل لغة)recursion
- ... وغيرها وكل لغة لديها وسائل خاصة بها للتكرار
كل لغة برمجة تحتوي على أوامر تكرارية تساعد المبرمجين على تكرار الأكواد بشكل متكرر وبسهولة
سنشرح هنا الطرق الأساسية للتكرار والتي ستصادفك في جميع لغات البرمجة بنفس الشكل وطريقة التنفيذ وهي while
و do-while
و for
وسنشرح الـ for-each
لكن في مقالة منفصلة عندما يحين وقتها
وهناك مقالة مفصلة عن الـ recursion
ستجدها في المدونة لكن لا تقرأها قبل أن تنتهي من سلسلة المقالات عن أساسيات البرمجة
الـ while loop
في لغات البرمجة نكتب الـ while
بالشكل التالي:
while (الشرط) {
// الكود المراد تكراره
}
ستلاحظ تشابه بين الـ while
والـ if
، فالشرط الذي نكتبه داخل الأقواس يكون مثل الشرط في الـ if
أي قيمة تعطينا boolean
أي قيمة true
أول false
ولكن الفرق أن الـ if
تنفذ ما بداخلها مرة واحدة فقط لو الشرط تحقق وأعطانا true
أما الـ while
يقوم بتكرار الكود ويظل تنفذ ما بداخله طالما الشرط يعطينا true
int i = 0;
if (i < 5) {
cout << "i is: " << i << '\n';
}
في هذا المثال، سيتم طباعة قيمة i
إذا كانت أقل من 5
بالتالي قيمة i
حاليًا بـ 0
فسيتم تنفيذ الشرط المكتوب في الـ if
وطالما الشرط يعطينا true
فسيتم طباعة i is: 0
وبعدها يتوقف التنفيذ ويخرج من الـ if
أما في حالة الـ while
:
int i = 0;
while (i < 5) {
cout << "i is: " << i << '\n';
}
سيتم طباعة قيمة i
طالما هي أقل من 5
بالتالي بسبب أن قيمة i
تساوي 0
والشرط الذي كتبناه داخل الـ while
يعطينا true
سيتم تنفيذ الكود المكتوب داخل الـ while
وسيتم طباعة i is: 0
ثم ... ثم .. هل تستطيع التخمين ماذا سيحدث بعد ذلك ؟
بالتأكيد سيتم تكرار الكود المكتوب داخل الـ while
مرة أخرى وسيتم طباعة i is: 0
مرة أخرى
لأن الشرط لازال يعطينا true
في كل مرة يتم فيها تنفيذ الكود داخل الـ while
والـ while
كما قلنا تظل تنفذ الكود داخلها طالما الشرط يعطينا true
وهكذا سيتم طباعة i is: 0
بشكل لا نهائي هكذا:
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
i is: 0
... etc. (infinity loop)
إذا ما الحل ؟
الحل بسيط وهو تغيير قيمة i
داخل الـ while
بعد كل مرة يتم فيها تنفيذ الـ while
بالتالي نضمن أن الشرط سيعطينا false
في النهاية ويتوقف التنفيذ
int i = 0;
while (i < 5) {
cout << "i is: " << i << '\n';
i = i + 1; // or i++ or i += 1
}
لاحظ أننا نقوم بزيادة قيمة i
بمقدار 1
في كل مرة يتم فيها تنفيذ الـ while
بالتالي نضمن أن الشرط i < 5
سيعطينا false
بعد 5
مرات تنفيذ للـ while
ويتوقف التنفيذ
وبالتالي سيتم طباعة الأرقام من 0
إلى 4
فقط
i is: 0
i is: 1
i is: 2
i is: 3
i is: 4
لنحلل الكود:
قيمة i |
الشرط i < 5 |
النتيجة |
---|---|---|
0 | الشرط 0 < 5 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 0 ثم يقوم بزيادة قيمة i ليصبح 1 |
1 | الشرط 1 < 5 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 1 ثم يقوم بزيادة قيمة i ليصبح 2 |
2 | الشرط 2 < 5 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 2 ثم يقوم بزيادة قيمة i ليصبح 3 |
3 | الشرط 3 < 5 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 3 ثم يقوم بزيادة قيمة i ليصبح 4 |
4 | الشرط 4 < 5 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 4 ثم يقوم بزيادة قيمة i ليصبح 5 |
5 | الشرط 5 < 5 سيعطي false |
لن ينفذ ما بداخل الـ while ويتوقف التنفيذ |
- في البداية قمنا بتعريف متغير
i
بقيمة0
- ثم بدأنا الـ
while
وكتبنا الشرطi < 5
وهو يعطيناtrue
لأن قيمةi
تساوي0
- ثم قمنا بطباعة
i is: 0
- ثم قمنا بزيادة قيمة
i
بمقدار1
لتصبح1
- ثم يعود الـ
while
للتحقق من الشرطi < 5
هل مازال يعطيناtrue
أم لا سيجد أن1 < 5
تعطيناtrue
- اذًا سيعود لتنفيذ ما بداخله مجددًا ويتم طباعة
i is: 1
- ثم يتم زيادة قيمة
i
بمقدار1
لتصبح2
- ثم يعيد التحقق من الشرط
i < 5
ثم يعود لتنفيذ ما بداخله مجددًا ويتم طباعةi is: 2
- وهكذا حتى يصل
i
إلى5
ويتوقف التنفيذ لأن الشرطi < 5
لن يعطيناtrue
بعد ذلك لأن5 < 5
تعطيناfalse
- هكذا يتم طباعة الأرقام من
0
إلى4
فقط
أمثلة على الـ while loop
لنرجع لسؤالنا الأول اطبع لي الأرقام من 1
إلى 100000
هل ستقوم بكتابة الأرقام يدويًا ؟ أم ستستخدم الـ while
؟ بالتأكيد ستستخدم الـ while
int i = 1;
while (i <= 100000) {
cout << i << '\n';
i++;
}
انتهينا!!
أنظر إلى الجمال والسهولة في كتابة الأكواد والتكرار بدون عناء
هل يمكنك كتابة جدول الضرب الخاص بالعدد 8
؟
هل يمكنك أن تفكر كيف ستساعدك الـ while
في ذلك ؟
int i = 0;
while (i <= 12) {
cout << i << " × 8 = " << i * 8 << '\n';
i++;
}
النتيجة:
0 × 8 = 0
1 × 8 = 8
2 × 8 = 16
3 × 8 = 24
4 × 8 = 32
5 × 8 = 40
6 × 8 = 48
7 × 8 = 56
8 × 8 = 64
9 × 8 = 72
10 × 8 = 80
11 × 8 = 88
12 × 8 = 96
ما رأيك ؟
لنحلل الكود:
- في البداية قمنا بتعريف متغير
i
بقيمة0
لنبدأ من0
وننتهي بـ12
- ثم بدأنا الـ
while
وكتبنا الشرطi <= 12
لأننا نريد طباعة جدول الضرب من0
إلى12
- ثم قمنا بطباعة قيمة
i
يليها جملة* 8 =
ثم قيمةi * 8
ليصبح الشكل واضح للقارئ بأنه جدول ضرب ويظهر له الناتج بهذا الشكل0 × 8 = 0
،1 × 8 = 8
،2 × 8 = 16
، ... وهكذا - ثم زيادة قيمة
i
بمقدار1
بعد كل مرة يتم فيها تنفيذ الـwhile
لضمام عدم دخولنا لحلقة لا نهايةinfinity loop
قيمة i |
الشرط i <= 12 |
النتيجة |
---|---|---|
0 | الشرط 0 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 0 ثم يقوم بزيادة قيمة i ليصبح 1 |
1 | الشرط 1 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 1 ثم يقوم بزيادة قيمة i ليصبح 2 |
2 | الشرط 2 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 2 ثم يقوم بزيادة قيمة i ليصبح 3 |
3 | الشرط 3 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 3 ثم يقوم بزيادة قيمة i ليصبح 4 |
4 | الشرط 4 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 4 ثم يقوم بزيادة قيمة i ليصبح 5 |
5 | الشرط 5 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 5 ثم يقوم بزيادة قيمة i ليصبح 6 |
6 | الشرط 6 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 6 ثم يقوم بزيادة قيمة i ليصبح 7 |
7 | الشرط 7 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 7 ثم يقوم بزيادة قيمة i ليصبح 8 |
8 | الشرط 8 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 8 ثم يقوم بزيادة قيمة i ليصبح 9 |
9 | الشرط 9 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 9 ثم يقوم بزيادة قيمة i ليصبح 10 |
10 | الشرط 10 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 10 ثم يقوم بزيادة قيمة i ليصبح 11 |
11 | الشرط 11 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 11 ثم يقوم بزيادة قيمة i ليصبح 12 |
12 | الشرط 12 <= 12 سيعطي true |
سينفذ ما بداخل الـ while ويطبع 12 ثم يقوم بزيادة قيمة i ليصبح 13 |
13 | الشرط 13 <= 12 سيعطي false |
لن ينفذ ما بداخل الـ while ويتوقف التنفيذ |
سؤال هل يمكنك جمع الأرقام من 1
إلى 100
؟
أظن أنه سؤال جميل وممتع ويحتاج إلى القليل من التفكير
أكيد لن نقوم بكتابة الأرقام يدويًا ونقوم بجمعها هكذا:
int sum = 0;
sum = 1 + 2 + 3 + 4 + 5 + 6 + 7 + ... + 100;
نريد أن نستخدم الـ while
لجمع الأرقام من 1
إلى 100
وطباعة الناتج النهائي
لذا نحتاج لمتغير يبدأ قيمته من 1
ويزيد بمقدار 1
كل مرة
وفي كل مرة نقوم بجمع في متغير آخر ليحتفظ بالناتج النهائي
فلنفترض أن المتغير يسمى i
الذي سيبدأ من 1
ويزيد بمقدار 1
كل مرة
فأول مرة سيكون المتغير i = 1
ثم نقوم بجمع 1
في المتغير sum
ويصبح sum = 1
ثم يتم زيادة قيمة i
بمقدار 1
ليصبح i = 2
ثم نقوم بجمع 2
في sum
ويصبح sum = 3
ثم يتم زيادة قيمة i
بمقدار 1
ليصبح i = 3
ثم نقوم بجمع 3
في sum
ويصبح sum = 6
وهكذا حتى يصل i
إلى 100
ويتوقف التنفيذ ويتم طباعة الناتج النهائي
int i = 1;
int sum = 0;
while (i <= 100) {
sum += i;
i++;
}
cout << "The sum of numbers from 1 to 100 is: " << sum << '\n';
النتيجة:
The sum of numbers from 1 to 100 is: 5050
ما رأيك ؟ ما الذي حصل هنا ؟
ما حصل هو ما كنا نتحدث عنه سابقًا ببساطة قمنا بتعريف متغير i
بقيمة 1
ثم قمنا بتعريف متغير sum
بقيمة 0
وهو الذي سيحتفظ بالناتج النهائي
ثم كل ما نحتاجه هو جمع المتغير i
في المتغير sum
ثم نزيد قيمة المتغير i
بمقدار 1
ونعيد جمعه مرة أخرى في sum
بحيث أن في المرة عندما يكون i = 1
سيتم جمع 1
في sum
ويصبح sum = 1
ثم يتم زيادة قيمة i
بمقدار 1
ليصبح i = 2
ويتم جمع 2
في sum
ويصبح sum = 3
ثم يتم زيادة قيمة i
بمقدار 1
ليصبح i = 3
ويتم جمع 3
في sum
ويصبح sum = 6
وهكذا حتى يصل i
إلى 100
ويتوقف التنفيذ ويتم طباعة الناتج النهائي
لذا كل ما كنا نحتاجه هو تكرار تلك العملية لذا استخدمنا الـ while
لتكرار عملية زيادة قيمة i
بمقدار 1
وجمعه مع sum
حتى يصل i
إلى 100
سؤال أخير ما رأيك بجمع الأرقام الزوجية فقط التي تقع بين 1
و 100
؟
هل يمكنك حل هذا السؤال ؟
الأمر مثله مثل المثال السابق مع تغير بسيط جدًا
int i = 2;
int sum = 0;
while (i <= 100) {
sum += i;
i += 2;
}
cout << "The sum of even numbers from 1 to 100 is: " << sum << '\n';
النتيجة:
The sum of even numbers from 1 to 100 is: 2550
لاحظ أنه نفس الحل السابق تمامًا ولكن الفرق أننا جعلنا i
يبدأ من 2
ثم نقوم بزيادة قيمة i
بمقدار 2
بدلًا من 1
وهذا يعني أننا سنقوم بجمع الأرقام الزوجية فقط وليس جميع الأرقام لأن قيمة i
تزيد بمقدار 2
في كل مرة
بالتالي أول مرة سيكون i = 2
ثم i = 4
ثم i = 6
وهكذا حتى يصل i
إلى 100
ويتوقف التنفيذ
وكل مرة يتم جمع قيمة i
في sum
ماذا عن الأرقام الفردية ؟ أظنك تستطيع حلها بنفس الطريقة السابقة دون حتى أن اشرحها لك
الـ do-while loop
الـ do-while
تشبه الـ while
ولكن الفرق الوحيد بينهما هو أن الـ do-while
يضمن لنا تنفيذ الكود داخله مرة واحدة على الأقل
لأنه يقوم بتنفيذ الكود داخله ثم يقوم بالتحقق من الشرط
أما الـ while
كانت تقوم بالتحقق من الشرط ثم تقوم بتنفيذ الكود داخله
do {
// الكود المراد تكراره
} while (الشرط);
لاحظ أننا نكتب الـ do
ثم الكود المراد تكراره ثم الـ while
والشرط
وهذا يعني أن الكود المكتوب داخل الـ do
سيتم تنفيذه مرة واحدة على الأقل ثم يتم التحقق من الشرط
وإذا كان الشرط يعطينا true
سيتم تنفيذ الكود مرة أخرى وهكذا حتى يعطينا الشرط false
الأمر مثله مثل الـ while
ولكن الـ do-while
يضمن لنا تنفيذ الكود مرة واحدة على الأقل حتى لو كان الشرط يعطينا false
من البداية
do {
cout << "I will be printed once" << '\n';
} while (false);
في هذا المثال سيتم طباعة الجملة I will be printed once
مرة واحدة فقط
برغم أن الشرط الذي داخل الـ while
قيمته false
while (false) {
cout << "I will not be printed" << '\n';
}
أما في هذا المثال فلن يتم طباعة الجملة I will not be printed
أبدًا
لأن الشرط الذي داخل الـ while
قيمته false
ولن يتم تنفيذ الكود داخله
لكن في الـ do-while
كان يضمن لنا تنفيذ الكود مرة واحدة على الأقل حتى لو كان الشرط يعطينا false
من البداية
لنفترض مثال بسيط جدًا لنفترض أنك تريد أن تجمع رقمين موجبين فقط
وتطلب من المستخدم إدخال رقمين وتقوم بجمعهما وطباعة الناتج
لكن الشرط أن الرقمين يجب أن يكونا موجبين فقط وإذا كان أحد الرقمين سالبًا يجب على المستخدم إعادة إدخال الرقمين
لاحظ ما قلته ؟ قلت:
- نطلب منه الرقمين أولًا
- ثم نقوم بالتحقق من الشرط هل هما موجبان أم لا
- ثم نعيد الطلب مرة أخرى إذا كان أحد الرقمين سالبًا
هذا تمامًا ما يقوم به الـ do-while
يقوم بتنفيذ الكود مرة واحدة على الأقل ثم يقوم بالتحقق من الشرط ثم يظل يعيد تنفيذ الكود حتى يعطينا الشرط false
int num1, num2;
do {
cout << "Enter the first positive number: ";
cin >> num1; // قراءة الرقم الأول من المستخدم
cout << "Enter the second positive number: ";
cin >> num2; // قراءة الرقم الثاني من المستخدم
} while (num1 <= 0 || num2 <= 0);
cout << "The sum of " << num1 << " and " << num2 << " is: " << num1 + num2 << '\n';
لاحظ هنا أننا عرفنا متغيرين num1
و num2
ثم قمنا بطلب من المستخدم إدخال الرقمين num1
و num2
ثم لاحظ أننا قمنا بالتحقق من الشرط num1 <= 0 || num2 <= 0
أي هل أحد الرقمين سالبًا أم لا
وإذا كان أحد الرقمين سالبًا سيتم طلب إعادة إدخال الرقمين مرة أخرى
وهكذا حتى يدخل المستخدم رقمين موجبين فقط
ثم بعد ذلك سيتم طباعة الناتج النهائي لجمع الرقمين
لاحظ جيدًا أننا استخدمنا الـ do-while
لسؤال المستخدم أن يدخل الرقمين مرة واحدة على الأقل ثم نقوم بتحقق من الشرط كخطوة ثانية لتأكيد أن الرقمين موجبين فقط أم لا
هل تستطيع أن تفعل ذلك بالـ while
نعم لكن سيحدث تكرار غير ضروري للكود ولن يكون منطقيًا
int num1, num2;
cout << "Enter the first positive number: ";
cin >> num1;
cout << "Enter the second positive number: ";
cin >> num2;
while (num1 <= 0 || num2 <= 0) {
cout << "Enter the first positive number: ";
cin >> num1;
cout << "Enter the second positive number: ";
cin >> num2;
}
cout << "The sum of " << num1 << " and " << num2 << " is: " << num1 + num2 << '\n';
هنا سيتم طلب من المستخدم إدخال الرقمين ثم سيتم الدخول للـ while
للتحقق من الشرط هل الرقمين موجبين أم لا
وإذا كان أحد الرقمين سالبًا سيتم طلب إعادة إدخال الرقمين مرة أخرى ويظل يطلب من المستخدم إعادة الإدخال حتى يدخل رقمين موجبين فقط
لاحظ أننا قمنا بتكرار الكود المكتوب داخل الـ while
مرتين مرة خارج الـ while
لأننا يجب أن نحصل على الرقمين أولًا
ثم كررنا نفس الكود داخل الـ while
لجعل المستخدم يعيد إدخال الرقمين إذا كان أحد الرقمين سالبًا
الـ do-while
يختصر لنا الكود ويلغي التكرار الغير ضروري للكود الذي حصل في الـ while
ملحوظة
: أمرcin
مجرد أمر في لغة البرمجةC++
لاسناد القيم والبيانات للمتغير عن طريق المستخدم وهو فقط يستقبل القيمة الذي يدخله المستخدم ويسنده للمتغير الذي نضعه بعد علامة>>
لا تحاول التركيز معه كثيرًا هنا، فقط تعلم أنه يستقبل البيانات من المستخدم
أغلب اللغات لديها أمر إدخال مشابه له مثلinput
فيPython
أوprompt
فيJavaScript
وcin
فيC++
وغيرها
فقط مجرد أوامر تستقبل القيم من المستخدم
cin >> name; // C++
scanf("%s", name); // C
name = input("Enter your name: ") // Python
name = prompt("Enter your name: ") // JavaScript
name = readline("Enter your name: ") // PHP
كل هذه الأوامر تقوم بنفس الغرض وهو استقبال قيمة من المستخدم واسنداها للمتغير الذي يدعى
name
أمثلة على الـ do-while loop
لنقم بعمل مثال بسيط وهو نطلب من المستخدم ادخال اسمه
ونشترط عليه أن يبدأ الاسم بحرف A
فقط
string name;
do {
cout << "Enter your name: ";
cin >> name;
} while (name[0] != 'A');
cout << "Welcome " << name << '\n';
هنا قمنا بتعريف متغير name
من نوع string
ليحتفظ بالاسم الذي يدخله المستخدم
ثم قمنا بطلب من المستخدم إدخال اسمه
ثم قمنا بالتحقق من الشرط هل يبدأ الاسم بحرف A
أم لا
إذا كان يبدأ بحرف A
سيتم الخروج من الـ do-while
ويتم طباعة الجملة Welcome
مع الاسم الذي أدخله المستخدم
إذا لم يبدأ بحرف A
سيظل يعيد طلب من المستخدم أن يقوم بإدخال الاسم مرة أخرى حتى يقوم بإدخال اسم يبدأ بحرف A
لنعطي مثال آخر لنقم بطلب من المستخدم إدخال رقمين
ثم نقوم نعطيه مجموعة من الاختيارات، هل يريد جمع الرقمين أم طرحهما أم ضربهما أم قسمتهما
ونقوم بتنفيذ العملية المطلوبة وطباعة الناتج
ثم نسأله هل يريد القيام بعملية أخرى أم لا
int num1, num2, choice;
do {
cout << "Enter the first number: ";
cin >> num1;
cout << "Enter the second number: ";
cin >> num2;
cout << "Choose the operation you want to do: \n";
cout << "1. Add\n";
cout << "2. Subtract\n";
cout << "3. Multiply\n";
cout << "4. Divide\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "The sum of " << num1 << " and " << num2 << " is: " << num1 + num2 << '\n';
break;
case 2:
cout << "The subtraction of " << num1 << " and " << num2 << " is: " << num1 - num2 << '\n';
break;
case 3:
cout << "The multiplication of " << num1 << " and " << num2 << " is: " << num1 * num2 << '\n';
break;
case 4:
cout << "The division of " << num1 << " and " << num2 << " is: " << num1 / num2 << '\n';
break;
default:
cout << "Invalid choice\n";
}
cout << "Do you want to do another operation? (1 for yes, anything else for no): ";
cin >> choice;
} while (choice == 1);
cout << "Thank you for using our calculator\n";
الكود كبير قليلًا لكن لا تقلق يمكننا تحليله
إن قرأت الكود بتمعن ستجد أنه ليس بالصعوبة التي تتخيلها
بالطبع أنت تعرف الـ switch
وكيفية عمله وكيفية استخدامه
لنقم بتحليل الكود:
- في البداية قمنا بتعريف متغيرين
num1
وnum2
ليحتفظا بالرقمين الذي يدخلهما المستخدم
ومتغيرchoice
ليحتفظ بالاختيار الذي يقوم به المستخدم - ثم قمنا بطلب من المستخدم إدخال الرقمين
num1
وnum2
- ثم قمنا بطلب من المستخدم اختيار العملية التي يريد القيام بها، هل يريد جمع الرقمين أم طرحهما أم ضربهما أم قسمتهما
وقمنا بتخزين الاختيار في المتغيرchoice
- ثم قمنا بتنفيذ العملية المطلوبة وطباعة الناتج عن طريق
switch
- ثم قمنا بطلب من المستخدم هل يريد القيام بعملية أخرى أم لا
وقمنا بتخزين الاختيار في المتغيرchoice
- إذا كان الجواب
1
سيتم الدخول للـdo-while
مرة أخرى ويتم تنفيذ العملية مرة أخرى - إذا كان الجواب غير
1
سيتم الخروج من الـdo-while
ويتم طباعة الجملةThank you for using our calculator
أريدك أن تراجع الكود جيدًا وتحاول فهمه جيدًا وتحليله
أهم شيء أو أهم مهارة عليك اكتسابها هي تحليل وتتبع أي كود تراه وفهمه جيدًا حتى إذا كان كبيرًا جدًا
هذه المهارة ستساعدك كثيرًا في فهم الأكواد الكبيرة والمعقدة والتي لم تكتبها أنت بالتالي ستكون قادرًا على فهمها وتعديلها أو تحسينها أو تطويرها
الـ for loop
الـ for
هو نوع آخر من أدوات التكرار ولكنه يختلف عن الـ while
والـ do-while
من حيث الكتابة وطريقة التنفيذ
الـ for
تحاول تقديم طريقة أسهل لتكرار الكود وتقليل الأخطاء التي قد تحدث بحيث تجمع كل شيء تريده في سطر واحد
for (1; 2; 4) {
// 3: الكود المراد تكراره
}
تنقسم الـ for
إلى أربعة أقسام مهمة:
- القسم الأول: نستطيع فيه تعريف المتغير الذي سنستخدمه داخل الـ
loop
ونستطيع اعطاء قيمة أولية له
مثلint i = 0
هنا قمنا بتعريف متغيرi
من نوعint
وأعطيناه قيمة ابتدائية0
- القسم الثاني: هو المكان الذي نضع فيه الشرط الخاص بالـ
loop
وهو الشرط الذي يحدد متى يتوقف التكرار
مثلi < 5
هنا قمنا بوضع الشرط أن يتوقف التكرار عندما يكونi < 5
- القسم الثالث: هو المكان الذي نقوم فيه بكتابة الكود الذي نريد تكراره
- القسم الرابع: هو المكان الذي نقوم فيه بزيادة قيمة المتغير الذي قمنا بتعريفه في القسم الأول
مثلi++
هنا قمنا بزيادة قيمة المتغيرi
بمقدار1
بعد كل تكرار
- لاحظ أن القسم الأول والثاني والرابع يفصل بينهم فاصلة منقوطة
;
وليس فاصلة عادية,
الـ for
يقوم بتنفيذ القسم الأول أولًا مرة واحدة فقط ثم يقوم بالتحقق من القسم الثاني الذي فيه الشرط
إذا كان الشرط يعطينا true
سيتم تنفيذ الكود الذي في القسم الثالث ثم ينتقل إلى القسم الرابع ليحدث قيمة المتغير
ثم يظل يكرر المرور على القسم الثاني ثم القسم الثالث ثم القسم الرابع حتى يعطينا الشرط الذي في القسم الثاني false
لنجمع ما قلناه في مثال بسيط لنقوم بطباعة الأرقام من 0
إلى 4
for (int i = 0; i < 5; i++) {
cout << i << '\n';
}
حسنًا ركز معي جيدًا هنا
في البداية قمنا بتعريف متغير i
من نوع int
وأعطيناه قيمة ابتدائية 0
في القسم الأول من الـ for
وهذا التعريف يحدث مرة واحدة فقط
ثم في القسم الثاني قمنا بوضع الشرط i < 5
ثم في القسم الثالث قمنا بكتابة الكود المراد تكراره وهنا نحن فقط نقوم بطباعة قيمة المتغير i
هكذا cout << i << '\n';
ثم في القسم الرابع قمنا بزيادة قيمة المتغير i
بمقدار 1
بعد كل لفة هكذا i++
كيف ينتقل الـ for
بين الأقسام ؟
- في البداية يقوم بتنفيذ القسم الأول مرة واحدة فقط
- ثم يقوم بالتحقق من الشرط في القسم الثاني
- ثم يقوم بتنفيذ الكود في القسم الثالث
- ثم يقوم بتنفيذ القسم الرابع
- ثم يظل يحوم بين القسم الثاني والثالث والرابع بالترتيب حتى يعطينا الشرط الذي في القسم الثاني
false
بالتالي في الكود السابق سيتم طباعة الأرقام من 0
إلى 4
لنعد كتابته هنا مجددًا لنعلق عليه ونوضح كيف سيسير التنفيذ
for (int i = 0; i < 5; i++) {
cout << i << '\n';
}
- في البداية سيتم تنفيذ القسم الأول وسيتم تعريف متغير
i
وإعطائه قيمة ابتدائية0
- ثم سيتم التحقق من الشرط في القسم الثاني هل
i < 5
نعم0 < 5
يعطيناtrue
- ثم سيتم تنفيذ الكود في القسم الثالث وسيتم طباعة قيمة المتغير
i
وهي0
- ثم سيتم تنفيذ القسم الرابع وسيتم زيادة قيمة المتغير
i
بمقدار1
ويصبحi = 1
- ثم سيتم التحقق من الشرط في القسم الثاني هل
i < 5
نعم1 < 5
يعطيناtrue
- ثم سيتم تنفيذ الكود في القسم الثالث وسيتم طباعة قيمة المتغير
i
وهي1
- ثم سيتم تنفيذ القسم الرابع وسيتم زيادة قيمة المتغير
i
بمقدار1
ويصبحi = 2
- وهكذا سيذهب لتتحقق من الشرط ويتم تنفيذ الكود وزيادة قيمة المتغير حتى يصل
i
إلى5
ويتوقف التنفيذ - وهذا يعني أنه سيتم طباعة الأرقام من
0
إلى4
فقط
لاحظ شيء مهم جدًا أن الكود الذي نكتبه بالـ for
نستطيع كتابته بالـ while
والعكس
لكن الـ for
يحاول تقديم طريقة أسهل لكتابة الكود while
لاحظ الفرق بين طريقة الكتابة بالـ for
والـ while
في نفس المثال
// for
for (int i = 0; i < 5; i++) {
cout << i << '\n';
}
// while
int i = 0;
while (i < 5) {
cout << i << '\n';
i++;
}
كلاهما يقومان بنفس العمل ولكن الـ for
يحاول تقديم طريقة أسهل لكتابة الكود وتجميع كل شيء في سطر واحد
لكن ستجد في بعض الأحيان أن الـ while
أسهل لكتابة الكود وأوضح بكثير
أنت في النهاية تختار الأداة التي تجد أنها تناسبك أكثر في الموقف الذي تواجهه
أمثلة على الـ for loop
لنقم بعمل مثال بسيط وهو جمع الأرقام من 1
إلى 10
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum = sum + i;
}
cout << "The sum of numbers from 1 to 10 is: " << sum << '\n';
هنا قمنا بتعريف متغير sum
وأعطيناه قيمة ابتدائية 0
ثم قمنا بالدخول للـ for
وتعريف متغير i
وأعطيناه قيمة ابتدائية 1
ووضعنا الشرط i <= 10
وهذا يعني أن التكرار سيتوقف عندما يكون i
أكبر من 10
ثم قمنا بجمع قيمة المتغير i
في المتغير sum
ثم زيادة قيمة المتغير i
بمقدار 1
بعد كل تكرار
وبعد الانتهاء من التكرار سيتم طباعة قيمة المتغير sum
وهي الناتج النهائي لجمع الأرقام من 1
إلى 10
قيمة i |
قيمة sum قبل الجمع |
قيمة sum بعد الجمع sum = sum + i |
---|---|---|
1 | 0 | 1 |
2 | 1 | 3 |
3 | 3 | 6 |
4 | 6 | 10 |
5 | 10 | 15 |
6 | 15 | 21 |
7 | 21 | 28 |
8 | 28 | 36 |
9 | 36 | 45 |
10 | 45 | 55 |
وبعد الانتهاء من كل اللفات سيتم طباعة الناتج النهائي 55
لنأخذ مثال جميل نريد إيجاد مضروب العدد n
أيًا كان
والمضروب هو لو كان n = 5
فإن المضروب هو 5 * 4 * 3 * 2 * 1
int n = 5;
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial = factorial * i;
}
cout << "The factorial of " << n << " is: " << factorial << '\n';
هنا قمنا بتعريف متغير n
وأعطيناه قيمة 5
ثم قمنا بتعريف متغير factorial
وأعطيناه قيمة ابتدائية 1
لأننا سنقوم بعملية الضرب فيه
ثم قمنا بالدخول للـ for
وتعريف متغير i
وأعطيناه قيمة 1
ووضعنا الشرط i <= n
وهذا يعني أن التكرار سيتوقف عندما يكون i
أكبر من n
ثم قمنا بضرب قيمة المتغير i
في المتغير factorial
وحفظ الناتج في نفس المتغير factorial
ففي البداية factorial = 1
وi = 1
سيتم الضرب factorial = 1 * 1
ويصبح factorial = 1
ثم في اللفة الثانية factorial = 1
وi = 2
سيتم الضرب factorial = 5 * 2
ويصبح factorial = 10
وهكذا حتى يصل i
إلى 5
ويتوقف التكرار
قيمة i |
قيمة factorial قبل الضرب |
قيمة factorial بعد الضرب factorial = factorial * i |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 6 |
4 | 6 | 24 |
5 | 24 | 120 |
وبعد الانتهاء من كل اللفات سيكون factorial = 120
وهذا هو المضروب للعدد 5
لاحظ أن القيمة الابتدائية للمتغير factorial
كانت 1
لأننا سنقوم بعملية الضرب فيه ولو كانت الابتدائية 0
لكانت كل النواتج ستكون دائمًا بـ 0
ملحوظات مهمة عن الـ for loop
يمكننا تعريف أكثر من متغير في أي قسم في الـ
for
ولكن يجب فصلهم بفاصلة,
معادا الشرطfor (int i = 0, j = 0; i < 5 && j < 5; i++, j++) { // الكود المراد تكراره }
يمكننا ترك أي قسم فارغًا وعدم كتابة شيء فيه
فمثلاً إذا كنت لا تريد تعريف متغير في القسم الأول يمكنك تركه فارغًا وتعريف المتغير خارج الـ
for
int i = 0; for (; i < 5; i++) { // الكود المراد تكراره }
أو إذا كنت لا تريد وضع شرط يمكنك ترك القسم الثاني فارغًا
وهذا يعني أن الشرط يعطيناtrue
دائمًا ولن يتوقف التكرار أبدًا
وهذا يعني أنك ستحتاج لوضع شرط توقف داخل الـloop
نفسه
عن طريقbreak
والتي سنتعرف عليها بعد قليلfor (int i = 0; ;i++) { // الكود المراد تكراره if (i == 5) { break; } }
أو إذا كنت لا تريد زيادة قيمة المتغير بعد كل تكرار يمكنك ترك القسم الرابع فارغًا
وزيادة قيمة المتغير داخل الـloop
نفسهfor (int i = 0; i < 5;) { // الكود المراد تكراره i++; }
في الواقع يمكننا كتابة الـ
for
بطريقة تشبه الـwhile
int i = 0; for (;i < 5;) { // الكود المراد تكراره i++; }
المتغيرات التي نقوم بتعريفها في الـ
for
تكون محدودة بالـloop
نفسه ولا يمكننا استخدامها خارج الـloop
for (int i = 0; i < 5; i++) { // الكود المراد تكراره } cout << i; // loop غير معرف خارج الـ i سيعطينا خطأ لأن المتغير
continue و break
في بعض الأحيان قد نحتاج للخروج من الـ loop
مبكرًا عندما يحصل شرط معين أو نريد أن نتخطى بعض الحالات ونوقف تنفيذ الـ loop
في حالات معينة وأخرى لا
لهذا الغرض يوجد أمرين مهمين في الـ loop
هما continue
و break
continue
الأمر continue
يقوم بتجاهل الكود الذي بعده وينتقل إلى اللفة التالي مباشرة
ويستخدم عندما نريد تجاهل بعض الحالات وننتقل إلى الحالة التالية
ويستخدم في الـ for
والـ while
والـ do-while
لنقم بمثال بسيط لنقوم بطباعة الأرقام من 0
إلى 4
ولكن نريد تجاهل الرقم 2
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue; // تجاهل هذه اللفة ولا تكمل وانتقل إلى اللفة التالية
}
cout << i << '\n';
}
هنا لاحظ أننا قمنا بتعريف متغير i
ونريد طباعة الأرقام من 0
إلى 4
لكن قبل طباعة الرقم نقوم بالتحقق إذا كان الرقم 2
نقوم بتجاهله وننتقل إلى الرقم التالي عن طريق continue
وهكذا سيتم طباعة الأرقام 0
و 1
و 3
و 4
فقط ولن يتم طباعة الرقم 2
مثال آخر نريد طباعة الأرقام الزوجية فقط التي تقع بين 0
و 10
for (int i = 0; i <= 10; i++) {
if (i % 2 != 0) {
continue; // انتقل إلى اللفة التالية عندما تقابل أي رقم فردي
}
cout << i << '\n';
}
هنا قمنا بتعريف متغير i
ونريد طباعة الأرقام من 0
إلى 10
لكن قبل طباعة الرقم نقوم بالتحقق إذا كان الرقم فردي نقوم بتجاهله وننتقل إلى الرقم التالي عن طريق continue
وهكذا سيتم طباعة الأرقام الزوجية فقط 0
و 2
و 4
و 6
و 8
و 10
break
الأمر break
يقوم بإيقاف تنفيذ الـ loop
فورًا والخروج منه وليس الانتقال إلى اللفة التالية كما في continue
فمثلاً لنفترض أننا نريد الخروج من الـ loop
عندما نصل إلى الرقم 5
for (int i = 0; i <= 10; i++) {
if (i == 5) {
break; // انتهي من الـ loop عندما يكون الرقم 5
}
cout << i << '\n';
}
هنا قمنا بتعريف متغير i
ونريد طباعة الأرقام من 0
إلى 10
لكنه قبل طباعة الرقم يقوم بالتحقق إذا كان الرقم 5
أم لا
فإذا كان الرقم 5
سيتم الخروج من الـ loop
فورًا ولن يتم استكمال الـ loop
ولا طباعة الرقم 5
ولا الأرقام التي بعده
بالتالي سيتم طباعة الأرقام من 0
إلى 4
فقط وعندما يصل إلى الرقم 5
سيتم الخروج من الـ loop
ولن يستكمل باقي اللفات
لنفترض أننا نقوم بالبحث عن أول رقم يقع بين الـ 0
و 100
ويكون يقبل القسمة على 3
و 5
في نفس الوقت
فنحن هنا سنقوم بعمل الـ loop
من 0
إلى 100
ثم نتحقق من كل رقم ونرى هل يقبل القسمة على 3
و 5
في نفس الوقت أم لا
for (int i = 0; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
cout << "The number " << i << " is divisible by 3 and 5\n";
break; // لقد وجدنا الرقم الذي نريده فلا داعي لاكمال البحث
}
}
هنا قمنا بكتابة شرط يقوم بالتحقق إذا كان الرقم يقبل القسمة على 3
و 5
في نفس الوقت
وعندما يتحقق الشرط ونجد الرقم الذي نبحث عنه يمكنك استخدام break
للخروج من الـ loop
فورًا
لأنه لا داعي لاستكمال البحث من بعد ما عثرنا على الرقم الذي نبحث عنه
الـ loops المتداخلة | Nested Loops
الـ loop
المتداخلة هي عبارة عن كتابة loop
داخل loop
آخر
أي أنك تقوم بعمل while
داخل while
أو for
داخل for
أو do-while
داخل do-while
وهذا يعني أن مع كل لفة في الـ loop
الخارجية سيتم تنفيذ كل اللفات في الـ loop
الداخلية
لنفترض أننا نريد طباعة جدول الضرب من 1
إلى 10
للأرقام 1
و 2
و 3
فقط
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 10; j++) {
cout << i << " × " << j << " = " << i * j << '\n';
}
}
هنا قمنا بعمل for
داخل for
الـ for
الخارجية سيتم تنفيذها 3
مرات لأننا قمنا بتحديد الشرط i <= 3
ولأنا نريد بناء جدول الضرب للأرقام 1
و 2
و 3
فقط كما قلنا فالـ for
الخارجية ستلف على هذه الأرقام وكل مرة المتغير i
سيأخذ قيمة جديدة
ومع كل رقم تمر عليه الـ for
الخارجية نحتاج لـ for
أخرى تهتم بعملية حساب جدول الضرب من 1
إلى 10
لهذا الرقم
وهذا ما قمنا به في الـ for
الداخلية التي تقوم بطباعة جدول الضرب من 1
إلى 10
للرقم الذي تم تحديده في الـ for
الخارجية
لنحلل الكود بالتفصيل
أولًا قيمة المتغير i
في الـ for
الخارجية سيبدأ من 1
ثم ستلف الـ for
الداخلية على الأرقام من 1
إلى 10
في المتغير j
قيمة i |
قيمة j |
التعويض بالقيم | نتيجة الطباعة |
---|---|---|---|
1 | 1 | cout << 1 << " × " << 1 << " = " << 1 * 1 | 1 × 1 = 1 |
1 | 2 | cout << 1 << " × " << 2 << " = " << 1 * 2 | 1 × 2 = 2 |
1 | 3 | cout << 1 << " × " << 3 << " = " << 1 * 3 | 1 × 3 = 3 |
1 | 4 | cout << 1 << " × " << 4 << " = " << 1 * 4 | 1 × 4 = 4 |
1 | 5 | cout << 1 << " × " << 5 << " = " << 1 * 5 | 1 × 5 = 5 |
1 | 6 | cout << 1 << " × " << 6 << " = " << 1 * 6 | 1 × 6 = 6 |
1 | 7 | cout << 1 << " × " << 7 << " = " << 1 * 7 | 1 × 7 = 7 |
1 | 8 | cout << 1 << " × " << 8 << " = " << 1 * 8 | 1 × 8 = 8 |
1 | 9 | cout << 1 << " × " << 9 << " = " << 1 * 9 | 1 × 9 = 9 |
1 | 10 | cout << 1 << " × " << 10 << " = " << 1 * 10 | 1 × 10 = 10 |
الآن الـ for
الداخلية قد انتهت من طباعة جدول الضرب من 1
إلى 10
للرقم 1
وستبدأ الآن الـ for
الخارجية في اللفة التالية وسيأخذ المتغير i
قيمة 2
وستبدأ الـ for
الداخلية مجددًا اللف من 1
إلى 10
في المتغير j
قيمة i |
قيمة j |
التعويض بالقيم | نتيجة الطباعة |
---|---|---|---|
2 | 1 | cout << 2 << " × " << 1 << " = " << 2 * 1 | 2 × 1 = 2 |
2 | 2 | cout << 2 << " × " << 2 << " = " << 2 * 2 | 2 × 2 = 4 |
2 | 3 | cout << 2 << " × " << 3 << " = " << 2 * 3 | 2 × 3 = 6 |
2 | 4 | cout << 2 << " × " << 4 << " = " << 2 * 4 | 2 × 4 = 8 |
2 | 5 | cout << 2 << " × " << 5 << " = " << 2 * 5 | 2 × 5 = 10 |
2 | 6 | cout << 2 << " × " << 6 << " = " << 2 * 6 | 2 × 6 = 12 |
2 | 7 | cout << 2 << " × " << 7 << " = " << 2 * 7 | 2 × 7 = 14 |
2 | 8 | cout << 2 << " × " << 8 << " = " << 2 * 8 | 2 × 8 = 16 |
2 | 9 | cout << 2 << " × " << 9 << " = " << 2 * 9 | 2 × 9 = 18 |
2 | 10 | cout << 2 << " × " << 10 << " = " << 2 * 10 | 2 × 10 = 20 |
الآن الـ for
الداخلية قد انتهت من طباعة جدول الضرب من 1
إلى 10
للرقم 2
وستبدأ الآن الـ for
الخارجية في اللفة التالية وسيأخذ المتغير i
قيمة 3
وستبدأ الـ for
الداخلية مجددًا اللف من 1
إلى 10
في المتغير j
قيمة i |
قيمة j |
التعويض بالقيم | نتيجة الطباعة |
---|---|---|---|
3 | 1 | cout << 3 << " × " << 1 << " = " << 3 * 1 | 3 × 1 = 3 |
3 | 2 | cout << 3 << " × " << 2 << " = " << 3 * 2 | 3 × 2 = 6 |
3 | 3 | cout << 3 << " × " << 3 << " = " << 3 * 3 | 3 × 3 = 9 |
3 | 4 | cout << 3 << " × " << 4 << " = " << 3 * 4 | 3 × 4 = 12 |
3 | 5 | cout << 3 << " × " << 5 << " = " << 3 * 5 | 3 × 5 = 15 |
3 | 6 | cout << 3 << " × " << 6 << " = " << 3 * 6 | 3 × 6 = 18 |
3 | 7 | cout << 3 << " × " << 7 << " = " << 3 * 7 | 3 × 7 = 21 |
3 | 8 | cout << 3 << " × " << 8 << " = " << 3 * 8 | 3 × 8 = 24 |
3 | 9 | cout << 3 << " × " << 9 << " = " << 3 * 9 | 3 × 9 = 27 |
3 | 10 | cout << 3 << " × " << 10 << " = " << 3 * 10 | 3 × 10 = 30 |
الآن الـ for
الداخلية قد انتهت من طباعة جدول الضرب من 1
إلى 10
للرقم 3
ثم عندما تحاول الـ for
زيادة قيمة المتغير i
إلى 4
ستجد أن الشرط لم يعد يتحقق وسيتوقف التنفيذ لأن الشرط كان i <= 3
لاحظ أن الـ for
الخارجية تمر على الأرقام 1
و 2
و 3
ومع كل رقم تمر عليه الـ for
الداخلية التي تمر على الأرقام من 1
إلى 10
فعندما كانت قيمة الـ i
الخاصة بالـ for
الخارجية تساوي 1
كانت قيمة الـ j
الخاصة بالـ for
الداخلية تتغير من 1
إلى 10
وكل مرة يتم طباعة جدول الضرب الخاصة بالرقم i
وهكذا سيتم طباعة جدول الضرب من 1
إلى 10
للأرقام 1
و 2
و 3
فقط
مثال آخر نريد طباعة الأرقام من 1
إلى 5
ولكن نريد طباعة الرقم 1
مرة واحدة والرقم 2
مرتين والرقم 3
ثلاث مرات وهكذا
هل يمكنك تخيل الكود كيف سيكون ؟
فكر قليلًا ثم انظر للشرح
نحن نريد طباعة الأرقام من 1
إلى 5
لذا بديهيًا سنقوم بعمل for
يبدأ من 1
وينتهي عند 5
ثم المسألة تقول لنا أن نطبع الرقم 1
مرة واحدة والرقم 2
مرتين والرقم 3
ثلاث مرات وهكذا
لذا مع كل لفة تقوم بها الـ for
الخارجية سنقوم بعمل for
أخرى داخلية تقوم بطباعة الرقم بعدد تكرار نفسه
فلو كان i
الخاص بالـ for
الخارجية يساوي 1
سنقوم بعمل for
داخلية تبدأ من 1
وتنتهي عند 1
وهذا يعني أن الرقم 1
سيتم طباعته مرة واحدة
فلو كان i
الخاص بالـ for
الخارجية يساوي 2
سنقوم بعمل for
داخلية تبدأ من 1
وتنتهي عند 2
وهذا يعني أن الرقم 2
سيتم طباعته مرتين
وهكذا سيتم طباعة الأرقام من 1
إلى 5
بالتكرار المطلوب
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
cout << i << '\n';
}
}
هنا قمنا بعمل for
داخل for
الـ for
الخارجية سيتم تنفيذها 5
مرات لأننا قمنا بتحديد الشرط i <= 5
ومع كل لفة تقوم بها الـ for
الخارجية سيتم تنفيذ الـ for
الداخلية بعدد تكرار نفسه لأن الشرط كما تلاحظ j <= i
وهذا معناه أن عندما تكون قيمة i
تساوي 1
ستكون قيمة j
في الـ for
الداخلية بـ 1
وتنتهي عندما تصل j
إلى 2
لأن شرط التكرار يقول j <= i
لنحلل الكود بالتفصيل
- عندما يكون
i = 1
في الـfor
الخارجية سيتم تنفيذ الـfor
الداخلية منj = 1
إلىj <= 1
وهذا يعني أن الرقم1
سيتم طباعته مرة واحدة
لأن في اللفة الثانية ستكون قيمةj
تساوي2
بالتالي الشرطj <= 1
لن يتحقق لأن2 <= 1
يعطيناfalse
بالتالي ستنتهي الـfor
الداخلية - ثم تستكمل الـ
for
الخارجية باللفة التاليةi = 2
وتبدأ الـfor
الداخلية منj = 1
إلىj <= 2
وهذا يعني أن الرقم2
سيتم طباعته مرتين
وليس ثلاث مرات لأن في اللفة الثالثة ستكون قيمةj
تساوي3
بالتالي الشرطj <= 2
لن يتحقق لأن3 <= 2
يعطيناfalse
بالتالي ستنتهي الـfor
الداخلية - ثم تستكمل الـ
for
الخارجية باللفة التاليةi = 3
وتبدأ الـfor
الداخلية منj = 1
إلىj <= 3
وهذا يعني أن الرقم3
سيتم طباعته ثلاث مرات - وهكذا ستستكمل الـ
for
الخارجية حتى تنتهي من الأرقام من1
إلى5
وستقوم الـfor
الداخلية بطباعة الأرقام بالتكرار المطلوب
الناتج النهائي سيكون كالتالي
1
2
2
3
3
3
4
4
4
4
5
5
5
5
5
بالطبع يمكنك عمل 3
أو أكثر من loop
داخل بعضها البعض وهذا بحسب المسألة التي لديك وما تريد تنفيذه
ولكن يجب أن تكون حذرًا لأنها تؤدي إلى تعقيد الكود وصعوبة فهمه
والكود الذي يحتوي على الـ loop
متداخلة مع بضها لا يكون أفضل كود وقد يكون هناك وسيلة لحل المسألة وفعل ما تريده بأسلوب مختلفة
مع الخبرة وتعلم الخوارزميات وهياكل البيانات ستتعلم كيف تقوم بعمل واختيار أفضل وسيلة لحل المسألة وتنفيذها بأفضل شكل ممكن
خاتمة
هذا كل شيء عن الـ loops
وأريدك أن تعرف أنها من أهم الأدوات في البرمجة وأن ما قمنا بشرحه وقوله عن الـ for
والـ while
والـ do-while
ستجده في كل لغات البرمجة الأخرى
كنت أود أن استكمل الشرح عن الـ for each
وما يشبها في لغات البرمجة لكن هذا سيكون في مقالة أخرى إن شاء الله
أما في المقالة التالية سنقوم بحل بعض المسائل البرمجية باستخدام الـ loops
لكي تتمكن من فهمها جيدًا
وسندمجها مع الأراي وكيف تستخدم الـ loop
للتعامل مع الأراي وحل المسائل والمشكلات البرمجية من خلالهما
أتمنى أن تكون قد استفدت من هذا الشرح وأن تكون قد فهمت كيفية استخدام الـ loops
هو درس قاسي قليلًا ولكنه مهم جدًا وأرجو أن تكون التالية كافية لترسيخ المعلومة في ذهنك عن طريق حل المسائل