ما الذي يختبئ خلف المشغل الغامض "-->" في C++؟
تخيل: تدخل إلى Stack Overflow وترى سؤالاً جمع آلاف الأصوات وملايين المشاهدات. السؤال بسيط ولكنه مثير للاهتمام: "What is the '-->' operator in C/C++?". يبدو وكأنه شيء سري للغاية، أليس كذلك؟ ربما هو معيار جديد لـ C++23؟ أو بناء سحري لا يُذكر في الكتب الدراسية؟
في الواقع، هذه واحدة من أشهر نكات المبرمجين وفي نفس الوقت - فرصة ممتازة لفهم كيفية عمل المشغلات في C++ وكيف يمكن خداع عقلك بسهولة عند قراءة الكود. في هذه المقالة، سنكشف سر "المشغل -->" ونوضح كيف يساعد هذا المثال المبتدئين على فهم بناء جملة C++ على مستوى عميق.
كيف يبدو الكود الغامض؟
ها هو، المقطع الذي فجر الإنترنت:
#include <iostream>
int main() { int x = 10; while (x --> 0) { std::cout << x << " "; } return 0;}نتيجة تشغيل البرنامج:
9 8 7 6 5 4 3 2 1 0يبدو الأمر كما لو أننا نستخدم المشغل --> (إنقاص وسهم). لكن دعونا نواجه الحقيقة: لا يوجد مشغل "-->" في C++ على الإطلاق. إنه وهم ناتج عن الطريقة التي يقسم بها مترجم C++ الكود إلى رموز (tokens).
كيف "يقرأ" المترجم هذا الكود؟
يتبع مترجم C++ قاعدة أقصى استهلاك (maximum munch rule): فهو يحاول دائمًا تكوين أطول رمز (token) ممكن من الأحرف المتاحة. في التعبير x --> 0، يرى المترجم ليس -->، بل رمزين منفصلين:
- الرمز 1:
--— مشغل الإنقاص (التقليل بمقدار 1) - الرمز 2:
>— مشغل المقارنة "أكبر من"
أي، في الواقع هذا ليس x --> 0، بل x-- > 0. المسافة بين -- و > غير ضرورية - المترجم سيفهم على أي حال أنهما مشغلان مختلفان.
تحليل كامل: من البداية إلى النهاية
دعونا نحلل هذا الكود خطوة بخطوة لفهم منطق عمل البرنامج:
- يتم تهيئة المتغير
xبالقيمة 10. - يتم التحقق من شرط الحلقة:
x-- > 0. هذا هو الإنقاص البعدي: أولاً يتم أخذ القيمة الحالية لـ x (10)، ومقارنتها بـ 0 (10 > 0 - صحيح)، وبعد ذلك فقط يتم تقليل x إلى 9. - نظرًا لأن الشرط صحيح، يتم تنفيذ جسم الحلقة: يتم طباعة القيمة التي تم تقليلها بالفعل (9).
- تتكرر الحلقة حتى يصبح x مساويًا لـ 0. عندما x = 0، يكون الشرط
0 > 0خاطئًا، وتنتهي الحلقة.
لاحظ: في المخرجات نرى الأرقام من 9 إلى 0، لكننا لا نرى 10. هذا لأن الإنقاص البعدي يستخدم أولاً القيمة القديمة للمقارنة، ثم يقوم بالتقليل. بالنسبة للمبتدئ، هذا فخ شائع، لكنك الآن تعرف كيف يعمل.
لماذا هذا المثال مشهور جدًا؟
على Stack Overflow، جمع هذا السؤال أكثر من 1.5 مليون مشاهدة. لماذا؟ لأنه يوضح بشكل مثالي عدة مفاهيم مهمة في البرمجة بلغة C++:
- التحليل المعجمي — كيف يقسم المترجم الكود إلى رموز (tokens)؛
- الإنقاص البعدي مقابل الإنقاص القبلي — الفرق بين
x--و--x؛ - أولوية المشغلات — لماذا يعمل الكود بهذه الطريقة وليس بطريقة أخرى؛
- قابلية قراءة الكود — لماذا حتى الكود "العامل" يمكن أن يكون مضللاً.
كيف لا تقع في هذا الفخ في الكود الحقيقي؟
الدرس الرئيسي من هذه القصة هو اكتب الكود بحيث يسهل قراءته. لا تعتمد أبدًا على