itoa関数の再帰版の実装
K&R本 演習4-12
再帰を使って変換ですか。面白そうですね。
#include <stdio.h> void myitoa (int n,char *s) { if(n){ int i = 0; int l = n; while(l/=10){ i++; } myitoa(n/10,s); s[i] = n % 10 + '0'; s[i+1] = '\0'; } } int main (void) { char str[100]; int n = 456; myitoa(n,str); printf("%s",str); }
こんなに短いコードなのに1時間以上格闘してましたorz
何度も考えて書き直した結果、まず最初にnの桁数をiに取得しておいて、そのiの部分から代入していくようにしました。
代入はmyitoa関数を再帰呼び出しするよりも後にするのがポイントです。
何故なら先に代入してしまうと、代入が全て終了した時点でsの位置が0要素目になってしまうからです。
つまり、\0を代入するタイミングがなくなってしまうということです。
わかりやすいようにprintfを入れてみます。
void myitoa (int n,char *s) { if(n){ int i = 0; int l = n; while(l/=10){ i++; } myitoa(n/10,s); s[i] = n % 10 + '0'; s[i+1] = '\0'; printf("i=%d s=%s\n",i,s); } }
$ main i=0 s=4\0 i=1 s=45\0 i=2 s=456\0
こうなります。要素を追加しつつ追いかけるように\0を代入できます。
しかし、これがもし逆だったら
void myitoa (int n,char *s) { if(n){ int i = 0; int l = n; while(l/=10){ i++; } s[i] = n % 10 + '0'; s[i+1] = '\0'; printf("i=%d s=%s\n",i,s); myitoa(n/10,s); } }
$ main i=2 s=ト06\0 i=1 s=ト5\0 i=0 s=4\0
こうなるので、\0の代入によって上書きされてしまい、うまくいかないのです。
といった感じであれこれやってたら1時間以上もかかってしまったというわけなのです。しくしく。
でも色々と勉強になったので良しとします。