اذهب إلى المحتوى

السؤال

نشر

  السلام عليكم

ياجماعة الخير أريد شرح فكرة برنامج بناء الهرم في لغة c (شرح الفكرة المنطقية)، لأنه واجب علي في دورة  cs50، حاولت وما وجدت الفكرة، دورت في الانترنت على الحل طلعت بسيطة، فقط المتغير الخاص ب loop الخارجية يكون زايد بقيمة واحدة عن المتغير في loop الداخلية، عشان يطبع هرم، لكن عندما أفكر فيها من الناحية المنطقية داخل عقلي لا أستوعبها ( لا أريد شرح كتابة الكود، أريد شرح الفكرة)، شكرا.

Annotation 2020-10-10 204152.png

Recommended Posts

  • 1
نشر
بتاريخ 5 ساعات قال Abderahman Benchalel:

@عبود سمير

الحمد لله فهمت الفكرة 

 أنت قلت لكي يكون الكود دقيق (الشرط في loop الداخلية يكون w أقل أو يساوي coun )، عشان إذا كان hgt = 3 نحصل على ثلاث أعمدة، ممتاز، طبقتها وكلام ما عليه غبار.

السؤال، بما أننا نريد w يساوي coun في مرحلة ما لكي يطبع 3 من #، كيف خلينا coun يساوي 3 أصلا بما أن hgt = 3، فالشرط في loop الخارجية أن يكون coun أقل من hgt وإلا نخرج من loop، وسامحنا تعبناك :)

العداد coun يبدأ من 0 إلى الإرتفاع بمعنى إذا كان hgt == 3 فسيكون تكرار الحلقه الخارجية 3 لأن العداد يبدأ من 0 و سيأخذ القيم 0، 1، 2 و هو ما يوافق عدد الصفوف أو الإرتفاع 3

العداد w يأخذ قيما متعلقة ب coun فعندما يكون coun == 0 سيتم الدخول إلى الحلقة الداخلية و تنفيذ محتواها و هذا إذا كان الشرط فيها أقل أو يساوي و بالتالي سيتم طباعة # مرة واحدة. أما عندما يكون coun == 2 فتكرار الحلقة الداخلية سيكون 3 و w سيأخذ القيم 0، 1، 2 و بالتالي سيتم طباعة ### 3 مرات و بهذا الشكل نكون قد حققنا الهرم المطلوب:

hgt == 3

coun == 0, 1, 2 : ثلاثة لفات تقابلها 3 صفوف في الهرم 

w في اللفة الأولى للحلقة الخارجية سيكون 0 و بالتالي طباعة # مرة واحدة ثم الإنتقال إلى سطر جديد

w في اللفة الثانية للحلقة الخارجية سيكون 0 ثم 1 و بالتالي طباعة ## مرتين ثم الإنتقال إلى سطر جديد

w في اللفة الثالثة للحلقة الخارجية سيكون 0 ثم 1 ثم 2 و بالتالي طباعة ### ثلاث مرات ثم الإنتقال إلى سطر جديد و في هذا الوقت سيكون coun == 2 و عند رفع قيمته ب 1 سيُحقق شرط الخروج من الحلقة الخارجية لأن hgt == 3 ثم إنهاء البرنامج و النتيجة ستكون 

#

##

###

بالتوفيق.

  • 1
نشر

