بسم الله الرحمن الرحيم
فى العديد من الأحيان تحتاج لعمل Infinite Loop على كود معين و فى هذه الحاله يتم استخدام while(true) على هذا الكود و هذه الطريقه قد تجدها عمليه جدا حيث سيتاح لك استخدام الكلمات المحجوزه continue و break. و لكن توجد طريقه يمكنك اعتبارها اسرع من while فى هذه الحاله فقط و هى استخدام goto كالتالى
START:
{
// code
// code
// code
}
goto START;قد يقول البعض ماذا يحدث اذا اردت الخروج من هذه الحلقه؟
فى هذه الحاله ستحتاج لتعريف Label بعد goto الموجوده فى اخر الـ block ثم نقوم بعمل jump إلى هذا الـ label لإنهاء الحلقه، سيصبح الكود بالشكل التالى:
START:
{
// code
goto AFTER; // break the infinite loop
// code
}
goto START;
AFTER:ايضا ماذا اذا اردت ان تقوم بتخطى الحلقه الحاليه فقط دون انهاء الحلقه نفسها فى هذه الحاله ستقوم بتعريف label عند goto فى اخر الحلقه و سنقوم بعمل jump إليه، سيصبح الكود كالتالى:
START:
{
goto INPLACE;
// code
goto AFTER; // break the infinite loop
// code
}
INPLACE: goto START;
AFTER:قد تقول ان الأمر حتى الأن جيد و لكنى لن اقوم بعمل Labels بهذا الشكل البشع لإنه سيجعل البرنامج صعب التتبع. كلامك صحيح لذا وجدت الماكرو، انظر معى الكود التالى
#define BEGIN_INF(KEY) BEGIN_##KEY: #define END_INF(KEY) END_##KEY: goto BEGIN_##KEY; BEYOND_##KEY:; #define CONTINUE_INF(KEY) goto END_##KEY; #define BREAK_INF(KEY) goto BEYOND_##KEY;
هذه الماكرو ستقوم بإستخدامها و هى عوضا عنك ستقوم بعمل الـ labels و ايضا ستجعل الكود منظم و منسق:
BEGIN_INF(TEST)
{
// code
CONTINUE_INF(TEST);
// code
BREAK_INF(TEST);
}
END_INF(TEST)الكلمه TEST تمثل Key او تعريف لهذا الـ block حتى يتم استخدامه لعمل الـ labels و BEGIN_INF و END_INF تستخدم لتحديد بداية و نهاية الجزء الذى سيتم عمل Loop عليه و CONTINUE_INF تقوم بتخطى هذه الدوره من الحلقه للتى تليها و BREAK_INF تقوم بالخروج نهائيا من الحلقه، الأقواس اختياريه و قد قمت بكتابتها فقط حتى تجعل الصوره مألوفه على ما اعتدنا عليه.
هذا مثال يقوم بطباعة كل الأرقام من 1 إلى 10 ماعدا الرقم 5 و تتم بإستخدام هذه الحلقه:
#include <stdio.h>
#define BEGIN_INF(KEY) BEGIN_##KEY:
#define END_INF(KEY) END_##KEY: goto BEGIN_##KEY; BEYOND_##KEY:;
#define CONTINUE_INF(KEY) goto END_##KEY;
#define BREAK_INF(KEY) goto BEYOND_##KEY;
void main ()
{
int i = 0;
BEGIN_INF(TEST)
{
i++;
if (i == 5) CONTINUE_INF(TEST);
if (i > 10) BREAK_INF(TEST);
printf("%d\n", i);
}
END_INF(TEST)
}و هذا نفس المثال بإستخدام while(true)
#include <stdio.h>
#define BEGIN_INF(KEY) BEGIN_##KEY:
#define END_INF(KEY) END_##KEY: goto BEGIN_##KEY; BEYOND_##KEY:;
#define CONTINUE_INF(KEY) goto END_##KEY;
#define BREAK_INF(KEY) goto BEYOND_##KEY;
int main ()
{
int i = 0;
while(true)
{
i++;
if (i == 5) continue;
if (i > 10) break;
printf("%d\n", i);
}
}ايهما اسرع فى هذه الحاله while ام ناتج الماكرو؟
بالطبع ناتج الماكرو سيكون اسرع لإنه يلغى عملية التحقق من شرط while.
و الله ولى التوفيق