مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
اقتباس:
المشاركة الأصلية كتبت بواسطة ThE* DaRk *SiDe
السلام عليكم ورحمة الله وبركاته
يوجد لدي لبس في أحد الامثلة في موضوع العودية:
في المثال الأول في الأمثلة التطبيقية لدرس الخامس ،أنا فهمت العودية لكن المشكلة في هذا المثال أنني حينما
أحوال أن أستنتج الحل بنفسي يكون الحل غير الحل الصحيح.
في هذا المثال لو فرضنا أننا أدخلنا 4قوة3 يكون الناتج كما في الصورة المرفقة
http://www.montada.com/attachment.ph...d=200409&stc=1
لكن النتج الصحيح هو 64.
هل من الممكن أخي أن تشرح لي كيف يستنتج البرنامج الحل الصحيح ؟
وشكرا.......
أخي الكريم ..
بالنسبة لهذا المثال .. كان التابع ( power ) مكتوباً على الشكل التالي :
كود:
int power(int x, int y)
{
if( y==0 ) return 1;
else return( x*power(x, y-1) );
}
و مع افتراض أننا نريد حساب 4 قوة 3 .. و بذلك سيكون استنتاج الحل كالتالي :
في الاستدعاء الأول ( حيث أن main قام باستدعاء هذا التابع ) :
قيمة x : ثابتة دائماً في جميع الاستدعاءات و تساوي 4 .
قيمة y : في هذا الاستدعاء تساوي 3 .
و بما أن ( y ) لا تساوي الصفر .. فسيتم تنفيذ التعليمة التالية :
كود:
return( x*power(x, y-1) );
لاحظ هنا كيف أننا سنعيد للتابع main ناتج ضرب : 4 × 4 قوة 2 .. و هي تساوي ( 4 قوة 3 ) .. و لكن قبل أن نعيد ذلك الناتج علينا حساب 4 قوة 2 لذلك سيتم استدعاء التابع ( power ) مرة أخرى من أجل تلك العملية .
القيمة المعادة للتابع main : غير معروفة إلى أن يتم معرفة قيمة 4 قوة 2 .. و عند الحصول على القيمة ( 4 قوة 2 ) من الاستدعاء الثاني نعيد للتابع main الناتج ( 4 × 4 قوة 2 ) و هو يساوي ( 4 قوة 3 ) .
في الاستدعاء الثاني :
قيمة x : قلنا أنها ثابتة دائماً في جميع الاستدعاءات و تساوي 4 .
قيمة y : في هذا الاستدعاء تساوي 2 .. لأن الاستدعاء الأول قام بإرسال ( y-1 ) .
و بما أن ( y ) لا تساوي الصفر .. فسيتم تنفيذ التعليمة التالية :
كود:
return( x*power(x, y-1) );
إذا هنا سيتم حساب ( 4 قوة 2 ) و إعطاء ذلك الناتج للاستدعاء الأول .. و لكننا سنحسب تلك العملية عن طريق ( 4 × 4 قوة 1 ) و هي تساوي ( 4 قوة 2 ) .. لذلك سيتم إرسال ( 4 قوة 1 ) للاستدعاء الثالث لكي يتم حسابها .
القيمة المعادة للاستدعاء الأول : غير معروفة أيضاً إلى أن يتم حساب ( 4 قوة 1 ) في الاستدعاء الثالث .. و عند الحصول على ذلك الناتج سيتم إرجاع ( 4 × 4 قوة 1 ) للاستدعاء الأول .
في الاستدعاء الثالث :
قيمة x : أيضاً تساوي 4 .
قيمة y : في هذا الاستدعاء تساوي 1 .. لأن الاستدعاء الثاني قام بإرسال ( y-1 ) .
و بما أن ( y ) لا تساوي الصفر .. فسيتم تنفيذ التعليمة التالية :
كود:
return( x*power(x, y-1) );
هنا ( في هذا الاستدعاء ) سيتم حساب ( 4 × 4 قوة 0 ) و هي تسوي ( 4 قوة 1 ) .. و سيتم إرسال هذا الناتج كقيمة معادة إلى الاستدعاء الثاني .. و لكن قبل ذلك علينا حساب ( 4 قوة 0 ) و هذا ما سوف ينفذه الاستدعاء الرابع .
القيمة المعادة للاستدعاء الثاني : غير معروفة أيضاً إلى أن يتم حساب ( 4 قوة 0 ) و عندها سيتم إرجاع القيمة ( 4 × 4 قوة 0 ) للاستدعاء الثاني .
في الاستدعاء الرابع :
قيمة x : أيضاً تساوي 4 .
قيمة y : هنا نكون قد وصلنا إلى الحالة النهائية و هيا الحالة المعروفة جوابها و هي عندما يكون الأس يساوي ( الصفر ) .. لذلك سيتم تنفيذ التعليمة التالية :
هنا ستكون القيمة المعادة للاستدعاء الثالث تساوي واحد و هي ناتج ( 4 قوة 0 ) .. و بذلك سيتم إرجاع القيم بالتسلسل بين الاستدعاءات حتى الرجوع إلى التابع main .. و ذلك كالتالي :
الاستدعاء الرابع سيعيد القيمة ( 1 ) للاستدعاء الثالث .. و الاستدعاء الثالث سيعيد القيمة ( 4 × 4 قوة 0 ) إلى الاستدعاء الثاني ( الناتج إلى الأن 4 ) .. و الاستدعاء الثاني سيعيد القيمة ( 4 × 4 قوة 1 ) إلى الاستدعاء الأول ( الناتج 16 ) .. و أخيراً الاستدعاء الأول سيعيد القيمة ( 4 × 4 قوة 2 ) إلى التابع الرئيسي main و سيكون الناتج ( 64 ) .
أتمنى أن تكون الفكرة قد وصلت .. بالتوفيق .
:: تنبيه ::
هناك أخطاء جوهري و منطقية في الدرس الثامن في فقرة ( التحرير الديناميكي ) .. لذلك لا تأخذوا بما هو مكتوب في تلك الفقرة .. و سيتم التصحيح قريباً إن شاء الله ( بمساعدة المراقب ) .. و الخطأ كان مني لعدم تأكدي من المعلومات التي كتبتها .. وسيتم توضيح أنه تم تصحيح تلك المعلومات داخل تلك الفقرة .
لذلك أرجو الانتباه إلى من يقوم بتصوير هذه الدروس و نشرها في الجامعات على هذا الخطأ لأني على علم بذلك .. و جزاهم الله خيراً على عملهم و حرصهم .. و الله الموفق .
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
أولا أشكرك أخوي لإجابتك على أسئلتي وأعتذر على إزعاجك :( ويبدو أنني طالب سيء . :D
في الحقيقه أنا فهمت لكن بقي لدي لبس بسيط وهو أنه:ستكون القيمة المعادة من الإستدعاء الثاني 16 وستكون القيمة المعادة من الأستدعاء ألاول64 وسيكون مجموعها 80. إلا أذ كانت قيمة كل إستدعاء مستقلة بذاتها.
أكرر أسفي عل الازعاج.
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
اقتباس:
المشاركة الأصلية كتبت بواسطة ThE* DaRk *SiDe
أولا أشكرك أخوي لإجابتك على أسئلتي وأعتذر على إزعاجك :( ويبدو أنني طالب سيء . :D
في الحقيقه أنا فهمت لكن بقي لدي لبس بسيط وهو أنه:ستكون القيمة المعادة من الإستدعاء الثاني 16 وستكون القيمة المعادة من الأستدعاء ألاول64 وسيكون مجموعها 80. إلا أذ كانت قيمة كل إستدعاء مستقلة بذاتها.
أكرر أسفي عل الازعاج.
لا إزعاج أبداً ;)
و المهم هو أن تفهم الحل .. بالنسبة للسؤال :
كما قلت أنت فكل استدعاء مستقل تماماً عن الاستدعاء الآخر و كأن لكل استدعاء قيمه الخاصة به .. فمثلاً الوسيط ( y ) يمثل متحولاً مختلفاً تماماً عن بقية الوسائط ( y ) في الاستدعاءات الأخرى ولكل وسيط قيمة مستقلة به تختلف أيضاً عن باقي الاستدعاءات ..
و بالنسبة للجواب الأخير ( 64 ) هذا هو الناتج الذي سيعيده الاستدعاء الأول للتابع main .. و هذا يعني أن القيمة التي سوف تتطبع على الشاشة هي ذلك الناتج .. و لكن لماذا جمعتهم أنت ؟ ليس لعملية الجمع دخل هنا في الحل .
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم
أخي Wolf Sniper
لقد قمت بتحقيق الشرط الأول و هو كتابة كل ما شاء المستخدم من النصوص (مصفوفة سجلات)
و لا أستطع تحقيق الشرط الثاني وهو كسر حلقة فور ..
هل يمكنك أن تعطيني الكود
و لم تجبني عن
اذا أدخل المستخدم كلمة سيئة مثل 6
ألا تطبع في نهاية البرنامج
و هذا ما قصدته بكلمة right
هل يمكن تحقيق هذا ؟
و شكرا لك على اضافة درس المؤشرات
رغم أني لم أفهم أهميتهم حتى الآن:02:
و السلام
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم
عمري 19 سنة
معهد كمبيوتر
عندي خلفية عن لغة الباسكال
و اتمنى ان اتابع معكم و يعطيك العافية :)
مشاركة: نحو برمجة حقيقية :: تعلم أساسيات ++C ::
1_محمد
2- 18
3- رابعة ثانوي
4-والله أحب أتعلم هاللغة كثقافة وحب في التعلم
5- إن شاء الله اكمل معاك.
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
اسمي :زيد
عمري : 16
اول ثانوي
انا متوسط بالفيجوال بيسك
بس علمت ان السي ++ اقوى وانا الآن اتعلمها
انشاء الله اتابع معاكم
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
اقتباس:
المشاركة الأصلية كتبت بواسطة Night_3
السلام عليكم
أخي Wolf Sniper
لقد قمت بتحقيق الشرط الأول و هو كتابة كل ما شاء المستخدم من النصوص (مصفوفة سجلات)
و لا أستطع تحقيق الشرط الثاني وهو كسر حلقة فور ..
هل يمكنك أن تعطيني الكود
و لم تجبني عن
اذا أدخل المستخدم كلمة سيئة مثل 6
ألا تطبع في نهاية البرنامج
و هذا ما قصدته بكلمة right
هل يمكن تحقيق هذا ؟
و شكرا لك على اضافة درس المؤشرات
رغم أني لم أفهم أهميتهم حتى الآن:02:
و السلام
بالنسبة للحل أخي Night_3 :
هذا هو الحل الذي كتبته و الموجود في الصورة في الرد الذي شرحت لك الإجابة فيه .. و لكنه كما قلت أنت أنه لم يعالج مشكلة عدم كتابة الرموز و الأشكال و الأرقام .. لذلك سأضع هذا الحل و سأشرحه ثم سأعطيك الحل الآخر و الذي يعالج تلك المشكلة :
كود:
#include <iostream.h>
#include <string.h>
void main()
{
char s[100];
cout << "Enter a Sentence :\n";
cin.getline(s, 100);
for(int i=0; i<strlen(s); i++)
{
if( s[i]==100 && s[i+1]==111 && s[i+2]==105 && s[i+3]==116 )
{
for(int j=0; j<i; j++)
cout << s[j];
cout << endl;
break;
}
}
}
شرح الحل :
1 – المكتبة ( string.h ) من أجل الدالة ( strlen ) و التي سنستخدمها لكي نحدد عدد المحارف المكتوبة و الموجودة في المصفوفة ( s ) .. و لقد شرحت هذه الدالة أكثر في درس المصفوفات لذلك أنصحك بالرجوع إليه .
2 – في التابع main : قمنا بتعريف المصفوفة ( s ) و هي تتسع لمائة محرف .. و هذه المصفوفة سيتم تخزين فيها الأحرف المدخلة من قبل المستخدم .. و من ثم استخدمنا cin.getline لكي نخزن جميع السطر المكتوب داخل المصفوفة ( s ) .. و أيضاً شرحت هذه الفقرة في درس المصفوفات .
3 – الأن نحن نريد اختبار وجود الكلمة ( doit ) داخل المصفوفة .. لذلك علينا اختبار جميع الأحرف الموجودة بداخل تلك المصفوفة .. و بالتالي سنحتاج إلى حلقة for للتنقل بين قيم المصفوفة ( s ) .. إذا عرفنا الأن فائدة الحلقة الأولى .. و لاحظ أيضاً كيف استخدمنا الدالة ( strlen ) لتحديد القيمة النهائية في هذه الحلقة .. حيث أننا نريد فقط القيم المدخلة و لا نريد حجم المصفوفة كله ( 100 ) .
4 – داخل الحلقة for : قلنا أننا سنختبر وجود الكلمة ( doit ) لذلك علينا وضع شرط ( if ) .. و لكن ماذا سيكون ذلك الشرط ؟ سنستخدم جدول الآسكي كما قلت لك من أجل التسهيل .. بحيث يمكن ذلك عن طريق معرفة الرمز المقابل في الآسكي لكل حرف من أحرف الكلمة ( doit ) .. و هي كالتالي :
الحرف ( d ) يقابله في الآسكي العدد 100 .
الحرف ( o ) يقابله في الآسكي العدد 111 .
الحرف ( i ) يقابله في الآسكي العدد 105 .
الحرف ( t ) يقابله في الآسكي العدد 116 .
ملاحظة / راجع مفهوم نظام الترميز ASCII و كيفية استخدامه لحل الكثير من المسائل في درس المصفوفات أيضاً .
الأن أصبح الشرط سهلاً مع ملاحظة استخدام الأدلة ( i ) و ( i+1 ) و ( i+2 ) و ( i+3 ) من أجل تحديد أماكن وجود تلك الأحرف في المصفوفة ( s ) .
5 – الأن إذا تحقق الشرط نكون قد وجدنا الكلمة ( doit ) .. لذلك كل معلينا الأن هو طباعة جميع الأحرف التي تسبق تلك الكلمة .. لذلك سنحتاج إلى حلقة for أخرى لكي تطبع لنا تلك الأحرف .. و سيكون دليل البداية لتلك الحلقة هو الصفر و النهاية سيكون الدليل ( i ) !!! لماذا ؟ لأننا من خلال الشرط السابق اكتشفنا أن الكلمة ( doit ) موجودة عند الدليل ( i ) .. و نحن نريد طباعة الأحرف إلى أن نجد تلك الكلمة .. و داخل الحلقة طبعاً سنطبع الأحرف المطلوبة ..
6 – ما زلنا الأن داخل الشرط ( أي أننا حددنا موقع الكلمة doit ) .. لذلك سنقوم بالنزول سطراً جديداً ثم سنخرج من الحلقة عن طريق ( break ) و ذلك لأننا لا نريد اختبار باقي القيم حيث أننا وجدنا الكلمة المطلوبة .
الأن بالنسبة لتطوير هذا الحل إلى حل أفضل يقوم بطباعة الأحرف الأبجدية فقط و التي تسبق الكلمة ( doit ) .. سنستخدم لذلك الدالة ( isalpha ) و أيضاً شرحت استخدامها في درس المصفوفات و هي تستخدم لاختبار فيما إذا كان الوسيط المرسل لها حرفاً أبجدياً أم لا .. و هذه الدالة تحتاج إلى المكتبة ( ctype.h ) .. شاهد الحل و من ثم سأشرحه ( فقط أضفنا شيئاً صغيراً على الحل السابق ) :
كود:
#include <iostream.h>
#include <ctype.h>
#include <string.h>
void main()
{
char s[100];
cout << "Enter a Sentence :\n";
cin.getline(s, 100);
for(int i=0; i<strlen(s); i++)
{
if( s[i]==100 && s[i+1]==111 && s[i+2]==105 && s[i+3]==116 )
{
for(int j=0; j<i; j++)
if( isalpha(s[j]) )
cout << s[j];
else
cout << " ";
cout << endl;
break;
}
}
}
شرح الحل :
1 – لاحظ أن مشكلتنا هي أثناء الطباعة حيث أننا نريد طباعة الأحرف الأبجدية فقط .. لذلك سنتجه فوراً إلى الكود الخاص بذلك و هو موجود في داخل الحلقة الثانية .
2 – هنا سنطور الكود إلى التالي : إذا كانت القيمة حرفاً أبجدياً فسنطبعه و إلا فسنطبع بدلاً منه الفراغ .. و بهذه الطريقة ستظهر الجملة خالية تماماً من أي رموز أو أرقام .
أرجو أن يكون الحل واضح و آمل أن يكون هو الذي تريد .. بالتوفيق
و أرحب بجميع المشتركين الجدد ..
القائمة :
1- son of Qatar .
2 - habash1986 .
3 - Son Of UAE .
4 - SONIC4ANIME .
5 - asf4ever .
6 - ^عبدالعزيز..ع^ .
7 - kokekemo .
8 - UAE Naruto .
9 - عنان 2005 .
10- ستو كايبا .
11 - Imaj .
12 - banan 86 .
13 - عبدالله..ع .
14 - the unforgiven .
15 - الرقمي .
16 - رنجوجيت .
17 - BoWalaaad .
18 - IWANTYOURHELP .
19 - yaser_xp .
20 - Night_3 .
21 - SomeABD .
22 - هاني الفقي .
23 - XxmanX .
24 - drbmsh .
25 - flent10 .
26 - ThE* DaRk *SiDe .
27 - TheMafia .
28 - samate .
29 - ماارياا .
30 - xdetective90 .
31 - IGI2000 .
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم
شكا لك يا أخ Wolf Sniper
لقد استفدت من حلك كثيرا
لكنك لم تفهم المقصود بسؤالي الثاني
سأبعث لك التوضيح على الخاص
اعذرني على ذلك
و السلام
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم ورحمة الله
صراحة مجهود جبار للأخ الفاضلWolf Sniper ,,
أريد اللحاق بركبكم,,صحيح أني جئت متأخر ,, لكني كنت متابعا لكم أولا بأول خاصة واني ادرس هذه المبادئ حاليا ,,ولاأخفيك اخي Wolf Sniper أني استفدت منك أكثر بكثيييييييير مما أتلقاه من أساتذتي
اتمنى تكملة دروس المؤشرات بأسرع وقت ممكن
***ملاحظة::ربما أكون تلميذا كسولا;) بعض الشيء لكثرة امتحاناتنا,,فأرجو تقدير ذلك ,,,,
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
الموضوع ده جامد اوي يا مان انا كان نفسي من زمان اتعلم لغة السي ++ .... جزاك الله كل خير
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
أشكر جميع الإخوان الذين قاموا بالرد :) و جميع ما أخبرتموني به قد أسعدني كثيراً و أن الدروس قد أفادتكم و هذا هو المطلوب ..
بالنسبة لبقية درس المؤشرات فيبدو أني لن أستطيع أن أكمله في الوقت الراهن و ذلك لانشغالي بالدراسة من أجل الامتحانات .. لذلك سنكمل الدروس بعدها فوراً .. و ذلك بعد حوالي شهرين من الأن .. و أعتذر من الجميع و لمن كان يريد الاسراع في تنزيل درس المؤشرات لأنه جائتني الكثير من الرسائل بطلب إنزال الدرس بأسرع وقت ممكن و لكن ليس لدي قدرة على ذلك ..
و الحمدلله لقد وصلنا في كتابة الدروس إلى حوالي 100 صفحة و ذلك في 4 أشهر .. و هذا متعب فعلاً .. فأرجو أن تراعوا أن كتابة أي صفحة جديد تستغرق وقت كبير مني و ذلك لمراجعتها و التأكد من عدم وجود أخطاء منطقية أو برمجية فيها .. لذلك فمن الصعب علي أن أكتب أي صفحة جديدة .. لأن ذلك سيؤثر على دراستي .. و شكراً
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم ان شاء الله تقبلوني معكم وانا راح اكون من المتابعين جدا لدروسكم والله يعينكم على الاسئله بس حبيت اعرف اذا قلبتوني معكم اخذ اي اصدر للغة سي علشان امشي مكم صح
ان شاء الله تقبلوني معكم
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
اقتباس:
المشاركة الأصلية كتبت بواسطة جوردا
السلام عليكم ان شاء الله تقبلوني معكم وانا راح اكون من المتابعين جدا لدروسكم والله يعينكم على الاسئله بس حبيت اعرف اذا قلبتوني معكم اخذ اي اصدر للغة سي علشان امشي مكم صح
ان شاء الله تقبلوني معكم
أهلاً بك أخي ..
يرجى قراءة أول رد لي في هذا الموضوع لمعرفة التفاصيل أكثر و لمعرفة كيفية التسجيل .. و بالنسبة للبرنامج فستجده في الصفحة الثالثة في الرد رقم 36 من هذا الموضوع أيضاً .
مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الردود و الأسئلة
السلام عليكم ورحمة الله وبركاتة
اشكرك من اعماق قلبي ....فعلاااا شروح ودروس رااائعه مبدع تستحق الشكر
اذا كان باب التسجيل مفتوح فانا سأكون معكم علما باني قد قرأت اكثر الدروس وطبقتها ..
الاسم / عبدالعزيز
العمر / 23
لغة اوراكل ولي فتره ادرس السي
طبعا ادرس الجامعة لغة انجليزي :D
بس تقدر تقول هاوي كمبيوتر واخص البرمجة