わからないこと 2 点 ならびに ちょっと脳裏の片隅に残った 2 点

先日から読んでいる プログラミング言語 C 第 2 版 ANSI 規格準拠 (B. W. カーニハン / D. M. リッチー著 石田晴久共立出版 1989 ISBN978-4-320-02692-6) は、「データ型・演算子・式」、「制御の流れ」、「関数とプログラム構造」 の各章を読み、きょうは第 5 章 「ポインタと配列」 に差し掛かりました。

実は、いくつか意味不明な部分があって、どうしようかちょっと迷うこともあるのですが、とりあえずはどんどん先に進んでいます。 とはいえ、あとで振り返って考え直すときのために、2 点だけ書き残しておこうと思います。

よくわからない箇所

同書 pp. 43-44 の 「2.1 変数名」 という節には、次のような記述があります。

内部名では、少なくとも最初の 31 文字が意味をもつ。 関数名や外部変数名については、字数は 31 より少なくするほうがいいこともある。 なぜなら、外部名は、C 言語ではコントロールの及ばないアセンブラやローダでも使われるからである。 外部名は、標準規格では 6 文字、しかも大文字と小文字の区別をしない範囲でしか一義性が保証されていない。

内部名および外部名が何を意味するのかが事前に語られずに、唐突にこういう説明をされても、ちょっとよくわかりません。 外部変数名と外部名の違いもよくわかりません。 とりあえず、何か問題が生じたときに思い出すことにしようかなと思っています。

もうひとつ書き残しておきたい事柄は、第 4 章 「関数とプログラム構造」 にあります。 この章は、ヘッダ・ファイル、宣言と定義の区別、変数の 「通用」 範囲、マクロ、などなど、非常に短い文字数でちょろちょろっと解説されるだけでは理解しづらい話題が豊富にありました。 そんな状態なので、マクロに関しては、たとえば同書 p. 109 に掲載された次のステートメントがなぜ間違いなのか、まだ理解することができていません。

#define square(x) x * x

実際に、次のようなコードを書いてみたとします。

#include <stdio.h>

#define square(x) x * x

main()
{
  int a = 1, b = 2, c = 3;
  printf("%d\n", square(a + b + c));
}

これを実行して出力されるのは、36 ではなく 11 です。 なぜなのか、よくわかりません。

「制御の流れ」 ほか

ところで、第 3 章 「制御の流れ」 では、C 言語って Java と違うんだなあと感心する細かな点がいくつかありました。 そのうち、ふたつだけここに書きとめておきたいと思います。

ひとつは、C 言語では真偽判定が 10 で表現される点です。 Java であれば true (真の場合) または false (偽の場合) ですが、C 言語ではそれらが 1 または 0 という整数値になります。 if 文も for 文も while 文も、条件判定式の値が 1 であれば真であるとみなし、0 であれば偽であるとみなします。 (厳密には、0 以外の値は 1 と同様に真であるとみなされます。) 考えてみれば、本当はそのほうが素直なのかもしれません。 不思議と、腑に落ちる思いがします。 おそらく、C 言語は、Java に比べたら、それだけ古く、それだけ機械語に近い存在なのでしょうね。

ここで、幼少の頃、父が買って来た 8 ビットパソコンに市販のゲームソフトがまったく存在しないことに悔しさを覚え、無謀にも機械語 (たしかモトローラ 6809 だったかな) を独学して自前でゲームを製作しようとしていた頃を、感慨深く思い出してしまいました。 両親は、わたしが理系的なるものに関心を持つことに非常な危惧を抱き、それを察したわたしはそれ以来ずっと文系で過ごしてきました。 いまごろ、25 年ぶりに、幼少の頃にありえたかもしれないもうひとつの選択肢の入り口に戻ってきたような、そんな感慨深さを覚えます。

もうひとつは、コンマ演算子についてです。 Java でも、for 文の中ではコンマ演算子っぽい記述ができたりすることは、実はこのたびはじめて知りました。 ただ、あまり多用する動機もないし、あまり多用してもソースコードが読みづらくなるのではないかという気もします。 でも、ただちには使い道が思いつかないまでも、もしや、何かのきっかけで、コンマ演算子を使うことがベストな選択だ、というような場面に遭遇したら、きっと自分は感動するのだろうな、とも思います。 その程度には感心したのがコンマ演算子の話題でした。

まとめ

以上です。 おしまい