سواء بلغة c أو أي لغة برمجية، التفكير المنطقي يكون هو العامل المشترك و الرئيسي في عمل أي ميثود أو تطبيق.

  • لنفترض أننا نريد بناء هرم من 5 أسطر :
    • بناء الهرم متوقف على أمرين مهمين و هما عدد النجوم في كل سطر و عدد المسافات التي تسبق كل سطر.
    • عدد النجوم في كل سطر يكون عبارة عن رقم السطر مضروب بـ 2 من ثم ننقص من الناتج 1
      ( على سبيل المثال السطر الأول سيكون فيه نجمة واحد ( (2*1) - 1 ) ، و السطر الخامس يجب أن يكون فيه 9 نجوم ( (5*2) - 1 ) ).
    • عدد المسافات التي تكون قبل النجوم في كل سطر تكون عبارة عن عدد أسطر الهرم ( و هو في مثالنا هذا 5 ) ناقص رقم السطر، ( على سبيل المثال سنجد أن في السطر الأول هناك نجمة واحدة ولكن تسبقها 4 فراغات ( 5 - 1 )، و في السطر الأخير سنجد أنه لا يوجد أي فراغ يسبق النجوم (5-5) و في السطر الثالث سنجد أن هناك فراغين يسبق النجوم (5-3).
    • بالتالي سنجد في كل مرة من المرات الـ 5 أنه تزيد النقاط و تنقص الفراغات، و هكذا يتكون الهرم.
    • و للإستفادة أكثر يمكنك الإطلاع على هذا الفيديو.
  • 1
نشر

وعليكم السلام , مرحبًا @Abderahman Benchalel.

يتكون الهرم بإستخدام اثنان من عملية التكرار For Loop.

و For الثانية هي موجودة داخل الآولى , ما الفكرة هنا ؟

اولاً البرنامج لديك لديه متغير hgt و هو يقوم بتحديد ارتفاع الهرم.

 

في حلقة التكرار الآولى نقوم بتكرار على حسب قيمة المتغير hgt, اذا قيمة hgt كانت 8 حلقة التكرار الآولى ستعمل 7 مرّات .

هذا يعني ان حلقة التكرار الثانية التي هي داخل الآولى ستعمل 7 مرّات ايضاً  , و الحلقة الثانية هي تقوم بمقارنة مع متغير coun في شرط العمل , و coun هو متغير الحلقة الآولى .

هذا يعني ان عندما يكون متغير حلقة التكرار الآولى (coun) لديه القيمة 2 , ستعمل حلقة التكرار الثانية مع التكرار 3 مرّات و هي تقوم بطباعة جسم الهرم هاشتاق ,

 

بعد ان تكتمل حلقة التكرار الثناية العمل , بعدها يوجد طباعة علامة "n\" و هنا نطبع سطر جديد قبل الرجوع مرّة آخرى لعمل حلقة تكرار الثانية بعد الإضافة على متغير coun في حلقة التكرار الآولى , حينها ستكون قيمة coun هي 3 , و حلقة التكرار الثانية ستقوم بتكرار 4 مرّات يعني طباعة 4 هاشتاق .

 

حلقة تكرار الثناية تُسمة nested loop لأنها موجدة داخل الحلقة الآولى , يمكنك معرفة المزيد عن ذلك من هنا .

  • 1
نشر

مرحباً @Abderahman Benchalel
فلتأخذ البرنامج خطوة بخطوة:

أولا:

int hgt;

هنا قمنا بتعريف متغير من النوع العددي(int) 
ثانياً:

do{
  hgt = get_int("height:\n");
} while(hgt < 1 || hgt > 8);

في هذا الجزء نقول للبرنامج كرر ما بداخل الحلقة ما دام الإرتفاع الذي يُدخله المُستخدم أصغر تماماً من 1 أو أكبر تماماً من 8 بمعنى إذا أدخل المستخدم عدداً صحيحا من المجال [1,8] سيمر إلى التعليمة التي بعد حلقة do .. while غير هذا سيبقى يسأل المُستخدم عن إدخال الإرتفاع.
ثالثاً:

for(int count = 0; count < hgt; count++) { // التعليمات التي بداخل هذه الحلقة ستتكرر حسب الإرتفاع
  for(int w = 0; w < count; w++) {
    printf("#");
  }
  printf("\n");
}

لفهم هذين الحلقتين فلنأخذ مثال و لنجعل hgt = 3 
الحلقة الأولى العداد count سيأخذ القيم التالية: 0, 1, 2 
من أجل كل قيمة من القيم الثلاثة سنقوم بعمل حلقة سيأخذ العداد w فيها قيماً متعلقة بقيمة العداد الأول بمعنى 

- عندما يكون count == 0 لن يتم تنفيذ الحلقة الثانية و سيتم تنفيذ فقط أمر الطباعة

printf("\n");

و هو يعني أترك السطر الحالي و إنتقل إلى سطر جديد
- عندما يكون count == 1 الحلقة الثانية ستتكرر مرة واحدة و السبب أن w سيأخذ قيما من هذا المجال [0, 1[ أي سيأخذ قيمة واحدة و هي 0 و بالتالي سيتم طباعة # مرة واحدة ثم يخرج من الحلقة الداخلية و بالتالي سيجد أمر الإنتقال إلى سطر جديد.
- عندما يكون count == 2 الحلقة الثانية ستتكرر مرتين و السبب أن w سيأخذ قيما من هذا المجال [0, 2[ أي 0 ثُم 1 و بالتالي سيتم طباعة ## 

و بالتالي سيكون الناتج:
 

#
##
 

حتى نحصل على الشكل الصحيح على الحلقة الثانية ان تكون بهذا الشكل: 

for(int w = 0; w <= count; w++) {
  printf("#");
}

حتى تفهم منطق الفكرة عليك أن تُفكر أنه لدينا جدول عدد صفوفه هو hgt و عدد أعمدته هو hgt و كل خانة مُحددة بإحداثيتن (count, w) بحيث count هو رقم الصف و w هو رقم العمود و نريد ملأ خاناته بهذا الرمز # نحتاج بشكل أساسي إلى حلقتين متداخلتين 
1- إذا كنا نريد ملأ كافة الخانات فسيكون تكرار الحلقة الداخلية نفس تكرار الحلقة الخارجية من أجل كل قيمة لعدادها أي أن count سيأخذ قيما من 0 إلى hgt و من أجل كل قيمة له سيأخذ w قيماً من 0 إلى hgt أيضاً.

2- إذا كنا نريد ملأ فقط الخانات التي تحت القطر أو الوتر: الخانات القُطرية هي التي تقع في (1, 1) , (2, 2) ... , (hgt, hgt) بمعنى أن الخانات القطرية يكون فيها الصف يُساوي العمود و في هذه الحالة سيكون تكرار الحلقة الداخلية متعلق بقيمة عداد الحلقة الأولى يعني أن عداد الحلقة الداخلية سيأخذ قيماً من 0 إلى قيمة عداد الحلقة الخارجية في تلك اللفة.
بالتوفيق .

  • 1
نشر
بتاريخ 7 ساعات قال Abderahman Benchalel:

@ياسين عناية، @عزام عبد الحافظ، @عبود سميربارك الله فيكم جميعا، 

سؤال أخير، في منطق البرمجة الحلقة التكرارية for loop، هل تقوم بتكرار الأمر بمقدار قيمة المتغير أم بمقدار الزيادة في قيمته، بمعنى، إذا كان المتغير x قيمته 3 هل يتكرر 3 مرات، أم أنه يتكرر بمقدار زيادة واحدة في قيمة المتغير، بحيث إذا أصبحت قيمة المتغير x تساوي 4 ف loop يتكرر مرة واحدة 1، شكرا جزيلا.

  • يتم تكرار الأمر في الـ for loop  بناءًا على :
  1.  نقطة الإنطلاق أو قيمة البداية و التي تكون متمثلة بـ i
  2. الشرط للتحق من عدد مرات تنفيذ الدالة
  3. قيمة الزيادة للـ i في كل مرة، بعد كل تنفيذ للعملية.

مثلًا نريد تكرار الأمر 5 مرات بإستخدام الـ for loop، نقوم بتعيين قيمة i  من الصفر و نضع الشرط بأنه في كل مرة و قبل تنفيذ عملية تكرار تأكد أنه هل وصلت عملية التكرار إلى 5، يتم ذلك من خلال وضعنا الشرط و الذي سيكون في هذه الحالة ( i < 5 )، بالإضافة لزيادة قيمة الـ i في كل مرة بـ 1.

  • الأمر سيتم كالتالي : 
    • سيتم تنفيذ الـloop أول مرة عند i = 0 و بعد تنفذ الـ loop  يتم زيادة قيمة الـ i بـ1، إذًا ستنتهي الـloop من تنفيذ العملية بعد أول مرة و ستصبح قيمة الـ i = 1.
    • بعد ذلك و عند تنفيذ الـloop للعملية للمرة التالية يتم فحص الشرط المرفق في الدالة و هو في مثالنا هذا ( هل قيمة i ما زالت أصغر من 5 ) إذا كانت الإجابة بنعم يتم تنفيذ الloop وبعدها تتم زيادة قيمة الـi  بـ 1
    • و هكذا إلى أن تصبح قيمة الـ i لا تحقق الشرط المرفق و ستتوقف الـ loop عن تنفيذ الأمر.
for (int i = 0; i < 5 ; i++)

{
// الأمر الذي ستم تكراره 5 مرات
}

 

  • 1
نشر
بتاريخ 7 ساعات قال Abderahman Benchalel:

@ياسين عناية، @عزام عبد الحافظ، @عبود سميربارك الله فيكم جميعا، 

سؤال أخير، في منطق البرمجة الحلقة التكرارية for loop، هل تقوم بتكرار الأمر بمقدار قيمة المتغير أم بمقدار الزيادة في قيمته، بمعنى، إذا كان المتغير x قيمته 3 هل يتكرر 3 مرات، أم أنه يتكرر بمقدار زيادة واحدة في قيمة المتغير، بحيث إذا أصبحت قيمة المتغير x تساوي 4 ف loop يتكرر مرة واحدة 1، شكرا جزيلا.

أولا عليك فهم طريقة كتابة الحلقة for: 

for ( init; condition; increment ) {
   // code here
}

init: يتم تنفيذه مرة واحدة في البداية ويتم فيه تهيئة المتغيرات

condition: هو شرط يتم التحقق منه في كل لفة إذا كان الشرط صحيح يتم تنفيذ ما بداخل الحلقة من تعليمات إذا كان خاطئ يتم الخروج من الحلقة.

increment: في هذا الجزء يُمكنك تغيير قيمة متغيرات التحكم في الحلقة و يتم تنفيذه كل مرة بعد تنفيذ التعليمات التي بداخل الحلقة و بعده يتم التحقق من الشرط ثانية.

لذلك فمقدار التكرار مُعتمد على هذه الأجزاء الثلاثة لكن وجودها ليس ضروري لكن وجود الفاصلة المنقوطة التي تفصل بين هذه الأجزاء ضروري فمثلاً يُمكن أن نجد شيء هكذا:

#include <stdio.h>

int main()
{
    int i = 2; // init
    
    for( ; ; ) {
        
        
        if(i >= 10) { // condition
            break;
        }
        
        printf("%d\n", i);
        
        i += 2; // increment
        
    }

    return 0;
}

و هذا المُخطط يُوضح طريقة عمل حلقة for:

for_loop.thumb.PNG.2b18ce211bb05f2677ae589b66def8a1.PNG

بالتوفيق.

  • 0
نشر

@ياسين عناية، @عزام عبد الحافظ، @عبود سميربارك الله فيكم جميعا، 

سؤال أخير، في منطق البرمجة الحلقة التكرارية for loop، هل تقوم بتكرار الأمر بمقدار قيمة المتغير أم بمقدار الزيادة في قيمته، بمعنى، إذا كان المتغير x قيمته 3 هل يتكرر 3 مرات، أم أنه يتكرر بمقدار زيادة واحدة في قيمة المتغير، بحيث إذا أصبحت قيمة المتغير x تساوي 4 ف loop يتكرر مرة واحدة 1، شكرا جزيلا.

  • 0
نشر

@عبود سمير

الحمد لله فهمت الفكرة 

 أنت قلت لكي يكون الكود دقيق (الشرط في loop الداخلية يكون w أقل أو يساوي coun )، عشان إذا كان hgt = 3 نحصل على ثلاث أعمدة، ممتاز، طبقتها وكلام ما عليه غبار.

السؤال، بما أننا نريد w يساوي coun في مرحلة ما لكي يطبع 3 من #، كيف خلينا coun يساوي 3 أصلا بما أن hgt = 3، فالشرط في loop الخارجية أن يكون coun أقل من hgt وإلا نخرج من loop، وسامحنا تعبناك :)

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...