if文はいらない

普通、条件分岐と言えばif文のことを指しますが、Cゴルフでは「&&」「||」「?:」で済ませてしまいます。例えば、
if(i<5)printf("%d",i);
をif文を消して書いてみると、
i<5&&printf("%d",i);
のようになります。「a&&b」はaが偽であった場合、bの操作を行わないのでif文と同じ働きをします。同様に「a||b」はaが真であった場合、bの操作を行いません。
if文を消すことでその部分を短くできるだけでなく、for文の()の中に入れたり、ブロックの{}を省略できたりするので基本的にif文は書きません。

「==」「!=」はあまり使わない

「==」「!=」の代わりに「-」を使った方が短くなることが多いです。
a==1&&b;
a!=1&&b;
は、以下のように書いた方が短くなります。
a-1||b;
a-1&&b;
int型は非0が真、0が偽と評価されるのを利用しています。ただし、論理値がひっくり返ったり式の値が変わったりするので常にこの方法で短くなるとは限りません。

三項演算子を極める

Cゴルフでは三項演算子を使いこなすことが必要になってきます。まずは基本から見ていきましょう。
a?b:c;
この式はaが真の時はbの操作を行い、偽の時はcの操作を行います。ここまでは当たり前ですね。
gcc拡張
a?:c;
これはgccの拡張機能であり、
a?a:c;
と同じことを表しています。「||」と似ていますが、式の値が異なります。
演算順序の例外
a?b=c,d:e;
演算子の優先順序を無視しているような感じがしますが、これでうまくいきます。(三項演算子は代入や順次より優先順序が高いので下のように書くのが普通。)
a?(b=c,d):e;
このコードと同じように解釈されます。このテクニックを使うと次のようなパターンで1バイト短くすることができます。
a?b:(c=d);
!a?c=d:b;
a&&(b=c);
a?b=c:0;
このように演算の優先順序を変えるためだけの括弧は外せることが多いです。次のようなパターンも括弧を外すことができます。
a||(b=c);
b=a?b:c;
括弧が出てきたら外せないか考えるというのはCゴルフの基本なので是非身につけてください。
入れ子になった三項演算子
a?b:c?d:e;
三項演算子を入れ子にするというゴルフ以外ではまず間違いなく見ないコードですがゴルフだとよく出てきます。この式は
a?b:(c?d:e);
のように解釈されるのであって
(a?b:c)?d:e;
のようには解釈されないことに気を付けてください。

本当にif文は使わないのか?

ここまでif文はCゴルフでは使わないという説明をしてきましたが、ごく稀に使う機会があります。それは代入が絡んだ時です。
if(a=b)c=d;
実はこのコード、これ以上縮まりません。試しにifを消してみると
(a=b)?c=d:0;
のように長くなってしまいます。めったに出てこない形ではありますが、代入がらみはif文の可能性があると頭の片隅に置いておきましょう。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

メンバーのみ編集できます