Наступні макроозначення я бачив у книзі кодування.
#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
. Це значення зарезервовано для нульового символу.