c++ - تعريفات غريبة من وحدات الماكرو TRUE و FALSE




macros boolean (4)

لقد رأيت تعريفات الماكرو التالية في كتاب الترميز.

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

لم يكن هناك تفسير هناك.

يرجى توضيح لي كيف ستعمل هذه كـ TRUE و FALSE .


أجاب Jay بالفعل لماذا قيم هذه التعبيرات هي 0 و 1 .

من أجل التاريخ ، تأتي هذه التعبيرات '/'/'/' و '-'-'-' من واحدة من إدخالات المسابقة الدولية الأولى للشفرة C في عام 1984 :

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

(رابط إلى البرنامج here ، هناك تلميح لما يقوم به هذا البرنامج في صفحة IOCCC أعلاه).

وأيضًا إذا كنت أتذكر بشكل صحيح ، تمت تغطية هذه التعبيرات بشكل صحيح مثل وحدات ماكرو مبهمة لـ TRUE و FALSE في كتاب "Obfuscated C and Mysteries" من تأليف Don Libes (1993).


إنها مجرد طريقة أخرى للكتابة

#define TRUE 1
#define FALSE 0

التعبير '/'/'/' سوف يقسم قيمة char على '/' حد ذاته ، والتي ستمنح 1 نتيجة لذلك.

'-'-'-' التعبير '-'-'-' قيمة char الخاصة بـ '-' من نفسها ، والتي ستمنح 0 نتيجة لذلك.

define الأقواس حول الكل تعبيرات مفقودة ، مما قد يؤدي إلى أخطاء في التعليمات البرمجية باستخدام وحدات الماكرو هذه. الجواب جاي يعالج ذلك بشكل جيد.

مثال على سيناريو "الحياة الحقيقية" حيث يمكن أن يكون نسيان الأقواس الضارة ضررًا هو الاستخدام المشترك لهذه وحدات الماكرو مع عامل تشغيل من النوع C. إذا قرر شخص ما إرسال هذه التعبيرات إلى bool في C ++ على سبيل المثال:

#include <iostream>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
    std::cout << "True: " << (bool) TRUE << std::endl;
    std::cout << "False: " << (bool) FALSE << std::endl;
    return 0;
}

إليك ما نحصل عليه:

True: 0
False: -44

لذلك (bool) TRUE ستقيم في الواقع إلى false ، و (bool) FALSE ستقيم إلى true .


دعنا نبدأ مع صحيح. يمكنك قراءتها كـ '/' / '/' ، مما يعني "الحرف" / 'مقسومًا على الحرف' / '". نظرًا لأن كل حرف ، في C ، يمثل قيمة رقمية (على بايت واحد) ، يمكن قراءتها على أنها "قيمة ASCII للشخصية / / مقسومة على قيمة ASCII الخاصة بنفس الحرف" ، وهذا يعني 1 (لأنه ، من الواضح ، س / س هو 1). وبالتالي ، TRUE هي 1.

بالنسبة إلى FALSE ، لها نفس المنطق: '-'-'-' يقرأ '-' - '-' ، أي "قيمة ASCII لـ '-' ناقص قيمة ASCII من '-' ، والتي هي 0. وبالتالي ، FALSE هو 0.

هذه طريقة سيئة لتوضيح ما هو واضح.


دعونا نرى: '/' / '/' تعني char الحرفي / ، مقسومة على الحرفي الحرفي '/' نفسه. والنتيجة هي واحدة ، والتي تبدو معقولة ل TRUE .

و '-' - '-' تعني char '-' ، مطروحة من نفسها. هذا هو صفر ( FALSE ).

هناك مشكلتان في هذا: أولاً ، إنه غير قابل للقراءة. باستخدام 1 و 0 هو أفضل تماما. كما أشار TartanLlama و KerrekSB ، إذا كنت ستستخدم هذا التعريف من قبل ، فيرجى إضافة أقواس من حولهم حتى لا يكون لديك أي مفاجآت:

#include <stdio.h>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
        printf ("%d\n", 2 * FALSE);
        return 0;
}

سيؤدي هذا إلى طباعة قيمة char '-' (45 على نظامي).

مع الأقواس:

#define TRUE  ('/'/'/')
#define FALSE ('-'-'-')

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





obfuscation