Наступні макроозначення я бачив у книзі кодування.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Там ніяких пояснень не було.
Будь ласка , поясніть мені , як це буде працювати , як TRUEі FALSE.
Наступні макроозначення я бачив у книзі кодування.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Там ніяких пояснень не було.
Будь ласка , поясніть мені , як це буде працювати , як TRUEі FALSE.
Відповіді:
Подивимось: '/' / '/'означає charбуквальне /, поділене самим 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 ('-'-'-')
програма правильно виводить нуль, навіть якщо не має особливого сенсу множувати значення істини на ціле число, але це лише приклад виду несподіваних помилок, які можуть вкусити вас, якщо ви не скористаєтеся дужками макросів.
ifзамість множення TRUEна ціле число.
notx = TRUE- x;і працює чудово. Окрім того, що TRUE-FALSEце -44 (припускаючи ASCII)
Це просто інший спосіб написання
#define TRUE 1
#define FALSE 0
Вираз '/'/'/'поділить саму значенню '/', яка дасть 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.
Це рівнозначно письму
#define TRUE 1
#define FALSE 0
Те, що '/'/'/'насправді робить вираз , - це ділення персонажа /(незалежно від його числового значення) саме собою, так воно і стає 1.
Аналогічно, вираз '-'-'-'віднімає персонаж -від себе і оцінює до 0.
Краще було б написати
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
щоб уникнути випадкової зміни значень при використанні з іншими операторами більш високого пріоритету.
Джей уже відповів, чому значення цих виразів є 0і 1.
Заради історії, ці вирази '/'/'/'і '-'-'-'з одного з входжень першого Міжнародного заплутаних C Code Contest в 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);}
(Посилання на програму тут є натяком на те, що ця програма робить на сторінці IOCCC вище.)
Крім того, якщо я добре пам’ятаю ці вирази як затуманені макроси TRUEта FALSEбули також висвітлені у книзі «Замучені С та інші містерії» Дон Лібс (1993).
Це веселий спосіб для написання макросів для Trueта False.
Оскільки було надано багато пояснень, /означає 1 байт (відповідно до ASCII), коли розділиться сам по собі, він дасть вам, 1що буде трактуватися як Trueі аналогічно, -це знову число байтів, якщо відняти те саме значення, яке воно вам дасть, 0яке буде інтерпретовано якfalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
отже, ми можемо замінити /або -будь-який, який нам подобається, наприклад:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Збереже те саме значення, що й вихідний вираз.
Почнемо з істинного. Ви можете його читати як '/' / '/', що означає "символ" / "розділений на символ" / "". Оскільки кожен символ у C є числовим значенням (на один байт), його можна читати як "значення символу ASCII" / ", поділене на значення ASCII того самого символу", що означає 1 (тому що, очевидно, x / x дорівнює 1). Отже, TRUEє 1.
Бо FALSEце ж міркування: '-'-'-'читає '-' - '-', тобто "значення ASCII '-' мінус значення ASCII '-'", що дорівнює 0. Отже, FALSEдорівнює 0.
Це неприємний спосіб констатувати очевидне.
'/'/'/'дорівнює 1 для будь-якого дійсного набору символів, як '/' == 47(як це є в ASCII), або '/' == 97(як це є в EBCDIC), або будь-якого іншого значення.
'/'в 0. Це значення зарезервовано для нульового символу.