ما هو بناء الجملة الكامل للحلقة "for" في لغة C؟

StackOverflow https://stackoverflow.com/questions/276512

  •  07-07-2019
  •  | 
  •  

سؤال

لقد رأيت بعض غريب جدا for حلقات عند قراءة كود الآخرين.لقد كنت أحاول البحث عن شرح كامل لبناء الجملة لـ for حلقة في C ولكن الأمر صعب جدًا لأن كلمة "for" تظهر في جمل غير ذات صلة مما يجعل البحث شبه مستحيل على Google بشكل فعال.

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

ال for هنا:

for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);

في الحالة الوسطى توجد فاصلة تفصل بين قطعتي الكود، ماذا تفعل هذه الفاصلة؟أفهم الفاصلة الموجودة على الجانب الأيمن لأنها تشير إلى كليهما a>>=1 و b<<=1.

ولكن في حالة الخروج من الحلقة، ماذا يحدث؟هل يخرج متى p==0, ، متى a==1 أو عندما يحدث كلاهما؟

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

هل كانت مفيدة؟

المحلول

الفاصلة لا تقتصر على الحلقات؛إنه عامل الفاصلة.

x = (a, b);

سنفعل أولاً a، ثم b، ثم نضبط x على قيمة b.

بناء الجملة هو:

for (init; condition; increment)
    ...

وهو إلى حد ما (تجاهل continue و break في الوقت الحالي) يعادل:

init;
while (condition) {
    ...
    increment;
}

لذا فإن مثال الحلقة الخاص بك هو (تجاهل مرة أخرى continue و break) أي ما يعادل

p=0;
while (p+=(a&1)*b,a!=1) {
    ...
    a>>=1,b<<=1;
}

الذي يتصرف كما لو كان (تجاهل مرة أخرى continue و break):

p=0; 
while (true) {
    p+=(a&1)*b;
    if (a == 1) break;
    ...
    a>>=1;
    b<<=1;
}

تفصيلان إضافيان للحلقة for والتي لم تكن موجودة في التحويل المبسط إلى حلقة while أعلاه:

  • إذا تم حذف الشرط، فهو دائما true (مما يؤدي إلى حلقة لا نهائية ما لم يكن a break, goto, أو أي شيء آخر يكسر الحلقة).
  • أ continue يعمل كما لو كان عبارة عن انتقال إلى تسمية قبل الزيادة مباشرةً، على عكس a continue في حلقة while والتي من شأنها تخطي الزيادة.

أيضًا، تفاصيل مهمة حول عامل الفاصلة:إنها نقطة تسلسل، مثل && و || (ولهذا السبب يمكنني تقسيمها إلى عبارات منفصلة والحفاظ على معناها سليمًا).


التغييرات في C99

يقدم معيار C99 بعض الفروق الدقيقة التي لم يتم ذكرها سابقًا في هذا الشرح (وهو أمر جيد جدًا بالنسبة لـ C89/C90).

أولاً، جميع الحلقات عبارة عن كتل في حد ذاتها.على نحو فعال،

for (...) { ... }

هو نفسه ملفوف في زوج من الأقواس

{
for (...) { ... }
}

المعيار يقول:

ISO/IEC 9899:1999 §6.8.5 بيانات التكرار

¶ 5 بيان التكرار هو كتلة نطاقها مجموعة فرعية صارمة من نطاق الكتلة المرفقة.جسم الحلقة هو أيضًا كتلة هي مجموعة فرعية صارمة من نطاق بيان التكرار.

وهذا موصوف أيضًا في الأساس المنطقي من حيث المجموعة الإضافية من الأقواس.

ثانيا، init الجزء في C99 يمكن أن يكون إعلانًا (مفردًا)، كما في

for (int i = 0; i < sizeof(something); i++) { ... }

الآن أصبحت "الكتلة الملفوفة حول الحلقة" في حد ذاتها؛وهو ما يفسر لماذا المتغير i لا يمكن الوصول إليها خارج الحلقة.يمكنك الإعلان عن أكثر من متغير، لكن يجب أن تكون جميعها من نفس النوع:

for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }

المعيار يقول:

ISO/IEC 9899:1999 §6.8.5.3 بيان

البيان

for ( clause-1 ; expression-2 ; expression-3 ) statement

