#تعريف، #ifdef #undef #endif
-
05-07-2019 - |
سؤال
لدي الكود التالي
#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! والصفر المعرفة التي تحدث ifdef
s وelse
s وغيرها لتكون داخل حلقة while
.
و#define
s تعمل فقط خلال تجهيزها. لذلك
#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
}