頭の体操

軽いクイズはいい頭の体操になる。服部昌博「C言語とポインタ」(工学図書株式会社)72pに、「次の[list39]のプログラムの間違いを指摘して下さい。」というクイズが出ている。

参考 [list39 ポインタの間違った使用法] #include <string.h> void main(void) { static char *str0="Hello "; char str1[10]; printf("\x1b[2J"); scanf("%s",str1); strcat(str0,str1); printf("%s\n",str0); }

メモ
「\x1b[2J」は、MS-DOS時代にNECのPC9801などで使われていたESCコードを使ったテキスト画面消去で、今では意味はない。

ここでポインタが使われているのは「*str0」の部分だけであるが、これは「ポインタの間違った使用」ではない
これはむしろ「strcat」関数の使い方の問題だという方が適当であろう。その使い方がまちがったために、さかのぼってその原因が「*str0」にあるのではないか(実際にはその原因ではない)、ということになっただけである。

また、ここで「static」が使われている点については何のコメントもない。この例ではstaticがあるかないかで雲泥の差がある。すなわち、staticがあるからこれを実行してみると「一応は何かが」表示される(想定したものが多い)ことになる。staticがなければ何も表示されない。想定したものが表示される場合は間違いに気がつきにくいが、想定外の場合はどこかに間違いがあることがわかることになる。

さて、この解答の例として次のようなものが出ている。もっとも、これと同様の動作をさせる方法は他にもいくつかある。

参考 [list40 ポインタの正しい使い方] #include <string.h> void main(void) { static char *str0="Hello "; char str1[10]; char buffer[255],*p; p=buffer; scanf("%s",str1); strcpy(p,str0); strcat(p,str1); printf("%s\n",p); }

問題点
ここでポインタが使われているのは「*str0」と「*p」の部分だけであるが、「*str0」は上と同じく「ポインタの間違った使用」ではない。となると、「ポインタの正しい使い方」は「*p」の方であるということになる。
こういうふうに改造すると、今度はここで使われているstaticには意味はないことになる。これはあってもなかっても差はない(むしろ使わないのが普通)。

確かにこうすると正常に動作する。しかし、このクイズが「ポインタの間違った使用法」「ポインタの正しい使い方」の例として妥当なものであるかどうかはやや疑問である。
「p=buffer;」とするぐらいなら、最初から配列を使った方が単純でいいのではないかと思うからである(配列的方法)。実際にはこんな二重手間をかけることはしない(だろう)。おそらく、ポインタを使ったクイズにするために配列的方法を、わざわざポインタを使うように合わせて作り変えた。そのためにこういう不自然なものになったということだろう(推測)。

- 2018/06/25 -