c# - example - لم تشاهد قبل C++ للحلقة



for-loop (8)

إذا كنت معتادًا على C / C ++ ، فلن يكون من الصعب قراءة هذا الرمز ، على الرغم من أنه مقتضب جدًا وليس كبيرًا من الشفرة. لذا اسمحوا لي أن أشرح الأجزاء التي هي Cism أكثر من أي شيء آخر. أولاً ، يبدو الشكل العام لحرف C للحلقة كما يلي:

for (<initialization> ; <condition>; <increment>)
{
    <code...>
}

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

لماذا تعمل u-- كشرط في C وليس C #؟ لأن C تحوّل الكثير من الأشياء بشكل منطقي إلى حد كبير ، وقد تتسبب في مشاكل. بالنسبة لرقم ما ، فإن أي شيء غير الصفر يكون صحيحًا والصفر خاطئ. لذلك سيكون العد التنازلي من b.size () - 1 إلى 0. وجود تأثير جانبي في الحالة مزعج بعض الشيء وسيكون من الأفضل وضعه في جزء الزيادة في الحلقة ، على الرغم من أن الكثير من C رمز يفعل هذا. إذا كنت أكتبها ، سأفعلها أكثر من هذا:

for (u = b.size() - 1, v = b.back(); u>=0; --u) 
{
    b[u] = v;
    v = p[v]
}

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

قد يرميك عامل الفاصلة في حلقة أيضًا. في C شيء مثل x=1,y=2 يبدو x=1,y=2 عبارة واحدة بقدر ما يتعلق الأمر المحول البرمجي وتناسبها في رمز التهيئة. يقوم فقط بتقييم كل جزء من الأجزاء ويعيد قيمة الأخير. على سبيل المثال:

std::cout << "(1,2)=" << (1,2) << std::endl;

سوف تطبع 2.

https://ffff65535.com

كنت أحول خوارزمية C ++ إلى C #. جئت عبر هذا للحلقة:

for (u = b.size(), v = b.back(); u--; v = p[v]) 
b[u] = v;

لا يعطي أي خطأ في C ++ ، ولكنه لا يعمل في C # (لا يمكن تحويل int إلى bool). أنا حقا لا يمكن معرفة هذا من أجل حلقة ، أين هي الشرط؟

يمكن للشخص يرجى توضيح؟

PS. فقط للتحقق ، لتكييف VECTOR إلى LIST هل b.back () تتوافق مع b [b.Count-1]؟


الخطأ الموجود في C # يزيل الشك. البحث عن حلقة for a

خاطئة

شرط لإنهاء. وكما نعلم ،

(BOOL) FALSE = (int) 0

ولكن لا يمكن معالجة C # هذا من تلقاء نفسها على عكس C ++. لذلك فإن الحالة التي تبحث عنها هي

u--

ولكن عليك أن تعطي الشرط بشكل صريح في C #

u--! = 0

أو

u--> 0

ولكن لا تزال تحاول تجنب هذا النوع من ممارسة الترميز. ال

حائط اللوب

المذكورة اعلاه في الاجابه هي واحدة من أبسط صيغتك

لحلقة.


الشرط هو نتيجة u-- ، وهي قيمة u قبل أن يتم تصغيرها.

في C و C ++ ، int هو قابل للتحويل إلى bool عن طريق إجراء ضمنيًا مقارنة != 0 (0 غير false ، وكل شيء آخر true ).

b.back() هو العنصر الأخير في الحاوية ، وهو b[b.size() - 1] ، عندما يكون size() != 0 .


الكثير من الإجابات الدقيقة ، ولكن أعتقد أنه يستحق كتابة ما يعادل حلقة.

for (u = b.size(), v = b.back(); u--; v = p[v]) 
   b[u] = v;

يعادل ما يلي:

u = b.size();
v = b.back();
while(u--) {
   b[u] = v;
   v = p[v];
}

