私はコーディングブックで次のマクロ定義を見てきました。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
そこには説明がありませんでした。
これらがTRUE
およびFALSE
としてどのように機能するかを説明してください。
見てみましょう:'/' / '/'
は、char
リテラル/
を、char
リテラル'/'
自体で割ったものを意味します。結果は1つで、TRUE
にとって妥当なように思えます。
_'-' - '-'
は、char
リテラル'-'
を意味し、それ自体から減算されます。これはゼロ(FALSE
)です。
これには2つの問題があります。1つ目は、読み取り不能です。 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 ('-'-'-')
真理値に整数を掛けるのはあまり意味がありませんが、プログラムは正しくゼロを出力しますが、マクロを括弧に入れない場合に噛みつく可能性のある予期しないバグの例にすぎません。
それはただの別の書き方です
#define TRUE 1
#define FALSE 0
式'/'/'/'
は、'/'
のchar値をそれ自体で除算し、結果として1を返します。
式'-'-'-'
は、'-'
のchar値をそれ自体から減算し、結果として0を返します。
ただし、define
式全体を囲む括弧が欠落しているため、これらのマクロを使用するコードでエラーが発生する可能性があります。 ジェイの答え それはかなりうまくいきます。
ブラケットを忘れると有害になる可能性がある「実際の」シナリオの例は、これらのマクロをCスタイルのキャスト演算子と組み合わせて使用することです。たとえば、C++でこれらの式をbool
にキャストすることにした場合:
#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 ('-'-'-')
他の優先順位の高い演算子と一緒に使用した場合に、値が誤って変更されるのを防ぎます。
Jay これらの式の値が0
と1
である理由はすでに答えています。
歴史のために、これらの式'/'/'/'
および'-'-'-'
は、 1984年の第1回国際難読化Cコードコンテスト :のエントリのいずれかに由来します。
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
の難読化されたマクロとしてのこれらの式が "難読化されたCおよびその他のミステリー" Don Libes(1993)でカバーされていることも覚えています。
真から始めましょう。これは'/' / '/'
として読むことができます。これは「文字 '/'を文字 '/'で割ったもの」を意味します。 Cの各文字は数値(1バイト)であるため、「_ '<'> 'のASCIIの値をASCIIの値で割った値」として読み取ることができます。同じ文字」、つまり1を意味します(明らかに、x/xは1であるため)。したがって、TRUE
は1です。
FALSE
の場合、同じ理由:'-'-'-'
は'-' - '-'
を読み取ります。つまり、「-'のASCII値から'-'のASCII値を引いた' 0 'です。したがって、FALSE
0です。
これは明白なことを述べる厄介な方法です。