セミコロンは重要
printf()やretrnの右側には,セミコロン(;)を付ける必要があります。
printf()自体は関数(関数呼び出しを行う式)ですが,これにセミコロン付けることによって,ひとつの文(ステートメント)となります。returnは制御文のひとつですが,同様にセミコロン付けることによってひとつの文となります。このように,C言語のプログラムは,基本的に文の並びとして記述されます。
図2.9 セミコロンを付けると文になる
printf() ← 関数呼び出しを行う式
return ← 制御文
printf(); ← 文(式文)
return; ← 文(return文)
C言語のプログラムでは,セミコロンを付け忘れたためにコンパイル時にエラーが発生したということがしばしば起こります。C言語のプログラムは,後述のとおりフリーフォーマットとなっていて行単位の概念がないため,たとえばprintf()のあとのセミコロンが抜けていると,Cコンパイラはさらに次の行まで何らかの式が続いているものと解釈してコンパイルを行おうとしてしまいます。
セミコロンを忘れた場合のコンパイラのエラーメッセージは,セミコロンとはかけ離れた不可解なメッセージになるのが普通です。そのような場合は,エラーが出た行よりも前の行に,セミコロンを付け忘れている文がないかどうかチェックするとよいでしょう。
図2.10の実行例は,hello.cの中のprintf()の右のセミコロンを付け忘れた場合のエラーメッセージです。このように,エラーはprintf()の行ではなく,次の行のreturnの直前で構文解析上のエラーとして表示されます。
図2.10 セミコロン(;)を付け忘れたhello.cのコンパイルエラー
$ gcc hello.c
hello.c: In function `main':
hello.c:7: parse error before `return'
$
複文の{ }について
複数の文を{ }で囲ってひとつの複文(ブロック)とすることができます。この複文は,後述のif文やfor文などの中でおもに使用されます。複文はそれ自体が文なので,{ }のあとにさらにセミコロンを付ける必要はありません。
「#include」とは
hello.c(第3回のリスト2.1参照)の1行目に書いてある#include <stdio.h>というのは,printf()などの関数の定義が書かれたstdio.hというヘッダファイルを読み込むという意味です。プログラム中でprintf()を使うには,あらかじめ「#include <stdio.h>」と書いてprintf()関数を定義する必要があります。なお,ヘッダファイルは,stdio.hのように拡張子を「.h」にします。
この「#include」は,実は後述のプリプロセッサに対する指令です。プリプロセッサの指令は,必ず行の左端に「#」を書く必要があります。hello.cのように1行目に「#include <stdio.h>」と書くと,この位置にstdio.hという別のファイルが読み込まれます。コンパイラはstdio.hが読み込まれた状態のhello.cをコンパイルします。つまり,hello.cをコンパイルすると,実はhello.cだけでなく,stdio.hというファイルも含めてコンパイルしていたのです。
stdio.hは,システムによってあらかじめ用意されたヘッダファイルのひとつです。本来,printf()という関数を使うには,まずその関数を定義しなければなりません。しかし,その関数の定義を毎回書いていたのでは不便です。そこで,システム側ですでにprintf()などの関数の定義が書かれているstdio.hというファイルを用意しておき,プログラマ側では単に「#include <stdio.h>」と書くだけでよいという仕組みになっているのです。
stdio.hは,実際には/usr/include/stdio.hという場所に存在します。「#include <stdio.h>」のようにファイル名を< >で囲んで書くと,/usr/includeというディレクトリからファイルが読み込まれるのです。実際に/usr/includeディレクトリをlsコマンドで見てみると,そこにはstdio.hだけでなく多数のヘッダファイルがあることがわかります。
自分で作れるヘッダファイル
ヘッダファイルは自分で書いて用意することもできます。自分が書いたヘッダファイルを読み込ませるには,
#include "my_header.h"
のように,ファイル名を< >ではなく" "で囲みます。" "で囲んだ場合は,ヘッダファイルはカレントディレクトリから読み込まれ,この場合はカレントディレクトリにあるmy_header.hというファイルが読み込まれることになります。
#include <stdio.h> ← /usr/include/stdio.hが読み込まれる
#include "my_header.h" ← ./my_header.hが読み込まれる

