どうも「一つの方法を覚えてうまくいくと、その方法しか認めなくなる人」や「有限状態遷移を知らない人」がいるような気がするんで、先に言った有限状態遷移のサンプルコードを書いてみます。
動作環境が手元に無いので試験していません。バグがあっても勘弁。
「cのソースコードからコメントを除去する」というコード片です。
仕様定義やスタイルに異論がある方もいるでしょうが、それがメインテーマではないので突っ込まないで下さいね。
#define SLASH '/'
#define ASTER '*'
not_incomment:
c = getchar();
if ( c == EOF ) return;
if ( c == SLASH ) goto find_slash;
putchar( c );
goto not_incomment;
find_slash:
c = getchar();
if ( c == ASTER ) goto incomment;
putchar( SLASH );
putchar( c );
goto not_incomment;
incomment:
c = getchar();
if ( c == ASTER ) goto find_aster;
goto incomment;
find_aster:
c = getchar();
if ( c == SLASH ) goto not_incomment;
goto incomment;
(続き)これを構造化すると以下のようになりますか。
enum { not_incomment, find_slash, incomment, find_aster } state;
for (state = not_incomment;;){
c = getchar();
switch ( state ){
not_incomment:
if ( c == EOF ) return;
if ( c == SLASH )
state = find_slash;
else
putchar( c );
break;
find_slash:
if ( c == ASTER )
state = incomment;
else {
putchar( SLASH );
putchar( c );
}
break;
incomment:
if ( c == ASTER ) state = find_aster;
break;
find_aster:
if ( c == SLASH ) state = not_incomment;
break;
}
}
前者と後者はどちらがbetterかという話ですが、私は前者がbetterであると判断します。書き易さも読み易さも保守性も断然、前者が優れています。ですが、後者の方がbetterであると判断する方もいてもおかしくはないです。と、それだけのことですが。