سؤال

ماذا يفعل الكود التالي في C/C++؟

if (blah(), 5) {
    //do something
}
هل كانت مفيدة؟

المحلول

يتم تطبيق عامل الفاصلة ويتم استخدام القيمة 5 لتحديد صواب/خطأ الشرط.

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


لاحظ أنه قد يتم تحميل عامل التشغيل بشكل زائد لنوع الإرجاع الخاص بوظيفة blah() (التي لم يتم تحديدها)، مما يجعل النتيجة غير واضحة.

نصائح أخرى

إذا لم يتم تحميل عامل الفاصلة بشكل زائد، فسيكون الكود مشابهًا لما يلي:

blah();
if (5) {
  // do something
}

إذا تم تحميل عامل الفاصلة بشكل زائد، فستعتمد النتيجة على تلك الوظيفة.

#include <iostream>
#include <string>

using namespace std;

string blah()
{
    return "blah";
}

bool operator,(const string& key, const int& val) {
    return false;
}

int main (int argc, char * const argv[]) {

    if (blah(), 5) {
        cout << "if block";
    } else {
        cout << "else block";
    }

    return 0;
}

(تم تحريره لإظهار سيناريو التحميل الزائد لمشغل الفاصلة.شكرًا لديفيد بيير لتعليقه على هذا)

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

وفي الحالة المرضية يعتمد الأمر على ما يفعله عامل الفاصلة...

class PlaceHolder
{
};

PlaceHolder Blah() { return PlaceHolder(); }

bool operator,(PlaceHolder, int) { return false; }

if (Blah(), 5)
{
    cout << "This will never run.";
}

أود أن أقول أن هذا يعتمد على بلاه ().

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

لذا، إذا كان لديك (foo(),bar()) فسيتم تنفيذ كلتا الوظيفتين، ولكن سيتم تقييم قيمة التعبير إلى bar() (ونوع التعبير أيضًا).

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

مثال:لدي ماكرو (لا أناقش ما إذا كان يجب عليك استخدام وحدات الماكرو أم لا، أحيانًا لا تكون أنت من كتبها)

FIND_SOMETHING(X) (x>2) ؟find_fruits(x):find_houses(x)

وعادةً ما أستخدمه في مهام مثل my_possession = FIND_SOMETHING(34);

أريد الآن إضافة سجل إليه لأغراض تصحيح الأخطاء ولكن لا يمكنني تغيير وظائف البحث.بإمكاني عمل :

FIND_SOMETHING(X) (x>2)؟(LOG("أبحث عن الفواكه"),find_fruits(x)):(LOG("أبحث عن منازل"),find_houses(x))

أستخدم أحيانًا بنيات مثل هذه لأغراض تصحيح الأخطاء.عندما أجبر if على أن يكون قريبًا صحيحًا بغض النظر عن القيمة المرجعة لـ blah.من الواضح أنه لا ينبغي أن يظهر أبدًا في كود الإنتاج.

تمت كتابة ما يلي على افتراض أنه كود C، إما في ملف C أو ضمن كتلة C من ملف C++:

إنه أمر لا طائل منه لو.سيتم استدعاء blah()، ولكن نتيجة blah() لن يتم أخذها في الاعتبار لو على الاطلاق.الشيء الوحيد الذي يتم أخذه في الاعتبار هو 5، وبالتالي سيتم تقييم if دائمًا على أنه صحيح.IOW يمكنك كتابة هذا الرمز كـ

blah();
// do something

دون أي لو على الاطلاق.

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