最初のコメント: この種のことは通常、IOCCCでのみ行われます。このようなコードは、自明ではないため、本番環境では使用しないでください。これについて言及する理由は、これにはパフォーマンスまたはスペースの利点があるという誤った印象を取り除くためです。コンパイルされたコードには、256 の数値を配列に直接書き込む場合と同じ (数の) バイトが含まれます。
さて、それがどのように機能するかです。もちろん再帰的に動作し、最上位の R6 で 2 つのビットを定義し、次のレベルでさらに 2 つのビットを定義します。Ok:
最初の手がかりは、興味深い 0->2->1->3 シーケンスです。「なぜ? 」と自問する必要があります。これは、構築に必要なビルディング ブロックです。2 進数の 0 1 2 3 は、00 01 10 11
それぞれを逆にすると、00 10 01 11
0 2 1 3 です。
ここで、テーブルに何をさせたいかを見てみましょう: 次のようになるはずです:
00000000 10000000 01000000 11000000
00100000 10100000 01100000 11100000
00010000 10010000 01010000 11010000
00110000 10110000 01110000 11110000 ...
インデックス 0 を 0 に、インデックス 00000001 を 10000000 に、というようにマッピングする必要があるためです。
各数値の最上位 (左端) 2 ビットに注意してください00 10 01 11
。
ここで、各数値の 2 番目の最上位 2 ビットが同じように増加することに注意してください (00 10 01 11) が、「列」についてです。
長さ 4 の行で配列を並べ替えることにした理由は、一度に 2 ビットが書き込まれ、2 ビットで 4 つのパターンを作成できることがわかったためです。
00 10 01 11
次に、テーブルの残りの数 (合計 256 エントリ) を観察し続けると、テーブルを 16 列で並べると、3 番目の 2 ビットがシーケンスを持ち、列で並べると最後の 2 ビットが見つかることがわかります。 64の。
ここで、元のマクロ展開の 16 と 64 という数字がどこから来たのかを暗黙のうちに伝えました。
それが詳細であり、一般化する:再帰の最高レベルは最下位2ビットを生成し、中間の2つのレベルはそのことを行い、最低レベルは最上位2ビットを生成します。