يتصرف على النحو التالي:التعبير التعبير 2 هو التعبير المسيطر الذي يتم تقييمه قبل كل تنفيذ لجسم الحلقة.يتم تقييم التعبير-3 كتعبير باطل بعد كل تنفيذ لجسم الحلقة.إذا كان الفقرة 1 عبارة عن إعلان ، فإن نطاق أي متغيرات يعلن هو الجزء المتبقي من الإعلان والحلقة بأكملها ، بما في ذلك التعبيرين الآخرين ؛يتم الوصول إليه بترتيب التنفيذ قبل التقييم الأول للتعبير المسيطر.إذا كان البند 1 هو تعبير ، فسيتم تقييمه كتعبير باطل قبل التقييم الأول للتعبير المسيطر.133)

يمكن حذف كل من البند 1 والتعبير 3.يتم استبدال تعبير تم حذفه -2 بدس غير صفري.

133) وبالتالي ، يحدد الفقرة -1 تهيئة الحلقة ، وربما الإعلان عن متغير واحد أو أكثر للاستخدام في الحلقة ؛يحدد التعبير المسيطر ، التعبير -2 ، تقييمًا تم إجراؤه قبل كل تكرار ، بحيث يستمر تنفيذ الحلقة حتى يقارن التعبير مساواة 0 ؛والتعبير-3 يحدد عملية (مثل الزيادة) التي يتم تنفيذها بعد كل تكرار.

نصائح أخرى

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

تتكون

والحلقات for من ثلاثة أجزاء، أي من الذي قد يكون أيضا فارغة. واحد (أول) يتم تنفيذه في البداية، و (الثالث) واحدة في نهاية كل تكرار. هذه الأجزاء عادة التهيئة وزيادة عداد، على التوالي؛ ولكنها قد تفعل أي شيء.

والجزء الثاني هو اختبار التي يتم تنفيذها في بداية كل التنفيذ. إذا false عائدات الاختبار، يتم إحباط الحلقة. هذا كل ما في الامر.

يتكون نمط C للحلقة من ثلاثة تعبيرات:

for (initializer; condition; counter) statement_or_statement_block;
  • يتم تشغيل المُهيئ مرة واحدة، عند بدء الحلقة.
  • يتم التحقق من الشرط قبل كل تكرار.تعمل الحلقة طالما تم تقييمها على أنها صحيحة.
  • يعمل العداد مرة واحدة بعد كل تكرار.

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

ولتحقيق ذلك، يعد عامل الفاصلة مفيدًا جدًا.فهو يسمح لك بربط التعبيرات معًا لتكوين تعبير جديد واحد.في معظم الأحيان يتم استخدامه بهذه الطريقة في حلقة for، والتأثيرات الأخرى لمشغل الفاصلة (على سبيل المثال:تلعب اعتبارات تخصيص القيمة) دورًا ثانويًا.

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

ويكيبيديا لديها لطيفة مقال عن الحلقة أيضًا.

كل شيء اختيارية في حلقة for. يمكننا تهيئة أكثر من متغير واحد، ونحن يمكن التحقق من حالة أكثر من واحد، يمكننا تكرار أكثر من متغير واحد باستخدام المشغل فاصلة.

وحلقة for التالية سوف يأخذك في حلقة لا نهائية. كن حذرا عن طريق التحقق من حالة.

for(;;) 

وكونراد المذكورة النقطة الرئيسية التي أود أن أكرر: إن قيمة أقصى اليمين التعبير هي قيمة التعبير العام

ومترجم جنو جاء هذا التحذير عندما أضع اختبارين في قسم "حالة" من أجل حلقة

warning: left-hand operand of comma expression has no effect

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

ووللحلقة هو تنفيذ لوقت معين ل(؛؛)

وعلى سينتكس عن حلقة

ول(؛؛)

وOR

ول(مهيئ، شرط؛ العداد)

ومنها مثلا (RMV = 1؛ RMV <= 15؛ RMV ++)

والتنفيذ إلى 15 مرة في لكتلة

و1.first initializ قيمة لبدء قيمة

و(على سبيل المثال) RMV = 1 أو RMV = 2

وبيان 2.second هو اختبار الشرط صحيحا أو كاذبة، شرط صحيح الاسم Name تنفيذ الوقت للحلقة والشرط هو إنهاء كاذبة عن كتلة

ومنها مثلا ط = 5؛ ط <= 10 كان الشرط صحيحا

i=10;i<10 the condition is false terminate for block,

و3.third هو زيادة أو إنقاص

و(على سبيل المثال) RMV ++ أو ++ RMV

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top