コーディングブックで次のマクロ定義を見ました。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
そこには説明がありませんでした。
これらのように動作するか私に説明してくださいTRUE
とFALSE
。
コーディングブックで次のマクロ定義を見ました。
#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 ('-'-'-')
真理値を整数で乗算することはあまり意味がありませんが、プログラムは正しく0を出力しますが、これは、マクロを括弧で囲まない場合に噛み付く可能性のある予期しないバグの例にすぎません。
if
を乗算する代わりにを使用する方が明確です(概念的には意味があります)TRUE
。
notx = TRUE- x;
、正常に機能します。それ以外TRUE-FALSE
は-44(ASCIIを想定)
それはただの書き方のひとつです
#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
ます。
書くことと同じ
#define TRUE 1
#define FALSE 0
式が'/'/'/'
実際に行うことは、文字/
(その数値が何であれ)をそれ自体で除算することなので、になり1
ます。
同様に、式はそれ自体から'-'-'-'
文字-
を減算し、に評価され0
ます。
書くほうがいい
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
他の優先順位の高い演算子と併用した場合に値が誤って変更されるのを防ぐため。
ジェイは、すでにこれらの式の値は、なぜ答えた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およびその他の謎」ドン・リブス(1993)による著書。
この陽気のためのマクロを記述するための方法True
とFalse
。
多くの説明が提供されているように/
(ASCIIの通り)1つのバイトの数を意味し、それ自体で割ったとき、それはあなたを与える1
ように治療されるTrue
と同様に -
、それはあなたを与える同じ値を減算するとき再びバイト数である0
と解釈されますfalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
したがって、我々は交換することができます/
または-
たとえば、私たちが好きな文字で:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
元の表現と同じ意味を保ちます。
真から始めましょう。'/' / '/'
これは、「文字 '/'を文字 '/'で割ったもの」と読むことができます。Cの各文字は数値(1バイト)であるため、「文字 '/'のASCII値を同じ文字のASCII値で割ったもの」として読み取ることができます。これは、1を意味します(明らかに、 x / xは1)です。したがって、TRUE
1です。
以下のためにFALSE
その同じ論法、:'-'-'-'
読み込み'-' - '-'
、すなわち「『 - 』マイナスのASCII値『 - 』のASCII値」、したがって0で、FALSE
0です。
これは明白なことを述べるための厄介な方法です。
'/'/'/'
図1は、のためにある任意のかどうか、有効な文字セット'/' == 47
(それがASCIIであるとして)、または'/' == 97
(それがEBCDICであるとして)、または他の値。
'/'
し0
。その値はヌル文字用に予約されています。