• 0
  • مالي خلق
  • أتهاوش
  • متضايق
  • مريض
  • مستانس
  • مستغرب
  • مشتط
  • أسولف
  • مغرم
  • معصب
  • منحرج
  • آكل
  • ابكي
  • ارقص
  • اصلي
  • استهبل
  • اضحك
  • اضحك  2
  • تعجبني
  • بضبطلك
  • رايق
  • زعلان
  • عبقري
  • نايم
  • طبيعي
  • كشخة
  • صفحة 3 من 5 الأولىالأولى 12345 الأخيرةالأخيرة
    النتائج 21 إلى 30 من 46

    الموضوع: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

    1. #21
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      ---------- ---------- ---------- الدرس الخامس ---------- ---------- ----------
      اليوم : الاثنين ... التاريخ : 21 / 2 / 2005

      :: مقدمة ::

      سنأخذ في هذا الدرس إن شاء الله موضوع العودية بالإضافة إلى بعض الأمثلة التطبيقية على التوابع .. و أيضاً سأتطرق إلى موضوع كيفية صناعة مكتبتنا الخاصة ذو الامتداد (h.) و وضع التوابع اللازمة بها .

      ملاحظة قبل قراءة موضوع العودية / هذا الموضوع يعد من أصعب مواضيع البرمجة .. لذلك إذا شعرت أنك لم تفهم شيئاً فهذا طبيعي .. فالكل أصابه نفس الشيء حين سماع هذا المصطلح حتى أنا .. لذلك حاول قراءة الموضوع أكثر من مرة و صدقني ستشعر أن هذا الموضوع سيصبح سهلاً عليك إن شاء الله إذا قرأت شرحي بتركيز ( أقول بتركيز ) .. فإذا فهمت هذا الموضوع اعلم أنك تقدمت كثيراً في البرمجة و أن استيعابك لأسلوب كتابة الأوامر قد تطور كثيراً .. بالتوفيق .

      سم بالله ثم اقرأ بتركيز و تمعن ..

      :: العودية ( الاستدعاء الذاتي ) Recursion ::

      و هي أن يقوم التابع باستدعاء نفسه .. و بالتالي سيستمر الاستدعاء إلى ما لا نهاية حتى يتم تحقيق شرط معين في الاستدعاء رقم n .. و عندها سيعود المترجم لتنفيذ التابع رقم n-1 و بعد ذلك إلى التابع رقم n-2 و هكذا إلى أن يصل المترجم للتابع الأول الذي قام باستدعاء نفسه .

      إن العودية تشابه فكرة حلقات التكرار .. و لكنها تختلف عنها بأمر سأذكره في شرح المثال .


      و كمثال على العودية سنستخدم تابع يقوم بإيجاد العاملي لعدد n .. بحيث سندخل هذا العدد إلى التابع و سنعيد الناتج كقيمة معادة :
      كود:
      int fact( int n )
      {
          if( n==0 ) return 1;
          else return ( n * fact( n-1 ) );
      }
      ملاحظة / اجعل هذا المثال كقاعدة لك مبدئياً عند استخدامك للعودية .

      شرح المثال :
      1 – يجب عليك أولاً معرفة الحالة النهائية التي سيقف عندها الاستدعاء المتكرر للتابع .. و في مثالنا حول العاملي سيتم الوقوف عند الوصول إلى ( صفر! ) و النتيجة ستكون هي الواحد ( لأن 0! تسوي واحد ) .. لذلك وضعنا شرط يقوم باختبار العملية السابقة .

      2 - و إذا لم تكن n تساوي الصفر .. فسيتم استدعاء التابع لنفسه .. بحيث سنضع قانون العاملي و الذي يمثل العدد نفسه ضرب العدد ناقص واحد في كل مرة حتى نصل إلى العدد واحد .. و لكن لماذا وضعنا القانون بهذا الشكل :
      كود:
      n * fact( n-1 )
      ملاحظة / يجب عليك معرفة أين ستقوم بعملية العودية ( استدعاء التابع لنفسه ) .. حيث هناك قانون آخر للعودية و هو كالتالي :

      5! = 5 × 4 × 3 × 2 × 1 = 120

      5! = 5 × 4! = 120
      5! = 5 × 4 × 3! = 120
      5! = 5 × 4 × 3 ×2! = 120
      5! = 5 × 4 × 3 × 2 × 1! = 120
      5! = 5 × 4 × 3 × 2 × 1 × 0! = 120

      و بالتالي نستنتج القانون التالي :
      كود:
      n! = n * (n-1)!

      و هذا ما يوضحه الحل الذي وضعناه .

      و انظر إلى آخر حالة كيف أننا وصلنا إلى ( 0! ) .. حيث أننا نعرف مسبقاً أن ( 0! ) تساوي الواحد الصحيح .. لذلك تكون عادة حالة التوقف عن العودية عند الوصول إلى قيمة معروف جوابها مسبقاً ( مثل 0! ) و التي تساوي الواحد .

      سنشرح الفكرة السابقة : بفرض أن المستخدم أدخل العدد 5 فستكون العملية كالتالي ( انظر الشكل ) :


      الاستدعاء الأول :

      في هذا المثال .. سيكون لدينا 6 استدعاءات .. عند الاستدعاء الأول ( الذي قام التابع main باستدعائه ) ستكون قيمة المتحول الشكلي الأول 5 لأن المستخدم أدخل العدد 5 و قد أرسلنا هذا العدد إلى التابع fact .. و بالتالي سيتم اختبار الشرط فيما إذا كان العدد يساوي الصفر ( لأن جواب 0! نعرفه مسبقاً ) .. و لكنه لا يساويه .. لذلك سيستدعي التابع نفسه مرة أخر لحساب ( 5 * 4! ) .. و بالتالي سيتم إرسال القيمة n-1 كمتحول شكلي إلى الاستدعاء الثاني و هذه القيمة تساوي 4 .. و كأننا نطلب من الاستدعاء الثاني أن يحسب لنا ( 4! ) .

      الاستدعاء الثاني :

      كما قلنا فإن قيمة المتحول الشكلي n في هذا الاستدعاء ستكون 4 .. و بالتالي لا تساوي الصفر .. لذلك سيستدعي التابع نفسه مرة أخرى و لكنه سيرسل القيمة n-1 كمتحول شكلي إلى الاستدعاء الثالث بحيث ستكون القيمة 3 .. لأننا قلنا سابقاً بأن : ( n! = n * ( n-1 .. حيث أننا نطلب من الاستدعاء الثالث أن يحسب لنا ( 3! ) .. و هكذا بقية الاستدعاءات .

      الاستدعاء الثالث :

      قيمة المتحول الشكلي
      كود:
       ( n ) = 3
      القيمة المرسلة إلى الاستدعاء الرابع
      كود:
       ( n-1 ) = 2

      الاستدعاء الرابع :

      قيمة المتحول الشكلي
      كود:
       ( n ) = 2
      القيمة المرسلة إلى الاستدعاء الرابع
      كود:
       ( n-1 ) = 1

      الاستدعاء الخامس :

      قيمة المتحول الشكلي
      كود:
       ( n ) = 1
      القيمة المرسلة إلى الاستدعاء الرابع
      كود:
       ( n-1 ) = 0

      الاستدعاء السادس :

      هنا ستكون قيمة ( n ) تساوي الصفر .. و بالتالي وصلنا إلى الحالة النهائية التي لا يوجد حل للعاملي بعدها .. لذلك سيعيد هذا التابع القيمة ( 1 ) لأن الشرط تحقق .. و لكنه لن يعيدها إلى الاستدعاء الأول بل إلى التابع الذي قام باستدعائه و هو الاستدعاء رقم 5 .. لذلك :
      القيمة المعادة للاستدعاء الخامس = 1 .

      في الاستدعاء الخامس :

      الأن في الاستدعاء الخامس نحن موجودين ضمن الشرط في else ( لأننا كما قلنا أن n لا تساوي الصفر ) .. و بالتالي الأن أصبحت قيمة :
      كود:
      n * fact( n-1 )
      معروفة و هي :

      n = 1 .
      fact( n-1 ) = 1 .. ( أوجدناها من الاستدعاء السادس الذي أعاد لنا تلك القيمة ) .

      و الناتج سيكون الواحد .. و بالتالي ( بسبب وجود return ) سيعيد الاستدعاء الخامس ناتج عملية الضرب إلى الاستدعاء ( التابع ) رقم 4 .
      القيمة المعادة للاستدعاء ( التابع ) رقم 4 = 1 .. ( لأن 1 × 1 = 1 ) .


      في الاستدعاء الرابع :

      تماماً كالاستدعاء رقم 5 .. سنكون بداخل else لأن n لا تساوي الصفر .

      n = 2 .
      fact( n-1 ) = 1 .. ( و هي القيمة المعادة من الاستدعاء الخامس ) .

      و الناتج سيكون ( 2 ) .. و بالتالي ( بسبب وجود return ) سيعيد الاستدعاء الرابع ناتج عملية الضرب إلى الاستدعاء ( التابع ) رقم 3 .
      القيمة المعادة للاستدعاء ( التابع ) رقم 3 = 2 .. ( لأن 2 × 1 = 2 ) .

      في الاستدعاء الثالث :

      تماماً كالبقية .. سنكون بداخل else لأن n لا تساوي الصفر .

      n = 3 .
      fact( n-1 ) = 2 .. ( و هي القيمة المعادة من الاستدعاء الرابع ) .

      و الناتج سيكون ( 6 ) .. و بالتالي ( بسبب وجود return ) سيعيد الاستدعاء الثالث ناتج عملية الضرب إلى الاستدعاء ( التابع ) رقم 2 .
      القيمة المعادة للاستدعاء ( التابع ) رقم 2 = 6 .. ( لأن 3 × 2 = 6 ) .


      في الاستدعاء الثاني :

      تماماً كالبقية .. سنكون بداخل else لأن n لا تساوي الصفر .

      n = 4 .
      fact( n-1 ) = 6 .. ( و هي القيمة المعادة من الاستدعاء الثالث ) .

      و الناتج سيكون ( 24 ) .. و بالتالي ( بسبب وجود return ) سيعيد الاستدعاء الثاني ناتج عملية الضرب إلى الاستدعاء ( التابع ) رقم 1 .
      القيمة المعادة للاستدعاء ( التابع ) رقم 1 = 24 .. ( لأن 4 × 6 = 24 ) .

      في الاستدعاء الأول:

      سنكون أيضاً بداخل else لأن n لا تساوي الصفر .

      n = 5 .
      fact( n-1 ) = 24 .. ( و هي القيمة المعادة من الاستدعاء الثاني ) .

      و الناتج سيكون ( 120 ) لأن ( 24 × 5 = 120 ) .. و هكذا نكون قد وصلنا إلى الجواب الذي نريده .. و بالتالي سيعيد هذا التابع تلك القيمة إلى التابع main الذي قام باستدعائه لكي يقوم بكتابة الناتج على الشاشة أو لإجراء أية عمليات أخرى على الناتج .


      خلاصة الحل :

      1 – لاحظ كيف بدأنا بالاستدعاء الأول و انتهينا أيضاً به .
      2 – عند القيام باستدعاء التابع لنفسه .. سيقف المترجم عند السطر الذي قمنا به بالعودية ( استدعاء التابع لنفسه ) .. و سيعود المترجم إلى نفس المكان حين إيجاد القيمة المعادة ( أو عند الانتهاء من التابع الذي قمنا باستدعائه ) و سيكمل ما تبقى من تعليمات موجودة في المكان الذي توقف به ( سنأخذ مثال على ذلك في هذا الدرس ) .

      مساوئ العودية :

      - إن الاستدعاء المتكرر للتوابع سيكون تنفيذه أبطأ من استخدام حلقات التكرار ( for و while ... إلخ ) .. و لكن هناك مسائل لا تحل إلا عن طريق العودية .. مثل عملية البحث في الملفات و التي ينفذها windows و طريقة عملها تشابه تماماً طريقة عمل العودية.. لذلك عليك معرفة متى تستخدم العودية و متى تستخدم حلقات التكرار ( على حسب المسألة ) .
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    2. #22
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      :: أمثلة تطبيقية ::

      سنأخذ عدة أمثلة على التوابع و لكننا سنبدأ بمثالين على العودية لتأكيد فكرة كيفية وقوف المترجم عند النقطة التي قام بالاستدعاء عندها و من ثم يكمل عمله مع باقي تعليمات الاستدعاء ( التابع ) نفسه عند إرجاع قيمة أو عند الانتهاء من التابع المستدعى .. و لكن سيكون التطبيق الأول كالمثال السابق حول العاملي .. و الثاني سيوضح تلك الفكرة .

      المثال 1 /
      نريد من المستخدم إدخال عددين بحيث يكون الأول هو الأساس و الثاني يكون هو الأس بحيث نوجد ناتج عملية الرفع إلى أس عن طريق العودية .. انظر الصورة :


      الحل /
      كود:
      #include <iostream.h>
      
      int power( int, int );
      
      void main()
      {
          int a,b;
      
          cout << "Enter X : "; cin >> a;
          cout << "Enter Y : "; cin >> b;
      
          cout << "X Power Y = " << power( a, b ) << endl << endl;
      }
      
      int power( int x, int y)
      {
          if( y==0 ) return 1;
          else return ( x * power( x, y-1 ) );
      }
      شرح الحل :

      1 – استخدمنا الطريقة الثانية في كتابة التوابع ( راجع الدرس السابق ) بحيث وضعنا رأس التابع في الأعلى لكي يتعرف عليه المترجم إذا ما استخدمناه في التابع main .. ثم كتبنا جسم ذلك التابع أسفل التابع main .

      2 – عرفنا متغيرين في التابع main : a من أجل الأساس .. و b من أجل الأس .. و بعد ذلك طلبنا من المستخدم إدخال تلك القيم .. و بعد ذلك استدعينا التابع power لحساب الناتج عن طريق إرسال a و b كمتحولات وسيطة .

      3 – في التابع power .. سنستخدم نفس أسلوب المثال السابق .. و لكن هناك اختلافات بسيطة :

      أولاً / ما هي القيمة النهائية ( القيمة المعروف ناتجها ) التي سيتوقف عندها الاستدعاء المتكرر للتابع ؟ الجواب هو عندما يكون الأس يساوي الصفر ! لماذا ؟ لأن أي عدد إذا كان أسه يساوي الصفر فالناتج هو الواحد .
      ثانياً / كيف سنستدعي التابع مرة أخرى عن طريق العودية ؟ ما هو القانون ؟ الجواب هو :
      لاحظ دائماً ما هي القيم التي تتغير في القانون .. انظر إلى الأمثلة التالية ( اقرأ من اليمين إلى اليسار ) :


      .. القوة تعني الأس ..
      4 قوة 4 = 256 .
      4 قوة 4 = 4 × 4 قوة 3 .
      4 قوة 4 = 4 قوة 2 × 4 قوة 2 .
      4 قوة 4 = 4 قوة 3 × 4 .

      4 قوة 4 = 4 قوة 4 × 4 قوة صفر .. و هكذا باقي الأرقام .

      لذلك يمكن أن نستنتج القانون التالي :
      كود:
      x Power y = x * x Power ( y-1)
      و هذا ما وضعناه في حل المثال .. و باقي الشرح يشابه تماماً شرح المثال السابق حول العاملي .. و بالتالي يجب عليك معرفة أين تضع مكان الاستدعاء التابع لنفسه و لاحظ كيف وضعناه نحن في الأمثلة السابقة .

      ----------------------------------------

      المثال 2 /
      نريد الأن أن نطلب من المستخدم إدخال جملة حرفية و من ثم نكتبها معكوسة .. بحيث تنتهي الجملة بإدخال النقطة .. انظر الصورة :


      الحل /
      كود:
      #include <iostream.h>
      
      void read()
      {
          char x;
      
          cin >> x;
      
          if( x != '.' )
          {
              read();
              cout << x;
          }
      }
      
      void main()
      {
          cout << "Enter a Sentence : ";
      
          read();
      
          cout << endl << endl;
      }
      شرح الحل :

      1 – أظن أن التابع main مفهوم .

      2 – في التابع read .. سيمثل كل استدعاء ( تابع ) حرف من الجملة .. و بالتالي سنطلب في كل مرة من المستخدم إدخال حرف جديد طالما أن الحرف السابق ليس النقطة .. و سيكون كل حرف مخزن في المتغير x الخاص بتابع معين .. فكلما أدخل المستخدم حرف جديد لا يساوي النقطة قمنا باستدعاء تابع آخر ليخزن الحرف الجديد في المتحول x الخاص به .

      3 – عند إدخال النقطة في نهاية الجملة .. سيكون آخر تابع يحمل قيمة النقطة و بذلك ينتهي هذا التابع دون كتابة تلك النقطة .. و بالتالي سيكون التابع قبل الأخير يحمل قيمة آخر حرف .. إذا سيتم كتابة هذا الحرف أولاً على السطر و بذلك ينتهي هذا التابع ..
      و تستمر التوابع بعد ذلك بكتابة كل منها قيمة المتغير x ( الحرف ) الذي يحمله .. و بالتالي ستكتب الجملة معكوسة لأن كتابة المتغيرات x الخاصة بالتوابع ستكتب من آخر تابع إلى الأول و نحن نعرف أن الأحرف وضعت بشكل متتالي في التوابع نتيجة إدخال المستخدم في كل مرة حرف واحد .


      و سبب ذلك أن المترجم يقف عند سطر استدعاء التابع و ينتقل إلى ذلك التابع .. و عند الانتهاء من هذا التابع يعود المترجم إلى السطر الذي يلي سطر الاستدعاء الخاص بالتابع .. و هكذا باقي التوابع .. انظر الصورة :


      هذه الصورة تمثل التوابع الثلاثة الأولى لكلمة Montada و بقية التوابع كهذه .. لاحظ كيف تم تسلسل إدخال الأحرف .. و أيضاً في النهاية كيف سيتم كتابة قيمة الحرف x في التابع رقم 3 و بذلك ينتهي عمله ثم سيتم سينتقل المترجم إلى التابع رقم 2 و لكن ليس إلى أوله بل إلى السطر الذي استدعينا فيه التابع رقم 3 .. و عندها سيتم كتابة قيمة x .. و عندها ينتهي عمل التابع رقم 2 .. و بالتالي سيعود المترجم إلى التابع رقم 1 .. و يكتب قيمة x و الذي تمثل أول حرف تم إدخاله و بالتالي سيكتب هذا الأحرف في النهاية .. و هذا يعني أن الجملة ستكتب معكوسة .

      ----------------------------------------

      المثال 3 /
      نريد من المستخدم إدخال عددين صحيحين و من ثم نعطي العدد الأكبر كقيمة عائدة عن طريق التابع bigger .. و إذا كان العددين متساويين فنعيد القيمة صفر .


      الحل /
      كود:
      #include <iostream.h>
      
      int bigger( int, int );
      
      void main()
      {
          int a, b;
      
          cout << "Enter Number 1 : "; cin >> a;
          cout << "Enter Number 2 : "; cin >> b;
      
          cout << "Max = " << bigger( a, b ) << endl;
      }
      
      int bigger( int a, int b )
      {
          if( a>b )
              return a;
          else if ( b>a )
              return b;
          else
              return 0;
      }
      شرح المثال :

      1 – استخدمنا الطريقة الثانية في تعريف التوابع كالمثال الأول .. بحيث عرفنا رأس التابع في بداية الصفحة لكي يتعرف عليه المترجم لأننا نريد استخدامه في التابع main و أيضاً لأننا سنضع هذا التابع ( bigger ) أسفل التابع main .

      2 – في التابع main .. طلبنا من المستخدم إدخال العددين .. و من ثم استدعينا التابع bigger لكي يحسب العدد الأكبر عن طريق إرسال العددين كمتحولات وسيطة .. و من ثم سيعيد لنا العدد الأكبر .. حيث أن العددين بالنسبة للتابع bigger يعتبران المدخلات و العدد الأكبر يعتبر مخرجاته .

      3 – في التابع bigger .. سنحل السؤال كما حللناه في الدروس السابقة .. فإذا كان العدد a أكبر من b فأرجع a كقيمة معادة .. أما إذا كان b أكبر من a فأرجع b .. أما إذا كان العددين متساويين فأرجع الصفر .

      ----------------------------------------
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    3. #23
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      المثال 4 /
      نريد من المستخدم إدخال عدد و من ثم نحسب له العاملي لهذا العدد عن طريق التابع fact .. و لكن ليس عن طريق العودية كما حللناه في بداية هذا الدرس بل عن طريق حلقة التكرار for ( نفس الحل الموجود في الدرس الثالث و لكن سنستخدم التوابع للحل ) .


      الحل /
      كود:
      #include <iostream.h>
      
      int fact( int );
      
      void main()
      {
          int a;
      
          cout << "Enter a Number : "; cin >> a;
      
          cout << fact( a ) << endl;
      }
      
      int fact( int x )
      {
          int f=1;
      
          for( int i=1; i<=x; i++ )
              f *= i;
      
          return f;
      }
      شرح المثال :

      1 – أظن أن التابع main مفهوم .

      2 – التابع fact مشروح فكرته في الدرس الثالث .. و لكننا هنا بدلاً من جعل I تتغير قيمتها تنازلياً .. جعلناها هنا تتغير تصاعدياً من الواحد و حتى العدد نفسه الذي أدخله المستخدم و الجواب هو نفسه .. و بعد ذلك سنعيد الناتج كقيمة عائدة إلى التابع main .

      ----------------------------------------

      المثال 5 /
      نريد من المستخدم أن يدخل عدد صحيح و من ثم نكتب له فيما إذا كان هذا العدد من الأعداد الأولية أما لا .. و ذلك عن طريق التابع prime .


      الحل /
      كود:
      #include <iostream.h>
      
      bool prime( int );
      
      void main()
      {
          int a;
      
          cout << "Enter a Number : "; cin >> a;
      
          if( prime(a) ) cout << "Prime" << endl;
          else cout << "not Prime" << endl;
      }
      
      bool prime( int x )
      {
          if( x==2 || x==3 ) return false;
      
          for( int i=2; i<=x-1; i++ )
              if( x%i == 0 ) return false;
      
          return true;
      }
      شرح الحل :

      1 – في التابع main .. قمنا بتعريف العدد الذي سيدخله المستخدم .. بحيث طلبنا منه ذلك .

      2 – بعد ذلك قمنا باختبار فيما إذا كان هذا العدد أولي أم لا عن طريق استدعاء التابع prime مع إرسال العدد كمتحول وسيط لكي يختبر فيما إذا كان ذلك العدد كذلك .. فإذا كان أولي سنكتب جملة Prime أما إن لم يكن أولي فسنكتب له not Prime .. وحيث أننا نعرف بأن القيمة المعادة هي من النوع bool لذلك نستطيع وضع التابع داخل الشرط if .. بحيث سيقوم الإختبار أولاً باستدعاء التابع ثم سيختبر القيمة المعادة هل هي true أم false .. و لاحظ أيضاً كيف أننا لم نضع التالي :
      كود:
      if( prime(a)==true )
      بل اكتفينا باستدعاء التابع .. لأن العبارتين متشابهتين ( اقرأ الملاحظة التالية ) .

      ملاحظة مهمة / من أجل طريقة استخدام التوابع التي تعيد قيمة من النوع bool أو من أجل المتغيرات من ذلك النوع أيضاً و كيفية استخدامها مع الشرط if .. راجع أول الدرس الثالث .. و طريقة استخدام تلك التوابع هي بنفس طريقة استخدام المتغيرات في الشرط .. و لكن في التوابع من ذلك النوع عند استخدامها مع الشرط سيتم استدعاء التابع أولاً ثم سيتم اختبار القيمة المعادة منه .

      3 – في التابع prime .. بنفس الحل الموجود في الدرس الثالث و لكننا سنطوره قليلاً .. حيث أن العددان 2 و 3 ليسا من الأعداد الأولية ( هكذا أتذكر ) .. و طريقة الحل هنا ستعتبر أن تلك الأعداد هي من الأعداد الأولية و هذا ما لا نريده .. لذلك وضعنا الشرط الأول لإختبار قيم x فوراً .. فإذا كانت تساوي إحدى العددين فسيتم إرجاع القيمة false للدلالة على أنهما ليسا من الأعداد الأولية .

      و من ثم في الاختبار الثاني حسبنا عدد القواسم للعدد المدخل .. و لكننا لن نحسب كم هي بالضبط ! فإذا وجدنا واحد فقط فهذا يعني أنه ليس من الأعداد الأولية ( طبعاً لم نضع في الحلقة العدد 1 و العدد نفسه x لأن العدد الأولي دائماً يقبل القسمة على الواحد و على نفسه فليس هناك فائدة من إدخالهم في عملية الحساب ) .. فإذا وجدنا قاسماً واحداً فسنعيد القيمة false أما إذا لم نجد أي قاسم للعدد فهذا يعني أنه أولي و بالتالي سنعيد القيمة true التي تدل على أنه أولي .

      ملاحظة مهمة / الأمر return ينهي عمل التابع .. و بالتالي عند استخدامه سيتم الخروج من التابع فوراً و عن طريقه سيتم إرجاع قيمة ما ( راجع الدرس السابق ) .

      ----------------------------------------
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    4. #24
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      :: كيفية صناعة المكتبات الخاصة بنا ذو الامتداد (h.) ::

      تحدثنا سابقاً حول الملفات التي نستطيع كتابة الأوامر فيها .. و لقد كتبنا جميع برامجنا و أمثلتنا على ملفات مصدرية Source File ذو الامتداد (cpp.) .. و لقد تحدثنا عن المكتبات ذو الامتداد (h.) و أنا تحتوي على مجموعة من الأوامر و التوابع و أشياء أخرى معرفة مسبقاً من قبل المستخدم .

      لذلك افرض مثلاً أنك تريد صناعة مجموع من التوابع الجاهزة بحيث لا تعيد كتابتها ثانية في برامجك الأخرى و بالتالي ستوفر على نفسك عناء تلك الكتابة .

      لذلك نستنتج أن هذه المكتبات مفيدة لكي يستخدمها المبرمج في برامج أخرى يقوم بكتابتها هو أو غيره و ستصبح هذه المكتبات كالمكتبات الجاهزة الأخرى مثل : math.h و ctype.h و مكتبات أخرى كثيرة .. و هناك أشخاص يقومون ببيع تلك المكتبات بأسعار خيالية و لكنها ليست على شكل ملفات رأسية (h.) كما سنتعلم الأن !!! حيث أنها عبارة عن مكتبات ربط ديناميكية و هو ما يسمى بملفات dll .. و لكن لا تخف فإن هذه المكتبات ما هي بالنهاية إلا ملفات رأسية (h.) و لذلك يجب أن نعرف الأن مبدئياً كيف يمكن أن نصنع مكتبة جزئية خاصة بنا من ذلك النوع من الملفات .

      ملاحظة / راجع الدرس الأول لمزيد من المعلومات حول الملفات الرأسية (h.) .

      أولاً / على ماذا تحتوي الملفات الرأسية (h.) ؟

      قد تحتوي هذه الملفات على الأنواع التالية :

      1 – توابع .
      2 – كائنات .
      3 – مؤشرات .
      4 – سجلات من النوع struct .
      5 – متغيرات .
      إلخ ...

      يعني أنك ممكن أن تضع بها كل مايعجبك من الأوامر التي تعلمناها و التي سنتعلمها إن شاء الله فيما بعد .. و لكننا مبدئياً سنضع بها مجموعة من التوابع فقط و التي كتبناها في درس اليوم لكي نستخدمها مرة أخرى إذا احتجنا لذلك .

      ثانياً / كيف نصنع ( ننشئ ) تلك الملفات ؟

      تستطيع ذلك بنفس طريقة إضافة ملف مصدري (cpp.) .. إضغط على : File >> New و من ثم ضمن القائمة File اختر Header File .. و اضغط على Ok .. و بهذا تكون قد أنشأت ملف رأسي .

      ثالثاًُ / ما هي طرق كتابة تلك الأنواع من الملفات ؟

      في الحقيقة هناك طريقتين :

      الأولى : نضع كل الأوامر مهما كانت ( كائنات .. توابع .. سجلات .. إلخ ) في هذه الملفات مع جميع أجزائها .. و بالتالي ستكون مكتبتنا الخاصة مكونة من ملف رأسي فقط .

      الثانية : هي أن نضع رؤوس الأوامر فقط داخل الملف الرأسي ( كما استخدمنا الطريقة الثانية لكتابة التوابع ) و أجسام تلك الأوامر في ملف مصدري (cpp.) .. و هذه الطريقة هي الأفضل و هي الأكثر استخداماً و لكننا لن نتطرق إليها إلا عند الوصول إلى الكائنات .. لأننا سنضطر لذكرها .. لذلك اتركوا هذه الطريقة الأن و لنرجع إلى الطريقة الأولى .

      رابعاً / الأن سنقوم بكتابة مكتبتنا الأولى .. لذلك قم بإنشاء ملف رأسي و سميه باسم Library1 .. و هذا الاسم سيكون اسم تلك المكتبة و التي ستحتوي على التوابع التالية :

      1 – تابع إيجاد قيمة العاملي لعدد ما ( بطريقة التكرار و ليس العودية ) .
      2 – تابع إيجاد القوة لعدد ما ( الأس و الأساس ) .
      3 – تابع إيجاد الجملة المعكوسة للجملة التي أدخلها المستخدم .
      4 – تابع إيجاد أي العددين أكبر .
      5 – تابع معرفة فيما إذا كان العدد أولي أم لا .

      و كل تلك التوابع قمنا بكتابتها في هذا الدرس .. و سنضيف على هذه المكتبة توابع أخرى إن شاء الله في الدروس القادمة .

      خامساً / كتابة المكتبة ( Library1 ) :

      المكتبة ( Library1 )

      كود:
      int fact( int x )
      {
          int f=1;
      
          for( int i=1; i<=x; i++ )
              f *= i;
      
          return f;
      }
      
      int power( int x, int y)
      {
          if( y==0 ) return 1;
          else return ( x * power( x, y-1 ) );
      }
      
      void read()
      {
          char x;
      
          cin >> x;
      
          if( x != '.' )
          {
              read();
              cout << x;
          }
      }
      
      int bigger( int a, int b )
      {
          if( a>b )
              return a;
          else if ( b>a )
              return b;
          else
              return 0;
      }
      
      bool prime( int x )
      {
          if( x==2 || x==3 ) return false;
      
          for( int i=2; i<=x-1; i++ )
              if( x%i == 0 ) return false;
      
          return true;
      }
      قمنا بوضع التوابع كما هي في الملف الرأسي Library1 .. و الحلول موجودة في هذا الدرس .

      سادساً / كيف يمكن أن نضيف المكتبة ( Library1 ) إلى برنامجنا بعد أن كتبناها ؟

      يمكننا ذلك عن طريق الأمر :
      كود:
      #include "Library.h"
      هل عرفت فائدة الأمر ( include ) ؟ تستطيع بهذا الأمر ضم المكتبات التي تريدها إلى مشروعك .. و لكن لماذا وضعنا اسم المكتبة داخل علامتي التنصيص ( " " ) ؟ قلنا سابقاً في الدرس الأول أننا نستخدم علامتي التنصيص في هذا المكان لكي نخبر المترجم بأن المكتبة موجودة ضمن الملف ( المجلد ) الذي يوجد فيه تطبيقك ذو الامتداد exe .

      أما إذا استخدمنا العلامتين ( < > ) فإننا نخبر المترجم بأن المكتبة موجودة في المكان المخصص ضمن المكتبات القياسية للغة .. و لكن إذا استخدمنا علامتي التنصيص ( " " ) و لم يجد المترجم المكتبة في ذلك المجلد فسيبحث عنها بشكل تلقائي ضمن المكتبات القياسية للغة .. و إذا لم يجدها هناك سيعطيق خطأ بعدم وجود تلك المكتبة .

      هل عرفت أيضاً ما فائدة الـ Linker ؟ يقوم Linker بربط برنامجك بالمكتبات و الملفات المطلوبة و التي قمت بإضافتها إلى مشروعك ( راجع الدرس الأول ) .

      سابعاً / الاستخدام الفعلي للمكتبة ( Library1 ) :

      سنأخذ الأن مثالاً عن كيفية استخدام هذه المكتبة .. سنجرب استخدام التابع bigger و الذي يقوم بإرجاع قيمة أي العددين أكبر و الذين أرسلناهما إليه عن طريق المتحولات الوسيطة .
      كود:
      #include <iostream.h>
      #include "Library1.h"
      
      void main()
      {
          int a, b;
      
          cout << "Enter Number 1 : "; cin >> a;
          cout << "Enter Number 2 : "; cin >> b;
      
          cout << "Max = " << bigger( a, b ) << endl;
      }
      لاحظ كيف أننا بهذا الشكل إختصرنا على أنفسنا عناء كتابة التابع bigger داخل هذا الملف المصدري .. و حيث أننا أيضاً نستطيع استخدام باقي التوابع المكتوبة في المكتبة ( Library1 ) و كأن تلك التوابع مكتوبة بداخل الملف الأساسي المصدري في هذا المثال .. و كل ذلك نتيجة إضافة تلك المكتبة عن طريق الأمر include و الذي جعل المترجم يقوم بتعريف تلك التوابع و كأنها في برنامجك .

      إذاً تستطيع الأن استخدام هذه المكتبة في أي برنامج تريد كتابته دون الحاجة إلى كتابة تلك التوابع مرة أخرى في ذلك البرنامج .

      ---------- ---------- ---------- نهاية الدرس الخامس ---------- ---------- ----------

      في النهاية .. أتمنى أن يكون هذا الدرس بداية طريقكم لفهم هذه اللغة و بداية لاحترافكم لها .. لأن هذه المواضيع مهمة و إذا لم تفهموها فلا أعتقد أنكم ستفهمون المواضيع القادمة .. لذلك أرجو من الجميع التركيز على كل ما سبق لكي تكون الدروس القادمة مفهومة لكم إن شاء الله .. بالتوفيق .
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    5. #25
      التسجيل
      01-02-2005
      المشاركات
      0
      المواضيع
      0
      شكر / اعجاب مشاركة

      Angry مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      السلام عليكم انا اعشق لغة c++ولكن مررت بوضوع جديد وهو class الذي خلبط علي الشغله وكرهني في لغة c++فيا ليت تقوموم يالشرح الكافي مع الاملثه لو سمحتم (تكفى ياwolf) ولكم الشكر الجزيل:vereymad:

    6. #26
      التسجيل
      03-09-2003
      الدولة
      d=(n_n)=b دار بو خليفة d=(n_n)=b
      المشاركات
      1,096
      المواضيع
      62
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      ::

      ::

      ممنوع الرد فب هذا الموضوع

      سيتم ابلاغ المشرف

      ::

      ::
      ::

      ::



      "التوقيع فوق التعديل لوووووول "

      3/12/2005...."and UAE Naruto...is back again"

      من مواضيعي

      "مؤقتاً ماشي مواضيع حلوة "

      ::

      ::

    7. #27
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      السلام عليكم ...

      :: مقدمة ::

      انتهينا حتى الأن من الجزء الأول من الدروس .. و بعبارة أخرى كان ذلك الجزء مقدمة لك في البرمجة لمعرفة مفاهيمها و كيفية صياغة الحل بشكل سليم عن طريق الدوال و الأوامر الموجودة .
      و بذلك أعتبر أن ذلك الجزء مستواه مبتدئ .. و المجموعة الثانية من الدروس التي سنبدأ بها اليوم إن شاء الله أعتبرها ذو مستوى متوسط و هي كالتالي :

      1 – المصفوفات ( Arrays ) .
      2 – السجلات ( Structures ) .
      3 – المؤشرات ( Pointers ) .

      أما الجزء الأخير و هو البرمجة غرضية التوجه ( بجميع مواضيعه ) أعتبره ذو مستوى متقدم .. و بذلك نكون قد قسمنا الدروس إلى ثلاثة مستويات .. و هذا الأمر مهم برأيي .

      ملاحظة / أريد أن أوضح نقطة مهمة .. أن الدروس التي أكتبها هي ليست مني 100% ؟؟! .. بل هي مجهود مشترك بيني و بين من قام بتعليمي تلك اللغة ( لن أذكر اسمه ) و أيضاً المرجع " كيف تبرمج بلغة السي++ " للدكتور صلاح الدوه جي .. و بذلك أكون أنا حلقة وصل بينكم و بينهم .. و لكن هذا لا يعني أني لا أكتب شيئاً في هذا الدروس بل على العكس .. الدروس مكتوبة 100% مني و لكن محتواها من الأمثلة و المعلومات و الشرح مجزء كالآتي :

      1 – مني أنا 50% .. و شرح الأمثلة كلها كتبته بنفسي .. بالإضافة إلى أمثلة كثيرة و أمور أخرى كتبتها بنفسي .
      2 – أستاذي 45% .. حيث أنني وضعت الكثير من التعاريف و الأمثلة و الحلول التي قام هو بإعطائها لي حين تعلمت لغة السي++ منه .
      3 – المرجع 5% .. استفدت قليلاً من المرجع في وضع الدروس من هذا المرجع و هو مهم لذلك أنصح الجميع بالحصول عليه .

      و بذلك أكون قد أخلصت نيتي .. و برّأت ذمتي أمام الله .. و مع ذلك أنا على استعداد تام لأي سؤال يتعلق في تلك المواضيع .. فالحمدلله تلك الأساسيات أتقنها بشكل كبير .. لذلك من أراد اختباري فلا بأس .

      اليوم سنتكلم عن المصفوفات .. و سننتهي منها في هذا الدرس بشكل كامل إن شاء الله .. لذلك درس اليوم أيضاً مهم و سأحاول تبسيط الموضوع قدر الإمكان .. بسم الله نبدأ .

      ---------- ---------- ---------- الدرس السادس ---------- ---------- ----------
      اليوم : السبت ... التاريخ : 26 / 3 / 2005

      :: المصفوفات ( Arrays ) ::

      تخيل أنك تريد مثلاً أن تعرّف ( تنشئ ) مجموعة كبيرة من المتغيرات من النوع الواحد ( int على سبيل المثال ) .. فإذا أردنا مثلاً تعريف 10 متغيرات من ذلك النوع فإننا سنكتب التالي عشر مرات لعشر متغيرات يختلفون في الاسم :
      كود:
      int a;
      و بالتالي هذه الطريقة تضيع وقتنا و تدخلنا في متاهات نحن في غنا عنها .. إذاً نحتاج لتعلم شيء جديد يفيدنا في تنفيذ ذلك الأمر .. و هذا ما توفره لنا المصفوفات .

      إذاً ما الفائدة من المصفوفات ؟ نستفيد منها بالتالي :

      1 – تعريف مجموعة من المتغيرات من النوع الواحد بحيث يكون لتلك المتغيرات اسم مشترك بينها يمثل اسم المصفوفة .. بالإضافة إلى أننا نستطيع الوصول إلى أي من متغيرات المصفوفة عن طريق ما يسمى بالدليل ( Index ) .
      2 – هناك مسائل و أمور لا تحل إلا عن طريق المصفوفات حيث أن لها استخدامات متعددة .
      3 – أنك حينما تتعامل في برنامجك مع اسم المصفوفة فإنك تتعامل مع عنوانها في الذاكرة .. سنستفيد من هذه المعلومة في حل بعض المسائل .

      :: تعريف ::

      المصفوفة / هي معرّف ( Identifier ) مكونة من مجموعة من المتحولات كلها من نوع واحد .. و لتلك المتحولات اسم مشترك و يشار إلى كل قيمة منها ( متحول ) باسم المصفوفة مع الدليل الذي يدل على موقع القيمة ( المتحول ) في المصفوفة و يكون دليل العنصر الأول يساوي الصفر .

      :: التصريح عن المصفوفات ::

      بنفس طريقة تعريف المتحولات العادية و لكن مع إضافة شيء بسيط .. حيث يمكننا تعريف مصفوفة عن طريق تحديد نوع المصفوفة ثم اسمها .. ثم القوسين ( [] ) و نضع داخل القوسين عدد المتغيرات التي نريد وضعها في المصفوفة ( قلت العدد و ليس الدليل ) و بعد ذلك نضع الفاصلة المنقوطة .. و بذلك نكون قد عرّفنا مجموعة من المتغيرات من النوع الواحد .

      مثال /
      كود:
      int a[10];
      float a[5];
      bool a[8];
      ملاحظة 1 / في المثال الأول سيكون دليل العنصر الأول صفر و سيكون دليل العنصر الأخير 9 .
      ملاحظة 2 / هذه المصفوفات تمثل أشعة ( مصفوفة أحادية البعد ) و هذا يعني أن أبعادها كالتالي :
      كود:
      N × 1
      حيث n ممكن أن تكون أي عدد صحيح يمثل عدد أعمدة المصفوفة .. و الواحد طبعاً يمثل وجود سطر واحد فقط في تلك المصفوفة ( لذلك قلنا أن تلك المصفوفات أحادية الأبعاد ) .

      ملاحظة 3 / سنأخذ المصفوفة ثنائية الأبعاد في الفقرات التالية .
      ملاحظة 4 / يجب وضع حجم المصفوفة عند تعريفها .. بخلاف مصفوفة المؤشرات التي من الممكن تحديد حجمها أثناء تنفيذ البرنامج ( سنأخذها إن شاء الله ) .

      :: إعطاء قيم ابتدائية للمصفوفة ::

      أمثلة /
      كود:
      int a[3] = { 10, 20, 30 };
      int a[3] = { 5. 2 };
      int a[3] = { 5 };
      int a[3] = { 0 };
      في المثال الأول أعطينا المصفوفة a ثلاثة قيم قيم للعناصر الثلاثة التي تحتوي عليها و سيتم إسناد القيم بالترتيب .. فالقيمة عشرة سيأخذها العنصر الأول و القيمة عشرين سيأخذها العنصر الثاني و هكذا .. بينما في المثال الثاني أعطينا المصفوفة a قيمتان فقط و الثالثة ستعتبر صفر .. بينما في المثال الثالث أعطينا المصفوفة a قيمة واحدة و البقية ستعتبر أيضاً صفر .. أما في المثال الرابع ستعتبر قيم جميع العناصر أصفار .

      مثال توضيحي :


      ملاحظة / قلنا سابقاً فائدة إعطاء قيم ابتدائية للمتحولات .. فإذا أردت مثلاً استخدام تلك المتحولات ( في الكتابة على الشاشة أو في أحد العمليات الرياضية ) و لم تكن تحتوي على قيم فلن تكون النتائج صحيحة .. و المصفوفات بنفس الأسلوب .. و لكي تفهم الفكرة حاول كتابة قيمة متحول على الشاشة لم يعطى له قيمة ( ليس منك و لا من المستخدم ) و شاهد النتيجة .. سترى قيمة لا معنى لها .

      :: التعامل مع المصفوفة ::

      هناك طريقتين .. الأولى إذا كنا نريد التعامل مع عنصر واحد فقط .. و الثانية إذا كنا نريد التعامل مع جميع عناصر المصفوفة أو مع بعضها .. و الطريقتان متشابهتان :

      1 – التعامل مع عنصر واحد فقط :

      نستطيع ذلك عن طريق استخدام رقم الدليل الخاص بالعنصر المطلوب .. مثال / بفرض لدينا مصفوفة a تحتوي على ثلاثة أعداد حقيقية :
      كود:
      float a[3];
      a[0] = 5.0;
      هنا أعطينا العنصر الأول من المصفوفة العدد 5 .. بالتالي تحتاج دائماً إلى الدليل لاستخدام عناصر المصفوفة في أي عملية مهما كانت ( إخراج على الشاشة أو إسناد أو عملية جمع ... إلخ ) .

      2 – التعامل مع أكثر من عنصر :

      نحتاج لذلك إلى حلقة تكرار for .. حيث أننا سنستخدم متحول التكرار كدليل للمصفوفة في كل دورة .. لأن هذا المتحول ستتغير قيمته في كل مرة .. بحيث نضع القيمة الابتدائية له تساوي الصفر ( لأن دليل أول عنصر يساوي الصفر ) و القيمة النهائية تساوي عدد عناصر المصفوفة ناقص واحد ( لأننا قلنا أن أول أول عنصر سيأخذ الدليل صفر و الأخير سيكون دليله عدد العناصر ناقصاً الواحد ) .. مثال / بفرض أن لدينا مصفوفة a تحتوي على ثلاثة أعداد صحيحة :
      كود:
      int a[3];
      for( int i=0; i<3; i++ )
          a[i] = 5;
      ملاحظة / تخيل أنك استخدمت المصفوفة a السابقة عدداً كبيراً من المرات في برنامجك بواسطة حلقة التكرار for .. بالتالي ستضع القيمة الابتدائية لمتحول التكرار صفر و النهائية 2 .. و لكن افرض أنك قمت بتغيير حجم المصفوفة a فجعلتها تحتوي 5 عناصر بدلاً من 3 ؟ فستحتاج إلى تغيير الأرقام كلها التي وضعتها لمتحول التكرار في الحلقات for .. و لكن هناك حل جيد لهذه المشكلة و هي كالتالي :

      نضع ثابت صحيح في أول البرنامج يمثل حجم المصفوفة a و لنفرض أنه m .. و نضع جميع القيم النهائية لمتحول التكرار في الحلقات for القيمة m .. و بالتالي إذا احتجت إلى تغيير حجم المصفوفة بعد ذلك فستغير رقماً واحداً فقط و هو قيمة m .. مثال :
      كود:
      const int m = 5;
      float a[m];
      
      for( int i=0; i<m; i++ )
          a[i] = 5;
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    8. #28
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      :: المصفوفة الحرفية ( char ) ::

      أولاً / فائدة المصفوفة الحرفية :

      للمصفوفة الحرفية عدة مزايا أهمها أننا نستطيع بها تخزين جملة حرفية كاملة بدلاً من حرف واحد بواسطة char ( اسم على سبيل المثال ) .. بالإضافة إلى أن لها مزايا عند استخدامها مع قنوات الدخل و الخرج ( cout, cin ) .

      ثانياً / الفرق بين مفهوم الحرف و المحرف :

      الحرف : نقصد به الحرف أبجدي حصراً .. سواءً كان باللغة العربية أو الأجنبية .
      المحرف : ممكن أن يكون حرف أبجدي أو من الممكن أن يكون رمز أو علامة مثل ( $ ) .

      ثالثاً / التصريح عن المصفوفة الحرفية :

      بنفس طريقة التصريح عن المصفوفات الأخرى .. و ذلك بذكر نوع المصفوفة ( نريد هنا char ) ثم اسمها ثم حجمها و ذلك بوضع عدد عناصرها داخل القوسين ( [ ] ) .. مثال :
      كود:
      char name[20];

      رابعاً / إعطاء قيم ابتدائية للمصفوفة الحرفية :

      الطريقة الأولى :
      كود:
      char name[20] = { 'm','o','n','t','a','d','a','\0' };
      بنفس طريقة إعطاء قيم ابتدائية للمصفوفة العددية .. ولكن القيم هنا هي أحرف و ليست أرقام لذلك وضعنا الحاصرة الأحادية .. و لكن ما فائدة آخر رمز ؟ هذا الرمز يسمى بالمحرف الصفري .. و هو مهم لأنه يدل على نهاية الجملة الحرفية في المصفوفة .. فإذا أردنا مثلاً كتابة تلك الكلمة ( montada ) على الشاشة فإن الحرف الأخير الذي ستتم كتابته هو الحرف ( a ) و لن يتم كتابة باقي قيم المصفوفة ( حيث أن حجمها يساوي 20 أي أنها تتسع لجملة طولها 20 محرف ) .. و ذلك بسبب وجود المحرف الصفري ( سنأخذ مثال على ذلك في الفقرة التالية ) .. و لكن يمكنك في هذه الطريقة ألا تكتب المحرف الصفري لأن المترجم سيضعه بشكل تلقائي بعد آخر حرف وضعته في المصفوفة و لكن يفضل أن تكتبه أنت لكي تفهم فائدته .

      الطريقة الثانية :
      كود:
      char name[20] = "montada";
      هذه الطريقة أبسط و أسرع .. و المترجم هنا أيضاً سيقوم بوضع المحرف الصفري بشكل تلقائي بعد آخر حرف تضعه .. و هذه الطريقة خاصة بالمصفوفة الحرفية فقط دون غيرها .

      خامساً / قنوات الدخل و الخرج في المصفوفة الحرفية :

      1 – قنوات الدخل ( cin ) :
      تستطيع ذلك بواسطة استخدام اسم المصفوفة ( فقط دون القوسين طبعاً و دون استخدام الدليل ) .. و أيضاً دون الحاجة إلى استخدام حلقة for .. و هذه الطريقة أيضاً خاصة بالمصفوفة الحرفية فقط .. مثال / بفرض أن name هي مصفوفة حرفية تحتوي على 20 عنصر :
      كود:
      char name[20];
      cin >> name;

      2 – قنوات الخرج ( cout ) :
      بنفس أسلوب cin .. حيث أننا نستخدم اسم المصفوفة الحرفية فقط ( دون استخدام الدليل ) و دون استخدام حلقة for .. مثال / بفرض أن name مصفوفة حرفية :
      كود:
      char name[20];
      cout << name;
      من الممكن توضيح عمل الطريقة السابقة كالآتي ( للتوضيح فقط ) :
      كود:
      int i=0;
      while( name[i] != '\0' )
      {
          cout << name[i];
          i++;
      }

      سادساً / معرفة عدد المحارف التي تحتوي عليها المصفوفة الحرفية و التي تسبق المحرف الصفري :

      يمكننا ذلك عن طريق استخدام المعامل ( الدالة ) strlen الموجودة في المكتبة string.h .. بحيث نرسل المصفوفة الحرفية ( عن طريق اسمها فقط ) أو السلسلة الحرفية ( جملة حرفية موجودة داخل حاصرات مزدوجة " " ) إلى تلك الدالة كوسائط .. مثال :
      كود:
      #include <string.h>
      #include <iostream.h>
      
      void main()
      {
          cout << strlen("Montada") << endl;
      
          char name[20] = "Montada";
          cout << strlen(name);
      }
      ملاحظة / لن يتم احتساب المحرف الصفري في الدالة strlen و الموجودة في المكتبة string.h .

      سابعاً / تطوير cin من أجل المصفوفة الحرفية :

      قلنا سابقاً أنك إذا أردت أن تطلب من المستخدم إدخال قيم حرفية و ذلك بأن تضعها في مصفوفة من النوع char .. فإنك ستستخدم التالي / بفرض أن name مصفوفة حرفية :
      كود:
      cin >> name;
      و لكن افرض أن المستخدم أدخل جملة و ليس كلمة .. بالتالي سيكون هناك فراغات بين كل كلمة .. و هذه المسألة تعتبر مشكلة ! لماذا ؟ لأن قناة الدخل ( cin ) لن تقرأ إلا الكلمة الأولى فقط .. لأنها سوف تقف عند المسافة فهي مبرمجة على أن تنهي القراءة عند وجود الفراغ .. و لحل هذه المشكلة يمكننا استخدام الآتي :
      كود:
      cin.getline( name, 20 );
      حيث قمنا بإضافة المنهج ( الدالة ) getline إلى cin ( سنتحدث عن المناهج أو التوابع الخاصة عن الحديث حول الكائنات ) .. فبذلك سيتم قراءة السطر ككل دون الانتهاء عند الفراغ كالسابق .. و طبعاً عليناً إرسال المصفوفة الحرفية كوسيط بالإضافة إلى أقصى حد من عدد المحارف التي تريد أن تقف القراءة عندها و يفضل أن تضع حجم المصفوفة كحد أقصى .

      :: المصفوفة ثنائية الأبعاد ::

      أولاً / مقدمة :

      المصفوفة ثنائية الأبعاد تشبه تماماً المصفوفة أحادية البعد و لكنها تحتوي على أكثر من سطر و أكثر من عمود .. و بالتالي سنحتاج إلى دليلين عند استخدام هذه المصفوفة .. الأول من أجل الأسطر و الثاني من أجل الأعمدة .. على عكس المصفوفة أحادية البعد التي تحتوي على سطر واحد فقط و لكنها تحتوي على أكثر من عمود .

      ثانياً / التصريح عن المصفوفة ثنائية الأبعاد :

      بنفس أسلوب المصفوفة أحادية البعد .. و لكننا كما قلنا يجب أن نحدد حجم البعد الثاني أيضاً .. بحيث يمثل البعد الأول عدد الأسطر و البعد الثاني عدد الأعمدة .. مثال :
      كود:
      int a[3][3];

      ثالثاً / إعطاء قيم ابتدائية :

      مثال 1 / بفرض أننا نريد تعريف مصفوفة تحتوي على سطرين و عمودين .. بحيث يكون في السطر الأول العددين 1 و 2 .. و في السطر الثاني العددين 3 و 4 :
      كود:
      int a[2][2] = { {1,2} , {3,4} };
      مثال 2 / نريد تعريف مصفوفة تحتوية على سطرين و ثلاثة أعمدة و لكن قيمها كلها أصفار :
      كود:
      int a[2][3] = { 0 };
      بنفس الأسلوب .. حيث أننا إذا أعطينا قيم ابتدائية لجزء من المصفوفة فالباقي ستعتبر قيمه كلها أصفار .

      مثال توضيحي :


      رابعاً / المصفوفة ثنائية الأبعاد الحرفية :

      تتمتع بنفس مزايا المصفوفة الحرفية أحادية البعد ما عدا ميزة الإدخال ( cin ) و الإخراج ( cout ) .. حيث أننا نحتاج إلى حلقتين for بدلاً من واحدة .. الحلقة الأولى من أجل عدد الأسطر و الثانية من أجل عدد الأعمدة .

      مثال 1 / بفرض أننا نريد تعريف مصفوفة تحتوي على خمسة أسماء بحيث يمثل كل سطر اسم ما .. و طلبنا من المستخدم إدخال تلك الأسماء فسيكون الحل كالتالي :
      كود:
      char name[5][20];
      
      for( int i=0; i<5; i++ )
          for( int j=0; j<20; j++ )
              cin >> name[i][j];
      مثال 2 / أو من ممكن أن نستخدم الشكل التالي :
      كود:
      char name[5][20];
      
      for( int i=0; i<5; i++ )
              cin >> name[i];
      يمكننا إعطاء قيم ابتدائية للمصفوفة السابقة على الشكل التالي :
      كود:
      char name[5][20] = { {"montada"} , {'m','o','n','t','a','d','a','\0'} };
      حيث أنني وضعت اسمين فقط بطريقتين مختلفتين .. و هما صحيحتين على ألا تنسى في الطريقة الثانية المحرف الصفري كما قلنا سابقاُ .. و باقي الأسطر ستحتوي على الفراغ .. فإذا حاولنا كتابة المصفوفة السابقة على الشاشة فإننا سنكتب التالي :
      كود:
      for( int i=0; i<5; i++ )
      {
          for( int j=0; j<20; j++ )
              cout >> name[i][j];
          cout << endl;
      }
      استخدمنا cout << endl لكي نضع كل جملة على سطر .
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    9. #29
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      :: استخدام المصفوفات في التوابع كمتحولات وسيطة ::

      كما قلنا في موضوع التوابع .. أنه يمكننا وضع أي شيء نريده كمتحولات وسيطة شكلية ( متغيرات عددية أو حرفية أو مؤشرات أو مصفوفات أو كائنات ... إلخ ) .. و نحن نريد هنا المصفوفات فكيف يمكننا ذلك ؟
      الحل بسيط .. فقط نقوم بوضع نوع المصفوفة ثم اسمها ثم حجمها .. مثال :
      كود:
      void f1( int s[20] )
      {
      }
      و يمكننا أيضاً عدم وضع حجم المصفوفة .. مثال /
      كود:
      void f1( int s[ ] )
      {
      }
      هذا إن كنا نستخدم الطريقة الأولى في كتابة التوابع .. أما لو استخدمنا الطريقة الثانية و هي كالتالي / بوضع رأس التابع فوق التابع الأساسي main و جسم التابع يكون أسفله :
      كود:
      void f1( int [ ] );

      فإننا لن نحتاج إلى وضع حجم المصفوفة أو حتى اسمها في رأس التابع و لكن يجب وضع القوسين( [ ] ) ( ليس كالسابق كالمتغيرات العادية حيث كنا نكتفي بنوع المتغير فقط ) .. هذا الأمر فقط في المصفوفة أحادية البعد .. أما في المصفوفة ثنائية البعد فيجب تحديد حجم البعد الثاني فقط متجاهلين حجم البعد الأول .

      مثال :
      كود:
      void f1( int [ ][20] );
      أو حتى عند كتابة التابع نفسه :
      كود:
      void f2( int s[ ][20] )
      {
      }

      قاعدة 1 / عند تعريف المصفوفات ( سواءً الأحادية أم الثنائية البعد ) كمتحولات وسيطة في التوابع :

      1 - فإننا لن نحتاج إلى وضع اسم المصفوفة إذا ما عرفنا رأس التابع و لكن نحتاج إلى وضع حجم البعد الثاني لمصفوفة إذا كانت ثنائية الأبعاد .. و الأقواس ( [ ] ) طبعاً ضرورية .
      2 – و لكننا نحتاج إلى وضع اسم المصفوفة عند وضع جسم التابع مع إمكانية تجاهل حجم البعد الأول فقط للمصفوفة ( قلت الحجم و ليس القوسين ( [ ] ) ) كما في الفقرة الأولى .

      و لكن كيف يمكننا إرسال إحدى قيم ( عناصر ) المصفوفة ؟ أو حتى كيف يمكننا إرسال المصفوفة كلها إلى إحدى التوابع كمتحولات وسيطة فعلية ؟ ( راجع درس التوابع لمعرفة معنى متحولات وسيطة فعلية و شكلية ) ..

      قاعدة 2 / يمكننا إرسال أحد عناصر المصفوفة عن طريق وضع اسم المصفوفة مع الدليل الخاص بذلك العنصر .. مثال / بفرض أن f1 تابع لا يعيد قيمة يحتاج إلى عدد صحيح كمدخلات له .. و s هي مصفوفة من النوع int :
      كود:
      f1( s[0] );

      قاعدة 3 / أما إذا كنا نريد إرسال المصفوفة كلها إلى تابع ما .. فنضع اسم المصفوفة فقط دون حجمها و بدون الأقواس ( [ ] ) .. مثال / هنا التابع f1 يحتاج إلى مصفوفة كمدخلات و ليس إلى قيمة واحدة كالمثال السابق :
      كود:
      f1( s );

      قاعدة 4 / إن نوع الاستدعاء في المصفوفات هو استدعاء بالمرجع ( حصراً ) و لا يمكن استدعاؤها بالقيمة ( هذا إن كنا أرسلنا المصفوفة كلها كمتحول فعلي إلى تابع آخر ) ..
      و بالتالي إذا قمت بتغيير إحدى قيم المصفوفة في أحد التوابع فإن تلك القيمة ستتغير في المصفوفة الأصلية لأنها تستدعى بالمرجع بشكل تلقائي .. حيث أن اسمها يمثل عنوان أول عنصر ( لها ) في الذاكرة .. و قلنا سابقاً بأن معنى المرجعية ( Reference ) هو التعامل مع عنوان المتغير في الذاكرة .. و بالتالي يمكن أن يكون هناك أكثر من متغير يحملون نفس الموقع في الذاكرة ( متغير فعلي واحد مع عدة متغيرات شكلية ) .. فإذا تغير أحدهم يتغير الآخر ( راجع موضوع الاستدعاء بالقيمة و بالمرجع في درس التوابع ) .

      قاعدة 5 / إن الاستدعاء لأحد قيم المصفوفة من الممكن أن يكون إما بالقيمة أو بالمرجع .. مثال لاستدعاء إحدى قيم المصفوفة بالقيمة / لبرنامج يقوم بطلب جملة من المستخدم و من ثم يكتب له أول حرف من هذه الجملة ( للتوضيح فقط ) :
      كود:
      #include <iostream.h>
      
      void f1( char s )
      {
          cout << s << endl;
      } 
      
      void main()
      {
          char name[20];
      
          cin >> name;
      
          f1(name[0]); 
      }

      ملاحظة / إذا كنا نريد في المثال السابق أن نستدعي القيمة :
      كود:
      name[0]
      بالمرجع فما علينا إلا أن نضيف الرمز ( & ) قبل المتحول الشكلي ( s ) الموجود في التابع ( f1 ) .


      :: نظام الترميز ASCII ::

      1 – مقدمة :

      لماذا نتعلم نظام الآسكي ؟ في الحقيقة هذا النظام مفيد جداً لحل بعض المسائل .. فهذا النظام قام على أساس وضع لكل رقم أو حرف أو رمز ... إلخ رقماً معين ( شفرة ) يشير إلى ذلك المحرف أو الرقم .. بحيث يحتوي هذا النظام على 256 رقماً يشيرون إلى تلك الرموز و الأحرف و الأرقام .

      2 – محتويات النظام ASCII :

      يحتوي هذا النظام كما قلنا على عدة رموز ( سنأخذ المهمة فقط ):

      أ ) من 0 إلى 32 : عبارة عن مجموعة من الأوامر و الأحـداث .. كحدث الضغط على زر Enter أو Space .
      ب ) من 48 إلى 57 : الأرقام من الصفر و حتى التسعة .
      ج ) من 65 إلى 90 : الأحرف الإنجليزية الكبيرة مثل : ( A, B, C ) .
      د ) من 97 إلى 122 : الأحرف الإنجليزية الصغيرة مثل : ( a, b, c ) .

      3 - استخدام نظام الترميز ASCII في السي++ :

      يمكننا ذلك عن طريق المتغيرات من النوع int و char .. كيف ؟ و ذلك إما بوضع محرف في متغير عددي صحيح ( int ) أو بوضع عدد صحيح في متغير حرفي ( char ) .. انظر المثال التالي :
      كود:
      int a = 'a';
      
      char b = 98;
      في المثال الأول أعطينا المتغير العددي a قيمة حرفية من النوع char .. و بالتالي سيقوم المترجم بإيجاد الرمز الذي يشير إلى الحرف الصغير a في النظام ASCII .. و سوف يضع القيمة ( 97 ) في المتحول a .. لذلك إذا حاولت كتابة قيمة المتحول a على الشاشة فسوف يظهر الرقم 97 كما قلنا .

      في المثال الثاني عكسنا العملية .. فقمنا بوضع قيمة عددية في متغير حرفي .. لذلك سيقوم المترجم بإيجاد القيمة التي يشير إليها الرمز 98 و هي الحرف b الصغير .. لذلك قم بكتابة قيمة كل من المتغيرين a و b على الشاشة ( cout ) و شاهد النتائج .

      4 – الاستفادة من نظام الترميز ASCII :

      سوف نأخذ مثال يوضح فائدة استخدام هذا النظام و أنه يبسط الحل أكثر .. فهناك مسائل إذا استخدمت فيها هذا النظام فسختصر على نفسك سطوراً كثيرة من الأوامر و سنرى ذلك في المثال العملي السابع .

      ----------------------------------------
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    10. #30
      التسجيل
      11-04-2002
      الدولة
      سوريا
      المشاركات
      760
      المواضيع
      76
      شكر / اعجاب مشاركة

      مشاركة: :: مشروع لتعليم أساسيات ++C :: موضوع الدروس

      :: أمثلة تطبيقية ::

      سأقوم بوضع أمثلة تتدرج من السهل إلى الأصعب .. مع وضع برنامج تطبيقي في النهاية يشمل موضوع المصفوفات بشكل كامل .

      ملاحظة / جميع هذه الأمثلة من أستاذي ( جزاه الله خيراً ) .. و ها أنا أضعها بين يديكم .

      المثال 1 /

      نريد من المستخدم أن يدخل خمسة أعداد صحيحة و من ثم نكتب له مجموع تلك الأعداد :


      الحل /
      كود:
      #include <iostream.h>
      
      void main()
      {
          int sum = 0;
          int a[5];
          
          for( int i=0; i<5; i++ )
          {
              cout << "a[" << i << "] : ";
              cin >> a[i];
              sum += a[i];
          }
      
          cout << "Sum = " << sum << endl;
      }
      شرح الحل :

      1 – قمنا بتعريف المتغير sum و الذي سيقوم بحساب مجموع الأعداد المدخلة .. و وضعنا له قيمة ابتدائية تساوي الصفر ( قلنا سابقاً فائدة ذلك ) .
      2 – عرفنا مصفوفة أعداد صحيحة لكي يدخل المستخدم الأعداد فيها .. و هي تحتوي على خمسة مواقع في الذاكرة من النوع int .
      3 – بعد ذلك قمنا بترتيب عملية الإدخال لكي يعرف المستخدم أي الأعداد سيدخل .. و ذلك عن طريق عملية الإخراج الأولى .. حيث أن المستخدم في كل عملية إدخال جديدة ( في كل دورة ) سيتم تخزين العدد المدخل في مكانه المناسب في المصفوفة a .. و بعدها أيضاً سيتم إضافة ذلك العدد إلى sum في كل مرة لكي يحتوي sum في النهاية على مجموع تلك الأعداد .
      4 – في النهاية قمنا بكتابة ناتج عملية الجمع بواسطة المتحول sum .

      ----------------------------------------

      المثال 2 /

      نريد من المستخدم أن يدخل عدداً من الحروف و من ثم نكتب له كل حرف قام بكتابته على سطر :



      الحل /
      كود:
      #include <iostream.h>
      #include <string.h>
      
      void main()
      {
          char s[100];
      
          cin >> s;
      
          for( int i=0; i<strlen(s); i++ )
              cout << s[i] << endl;
      }
      شرح الحل :

      1 – قمنا بتعريف مصفوفة حرفية تتسع لمائة محرف و سميناها s ( المائة عدد افترضناها تستطيع وضع ما شئت ) .
      2 – طلبنا من المستخدم إدخال تلك الأحرف .
      3 – في الحلقة for .. قمنا بجعل الدليل i يبدأ من القيمة صفر ( لأن دليل أول عنصر في المصفوفة يساوي الصفر ) و ينتهي في آخر دورة بعدد محارف تلك المصفوفة و التي تسبق المحرف الصفري ( راجع فقرة معرفة عدد المحارف ) .. و لكن لماذا فعلنا هذا ؟ لأننا نريد كتابة الأحرف التي أدخلها المستخدم فقط و لا نريد جميع عناصر المصفوفة حيث أن المستخدم قد يدخل عدداً من الأحرف تقل عن المائة .
      4 – في داخل الحلقة for قمنا في كل دورة بكتابة عنصر المصفوفة ذي الدليل i و انتقلنا إلى سطر جديد .. و هذه العملية ستتكرر على حسب عدد المحارف التي أدخلها المستخدم .

      ----------------------------------------

      المثال 3 /

      نريد من المستخدم إدخال جملة و من ثم نكتب له كل كلمة أدخلها على سطر :



      الحل /
      كود:
      #include <iostream.h>
      #include <string.h>
      
      void main()
      {
          char s[100];
      
          cin.getline( s, 100 );
      
          for( int i=0; i<strlen(s); i++ )
              if( s[i] == ' ' )
                  cout << endl;
              else
                  cout << s[i];
      
          cout << endl;
      }
      شرح الحل :

      1 – بنفس أسلوب المثال السابق و لكن مع بعض التطوير .. حيث قمنا باستخدام المنهج ( الدالة ) getline لكي نخزن في المصفوفة s جميع الكلمات و ليس الكلمة الأولى فقط حيث أننا سنقرأ أول مائة محرف ( قلنا أنه يفضل وضع حجم المصفوفة و الذي سنرسله مع المصفوفة s كوسائط إلى المنهج getline ) .. و حيث أن cin العادية ستقوم بقراءة أول كلمة فقط حيث أنها تنتهي القراءة عند الفراغ ( راجع فقرة تطوير قناة الدخل cin ) .
      2 – في الحلقة for .. سنختبر في كل دورة عناصر المصفوفة عنصراً عنصراً .. فإذا كان هذا العنصر ( المحرف ) يساوي الفراغ فسنقوم بالنزول إلى سطر جديد .. أما إذا لم يكن كذلك فسنكتب له المحرف و بهذه الطريقة سيتم وضع كل كلمة على سطر و هذا هو المطلوب .
      3 – في النهاية قمنا فقط بالنزول إلى سطر جديد من أجل ترتيب البرنامج .

      ----------------------------------------

      المثال 4 /

      نريد من المستخدم إدخال 10 أعداد صحيحة و من ثم نكتب له أكبر عدد و أصغر عدد و ذلك باستخدام المصفوفات :



      الحل /
      كود:
      #include <iostream.h>
      
      void main()
      {
          int a[10], max, min;
      
          cout << "a[0] = ";
          cin >> a[0];
      
          max = a[0];
          min = a[0];
      
          for( int i=1; i<10; i++ )
          {
              cout << "a[" << i << "] = ";
              cin >> a[i];
      
              if( a[i] > max ) max = a[i];
              if( a[i] < min ) min = a[i];
          }
      
          cout << "Max = " << max << endl
                   << "Min = " << min << endl;
      }
      شرح الحل :

      هذا المثال يطابق تماماً المثال الثالث الموجود في الدرس الثالث .. لذلك لن أشرحه لكي لا أقوم بتكرار شيء موجود .

      ----------------------------------------

      المثال 5 /

      نريد من المستخدم إدخال جملة و من ثم نحسب له عدد كلمات تلك الجملة .. على أنه من الممكن أن يكون بين كل كلمتين أكثر من فراغ أو حتى من الممكن أن يكون هناك رمز ما مثل ( $ ) أو حتى رقم .. لذلك من الخطأ حساب عدد الفراغات .. و لكن ما الحل ؟

      فكرة الحل / يمكننا حساب عدد كلمات جملة ما إذا عرفنا متى تنتهي الكلمة .. تنتهي الكلمة إذا وجدنا حرف في المصفوفة بعده فراغ و بالتالي يكون ذلك الحرف هو آخر حرف في الكلمة .. عندها يكون عندنا متحول يحسب لنا عدد الكلمات فنزيده واحد و هكذا ..


      الحل /
      سنستخدم التوابع في هذا الحل :
      كود:
      #include <iostream.h>
      #include <string.h>
      #include <ctype.h>
      
      int nword(char s[ ]);
      
      void main()
      {    
          char s[100];
      
          cout << "Enter The Sentence : ";
          cin.getline(s, 100);
      
          cout << nword (s) << endl;
      }
      
      int nword(char s[100])
      {
          int c=0;
      
          for( int i=0; i<strlen(s); i++ )
              if( isalpha(s[i]) && !isalpha(s[i+1]) )
                  c++;
      
          return c;
      }
      شرح الحل :

      1 – ما فائدة التابع ( الدالة ) isalpha ؟ هذا التابع يقوم باختبار فيما إذا كانت القيمة المرسلة إليه حرفاً أبجدياً أم لا .. و هذا ما نحتاجه في سؤالنا هذا .. و هذا التابع موجود في المكتبة ctype.h .
      2 – أظن أن التابع main مفهوم .. فقط قمنا بتعريف مصفوفة حرفية و من ثم طلبنا من المستخدم إدخال جملة و بعد ذلك استدعينا التابع nword و الذي سيحسب لنا عدد الكلمات للجملة المدخلة من قبل المستخدم .
      3 – في التابع nword .. قمنا بأخذ المصفوفة من التابع main و أجرينا عليها الاختبار الذي ذكرناه في فكرة الحل .. قمنا باختبار جميع قيم المصفوفة فإذا وجدنا أن إحدى القيم هي حرف أبجدي و كان المحرف الذي يليه ليس حرفاً أبجدياً ( استخدمنا علامة النفي ! ) بالتالي يكون لدينا كلمة جديدة و عندها نزيد العداد ( c ) واحد .. و هكذا إلى نهاية المصفوفة .. و في النهاية سيقوم التابع nword بإرجاع قيمة عدد الكلمات إلى التابع main .

      ----------------------------------------
      التعديل الأخير تم بواسطة Wolf Sniper ; 25-03-2005 الساعة 10:41 PM
      لا إله إلا الله
      مشروع لتعليم أساسيات لغة الـ ++C :
      -
      موضوع لتعليم الفيجوال بيسك 6 :

    صفحة 3 من 5 الأولىالأولى 12345 الأخيرةالأخيرة

    ضوابط المشاركة

    • لا تستطيع إضافة مواضيع جديدة
    • لا تستطيع الرد على المواضيع
    • لا تستطيع إرفاق ملفات
    • لا تستطيع تعديل مشاركاتك
    •