なんとなく気が向いた,というか,この手のプログラミングパズルにしては対応言語が多く,C言語もOKというのは珍しいな,ということで解いてみた.
お題
引用する.
標準出力に Hello World と出力するプログラムを作成して下さい。
ただし、数値、文字及び文字列リテラルを解答に含めることはできません。 Perlのqqやqw、Rubyの%Q、%q、%wなども避けたほうが評価が高くなります。 言語仕様をフル活用して下さい!
解法の定石
定石は,数値を得て,その文字コードに変換する. ASCIIコードでなくEBCDICな処理系だったらどうするの? みたいなツッコミは,とりあえず採点環境が OSX だということで無視できる.
この方針だと,1 をどのようにして得るかというのが鍵になる. 出題者の意図は,この定石通りだった. 回答者に送られた解説も引用可とのことなので,出題者の解説から引用する.
・C/C++ 初期化式を持たないグローバル変数はbssセクションに置かれます。main()が実行されるより前に0で初期化されるので、その変数をインクリメントすれば1になります。 また、xorにより0を作り出し、それをインクリメントしても1になります。 もしくは、少なくともx86/x64のgcc/clang上では、sizeof(char)は1です。
もなもな的解法
定石通りに解くのは面白く無い. 他の言語でなく GCC を選ぶからには,GCC なりの解き方で行かねば. なので,このように解いた.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
__func__
は GCC拡張のビルトインマクロ.
最終的には関数名の文字列リテラルに展開される.
しかし,cpp を通した時点ではC言語仕様の数値,文字には展開されない.セーフ.
スペース文字を関数名に含めることは(当然)できないので,一工夫.
関数名を31文字にして,__func__
の sizeof を取った.ナル文字含めて32.
これを文字として表示すればスペース文字になる.
言語仕様をフル活用して下さい!
とのことで,GCC の言語仕様を活用. LL系言語だと,シンボルを文字列に変換する機能をよく見かけるけれど,C言語でこの技法を選ぶ奴は少ない…よね.たぶん.
馬脚,もしくは,見直しは大事だよ
なお,出題者からのコメント.
なお、putchar()を使えば”%c”は回避可能です。
確かに.
そういや,学生だった頃も,最後の見直しをしないで提出して,必ず何点か引かれていたよなぁ…. こういうの,何歳になっても,治らんね.