わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

定数なしで"Hello, world!"

「先生,ちょっと聞いてもいいですか?」
  「ん? 何か」
「Cでハローワールドを出すプログラムなんですが…」
  「…」
「定数を使ってはいけない,ってルールなんですよ.あるところで話題になったんですが」
  「研究室で?」
「じゃないんです.学外です」
  「へえ,まいいや.定数ってのは…」
「数値,文字定数,文字列リテラル,こんなのはダメなんです」
  「ふむ」
「先生だったら,それで,どうやってハローワールドを出しますか?」
  「うーん,せやなあ,1文字ずつ,putcharで出力かなあ」
「1文字ずつ,ですか?」
  「1文字ずつの値を求めるには,最低限ひとつ,変数がいるね」
「変数の初期化は,どないします?」
  「んん…グローバル変数で初期化なしにすれば,ゼロになるよね」
「あ,そうですね」
  「int c;とでもしてから,mainの中でc++;とすれば,cの値は1になって」
「はい」
  「任意の回数だけインクリメントさせたら,任意の数にすることができて」
「ええ」
  「あとは'H'の文字コードにしてから,putchar(c);,2番目の文字も以下同様,としたら,いけそうやね」
「…そのとおりです.なるほど.どうもありがとうございます」
  「そんな,プログラミングのパズルかなんかが,あるんやね.面白いね」
「あ,そうだ先生,もう一つ,聞いていいですか」
  「はいはい」
「先ほど,グローバル変数とおっしゃったじゃないですか」
  「まあ,手軽やもんね」
「ローカル変数で,やっぱし定数なしで,ゼロにするにはどないします?」
  「ん?」
「僕ね,こないしたんですよ.int c;だけだったら,何が入ってるか,わからないじゃないですか」
  「まあねえ」
「それでね,そのあとにwhile(--c);って.これで,デクリメントを繰り返して,cが0になったらそこで抜けるんです」
  「…え!?」
「おかしいですか?」
  「いやあ,そんなことしなくても,c-=c;で0にならない?」
「あ,そうですねえ.そんな簡単な式で,できるんや!」

生成プログラムをRuby

ラフスケッチ

Rubyの生成プログラムを書く前に,テキストエディタで作成したファイルです.

#include <stdio.h>

int o;
int a, b, c, d, e, f, g, h;

main(void)
{
  h++;       /* 0x01 */
  g = h + h; /* 0x02 */
  f = g + g; /* 0x04 */
  e = f + f; /* 0x08 */
  d = e + e; /* 0x10 */
  c = d + d; /* 0x20 */
  b = c + c; /* 0x40 */
  a = b + b; /* 0x80 */

  /* "Hello, world!" */
  putchar(b + e);                 /* H:0x48 */
  putchar(b + c + f + h);         /* e:0x65 */
  putchar(b + c + e + f);         /* l:0x6c */
  putchar(b + c + e + f);         /* l:0x6c */
  putchar(b + c + e + f + g + h); /* o:0x6f */
  putchar(c + e + f);             /* ,:0x2c */
  putchar(c);                     /*  :0x20 */
  putchar(b + c + d + f + g + h); /* w:0x77 */
  putchar(b + c + e + f + g + h); /* o:0x6f */
  putchar(b + c + d + g);         /* r:0x72 */
  putchar(b + c + e + f);         /* l:0x6c */
  putchar(b + c + f);             /* d:0x64 */
  putchar(c + h);                 /* !:0x21 */
  puts((char *)&o); /* putchar(e + g); */
}

「Hello, world!」の16進ダンプは,「echo "Hello, world\!" | hexdump -C」というコマンドで求められます.