C言語における6つの文

手元にK&Rが無いときにはgoogleに頼るのだけれど、「C言語 文 式」あたりで検索して、上位を見ていくと相当げんなりする。用語の使い方が、全くなっていない。もっとも以前は自分だって、用語の使い方は正確ではなかったと思い当たる。そうやって、俺様用語が蔓延していくのだろう。

その中では下記のページがよくできていると思った。
http://okuyama.mt.tama.hosei.ac.jp/unix/C/index.html
今だからわかるが、上記サイトでは「文」「式」などの用語の使い方に非常に神経を使っていることがよくわかる。

さてC言語の文は以下の6つである。*1

  1. 名札付き文
  2. 式文*2
  3. 複合文*3
  4. 選択文
  5. 繰返し文
  6. 分岐文*4

さて、とりあえずこの中から名札付き文を取り上げる。文法は以下

名札付き文
    識別子:文
    case 定数式:文
    default:文

ポイントは、文の中の一種類として名札付き文の説明をしているはずなのに、そこに「文」が登場していること。要するに「再帰的に」定義されているのである。

文法が再帰構造をしていることは、初めはわかり難い原因になっていると思う。しかし、スタイルで覚えていたものの文法的意味がわかると、今までとコードが違う姿に見えてきて、それからプログラムの理解が深まったように思う。

例えば以下のコードではswitch文でbreak文を使わないfall throughを利用している。しかし、文法的にfall throughの仕組みがあるわけではない。

#include <stdio.h>

int main(int argc, char **argv)
{
	unsigned char month;
	unsigned char dayOfMonth;

	switch (month) {
	case 2:
		dayOfMonth = 28;	/* 閏年は考えない */
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		dayOfMonth = 30;
		break;
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		dayOfMonth = 31;
		break;
	default:
		fprintf(stderr, "input err\n");
		break;
	}

	return 0;
}

case 4:の文にあたるのは
case 6:
case 9:
case 11:
dayOfMonth = 30;
である。case 4のラベルがついている文が、またcase文というわけだ。そしてそのcase 6ラベルが付いている文もさらに、case文なのである。

文法上は、各caseラベルは入れ子になってるのである。しかしセマンテック上は、各caseが並列してる感覚である。であるから、入れ子を示す、インデントは通常しない。

そういうことを知っているのと、知らないのは、長い目で見ると結構な差になるように思う。

*1:JIS用語に合わせてある

*2:K&Rでは「式の文」

*3:K&Rでは「複文」

*4:K&Rでは「ジャンプ文」この分岐文は馴染み無いな。googleで検索してみると、上位はswitchに関する説明で使われている。jump statementの意で使っているサイトは上位には無かった。