سؤال

لدي الكود التالي

#define PROC_ADD

void main(void)
{
    while(1)
    {
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
    }
}

ومع ذلك، سيتم تشغيل التعليمات البرمجية.لكنها لن تقوم بتشغيل الكود الموجود في else بعد PROC_ADD لم يتم تحديده.

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

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

المحلول

ما تقومون به هو ما يعادل بناء وقت:

int x = 1;

int main()
{
    if (x)
    {
        ...
        x = 0;
    }
    else
    {
        ...
    }
}

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

نصائح أخرى

ويتم تقييم حالة ifdef عندما يحصل المعالج على ذلك. عند undef PROC_ADD داخل رمز ifdef'd، قررت المعالج بالفعل القسم الذي رمز لتشمل والتي لتجاهل.

وعلاوة على ذلك، نعم: تتم معالجة ifdef، undef، وما إلى ذلك في وقت ما قبل المعالجة - المترجم أبدا حتى يرى هذه التوجيهات ما يسمى. وهذا يعني بالطبع وقت التشغيل كود أبدا يرى هذه التوجيهات سواء.

تعديل : في هذا المعالج يعمل عن طريق اتخاذ مسار واحد عبر ملف نصي. والمعالج حتى لا يهمني هذا الملف النص يحدث أن تحتوي على شفرة C! والصفر المعرفة التي تحدث ifdefs وelses وغيرها لتكون داخل حلقة while.

و#defines تعمل فقط خلال تجهيزها. لذلك

#define PROC_ADD 
void main(void) 
{
#ifdef PROC_ADD 
// Do this code here then undefined it to run the code in the else 
// processing work 
#undef PROC_ADD 
#else 
// now that PROC_ADD has been undefined run this code 
// processing work 
#endif 
}

وسوف تتم معالجتها على النحو التالي: حيث يتم تعريف PROC_ADDR على المعالج سوف تستبعد تماما فرع #else ومن ثم تنفيذ #undef، وبالتالي فإن رمز الفرع #else أبدا يبقى تجهيزها ولم تصل إلى مترجم

في كل لغة برمجة أو بناء جملة تقريبًا، بمجرد دخول التنفيذ إلى فرع واحد من الشرط الشرطي (في هذه الحالة، الكائن الشرطي #ifdef, حتى لو تغير الشرط أثناء تنفيذ الفرع، فلن يتم تنفيذ الفروع الأخرى أبدًا.

أنا متأكد من أنك لا تتوقع طباعة "مرحبًا" على هذا، أليس كذلك؟

if (i == 1)
    i = 0;
else
    printf("Hello\n");

ما تقوله في الأساس هو أن الكود الموجود أسفل else يجب تنفيذ الفرع دائمًا، ثم أخرجه من الفرع، و ضعه مباشرة في الكود.

يقوم كل من المترجم والتنفيذ بإجراء تمريرة واحدة فقط من خلال الشروط الشرطية، وبمجرد العثور على تطابق، لا ينظرون إلى أبعد من ذلك.

لذلك تريد أن يمثل الكود في قسم التعليق الثاني دائماً يجري؟لماذا لا تفعل فقط

#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done

يحرر

حسنًا - إذا كنت تريد إجراء تغييرات في سلوك وقت التشغيل، فيجب عليك استخدام بنيات وقت التشغيل (مثل المتغير ليكون بمثابة علامة).كما نقول جميعًا؛)، يتم تقييم توجيهات ما قبل المعالج مرة واحدة فقط، في وقت الترجمة.

وفكروا بهذه الطريقة: لم يتم تنفيذ جزء else من التعليمات البرمجية التالية على الرغم من x تم تعيينها إلى false في قسم if.

ويتم فحص حالة في خط if(x) نفسه - عندما تدخل تلك الكتلة، فإنه لا حساب كل قسم من الأقسام else اللاحقة - جعلت مترجم بالفعل قرارا في هذا الشأن

bool x = true;
if(x)
{
  //do something
  x = false;
}
else
{
  //else code
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top