قد تفكر في إعادة الصياغة إلى صيغة while () أثناء الترجمة إلى C #. في رأيي أنه أكثر وضوحا ، أقل من فخ للمبرمجين الجدد ، وعلى نفس القدر من الكفاءة.

كما أشار آخرون - ولكن لإكمال إجابتي - لجعلها تعمل في C # ، ستحتاج إلى التغيير while(u--) إلى while(u-- != 0) .

... أو في while(u-- >0) فقط في حالة ش البداية السلبية. (حسناً ، لن يكون b.size() سالبًا أبدًا - لكن ضع في اعتبارك حالة عامة قد يكون فيها شيء آخر قد b.size() ).

أو لجعلها أكثر وضوحًا:

u = b.size();
v = b.back();
while(u>0) {
   u--;
   b[u] = v;
   v = p[v];
}

من الأفضل أن تكون واضحًا من أن تكون مقتضبًا.


حالة حلقة for في الوسط - بين الفاصلتين المنقوطة ; .

في C ++ ، من الممكن وضع أي تعبير تقريبًا كشرط: أي شيء يتم تقييمه إلى الصفر يعني false . غير الصفر يعني true .

في حالتك ، يكون الشرط هو u-- : عند التحويل إلى C # ، ببساطة أضف != 0 :

for (u = b.size(), v = b.back(); u-- != 0; v = p[v]) 
    b[u] = v; //                     ^^^^ HERE

سيكون هذا هو شكل C # من الحلقة.

// back fetches the last element of vector in c++.
for (u = b.size(), v = b.back(); (u--) != 0; v = p[v]) 
{      
  b[u] = v;      
}

فقط استبدال مكافئ لحجم () والظهر ().

ما يفعله هو عكس القائمة والمخازن في صفيف. ولكن في C # لدينا مباشرة وظيفة محددة لهذا النظام. لذلك لا تحتاج إلى كتابة هذه الحلقة أيضا.

b = b.Reverse().ToArray();

وكما ذكر آخرون ، فإن حقيقة أن C ++ u-- ضمنيًا إلى u-- يعني أن الشرط هو u-- ، والذي سيكون صحيحًا إذا كانت القيمة غير صفرية.

من المفيد إضافة ، أن لديك افتراضًا زائفًا في السؤال "أين هو الشرطي". في كل من C ++ و C # (وغيرها من لغات syntaxed المماثلة) ، يمكن أن يكون لديك شرط شرطي فارغ. في هذه الحالة ، يتم تقييمها دائمًا إلى true ، بحيث تستمر الحلقة إلى الأبد ، أو حتى تخرج منها حالة أخرى (عن طريق return ، أو break ، أو throw ).

for(int i = 0; ; ++i)
  doThisForever(i);

في الواقع ، يمكن استبعاد أي جزء من البيان ، وفي هذه الحالة لا يتم تنفيذه.

بشكل عام ، for(A; B; C){D} أو for(A; B; C)D; يصبح:

{A}
loopBack:
if(!(B))
  goto escapeLoop;
{D}
{C}
goto loopBack;
escapeLoop:

يمكن ترك أي واحد أو أكثر من A أو B أو C أو D خارجًا.

نتيجة لهذا ، بعض لصالح for(;;) للحلقات لانهائية. أظن أنه بينما while(true) أكثر شعبية ، قرأت ذلك بأنه "حتى تنتهي الحقيقة أن تكون حقيقية" ، والتي تبدو كارثية إلى حد ما بالمقارنة مع قراءتي for(;;) بأنها "إلى الأبد".

إنها مسألة ذوق ، ولكن بما أنني لست الشخص الوحيد في العالم الذي يعجبني for(;;) فإنه يستحق معرفة ما يعنيه.


for (u = b.size(), v = b.back(); u--; v = p[v]) 
   b[u] = v;

في التعليمة البرمجية أعلاه ، تتم تهيئة u و v بـ b.size() و b.back() .

في كل مرة يتم فيها فحص الشرط ، يقوم بتنفيذ العبارة decrement أيضاً.

ستخرج الحلقة for عندما ستصبح 0 .





for-loop