ログイン
kid's world

C言語の文法

「コンピュータ」は日本語で「電子計算機」という。今回は計算をさせる方法と,C言語の文法について触れた後,誤ったプログラムを訂正する方法について解説する。


はじめに

おさらい

前回は,画面に「愛してる!」と表示するプログラムを作成してみた。それだけのプログラムであったが,学ぶことは多かったと思う。プログラミング言語とは何なのか,プログラマはどのようにしてプログラムを作成するのか,コンピュータはどのようにしてプログラムを実行しているのか,などに興味を持ったことだと思う。

今回のお話

今回は,前半部分で簡単に文法と計算方法について解説する。C言語では,足し算や掛け算の混ざった複雑な式を書かれても,ちゃんと掛け算を優先して解いてくれる。なんと賢いのだろう。

後半部分では,誤ったプログラムを作ってしまったときの対処法について考える。そのために,わざと誤ったプログラムを作り,エラーを起こしてみる。本来は誤ったプログラムを作ってはならないのだが,失敗例からいろいろと学習してみよう。

C言語の文法

それでは,C言語の文法の要点について簡単に解説する。キーワードは「文」と「関数」である。この2つのキーワードの意味をしっかりと頭に叩き込んでいただきたい。

C言語で書かれたプログラムには,それがある程度役に立つ処理をしてくれるプログラムであれば,必ず1つ以上の文が存在している。

たとえば,文字の表示や入力の受け付けなど,コンピュータが行う「処理」をC言語流に表したものである。日本語の文は必ず最後が「。」で終わっているように,C言語の文の終わりには必ずセミコロン「;」がついている。

printf("愛してる!\n");

この世には数え切れないほどのプログラムが存在し,さまざまな処理を行うことができるが,C言語でこれらのプログラムを作る場合はすべて「文」によって実現されているのである。たとえば,文字を表示するのに,

printf("C言語学習帳\n");

という「文」を書いた。この文は,「C言語学習帳という文字列を表示しろ」という処理を表しているのである。このように,

「コンピュータに行わせたいことを文として書く」

ということが,C言語のプログラミングの基本的な概念である。

文の実行順序

さて,文字を1回だけ表示するというのならば話は簡単なのだが,プログラムはたいていさまざまな処理を大量にこなしていくものである。また,C言語の文は日本語の文とは異なり,複雑なことを一文で表現することはできない。そこで,必ずといっていいほど,List 1のようにいくつもの文を並べて書くことになる。

List 1: 文のイメージ

ほげ;
げほっ;
ぷぴーっ;
 …

日本語とまったく同じように,C言語においても,文は最初から1つずつ順番に読むというルールがある。よってList 1のようなC言語のプログラムを書いた場合は,

「ほげ」→「げほっ」→「ぷぴーっ」…

という順番で,処理されていく。

関数

プログラムの中には必ず文が存在するということがわかった。しかし,人間,ひとりでは生きてはいけないのと同じように,文はC言語のプログラムに単独で存在することはできない。人間が地球という環境の中で生きているように,文も関数の中でのみ,その存在を許されている(ごく少数だが関数外での存在を許されているものもある)。イメージとしては,List 2のようになる。

List 2:関数のイメージ

「関数
  ほげ;
  げほっ;
  ぷぴーっ;
」

関数といわれると,数学で習った関数を思い出してしまうが,これとはまったく別物である。C言語の関数とは,基本的には,

いくつかの文を1つにまとめたかたまり

と解釈してよい。

実は,これまでに何度も登場した「printf」は関数である。printf関数内部には,カッコの中で指定された文字列を表示するための処理がたくさんの文で書かれているのだ。

文字を表示する処理はたいへんな処理なのだが,関数という形で1つにまとめることによって「プログラマが毎回のように文字を表示させる複雑な処理を書かなくても,関数を書くだけで簡単に処理できる」ようにしているのである。printf関数を使って文字を表示するときは,printf関数のコードを書いた人たちに感謝しながら使おう。

関数の実行順序

関数は,文と同じようにプログラムの中にいくつでも存在することができる(List3)。

List 3:関数の集まり

「関数1」
「関数2」
「関数3」
 …

しかし、関数は文とは違い、

「関数1」→「関数2」→「関数3」→…

という順番で実行されるわけではない。では,関数はどのようにして処理されるのだろうか。

実は,関数は「呼び出される」ことによって初めて処理される。みずからアクションを起こすことはないのである。

それでは,関数は何から呼び出されるのであろうか。答えは「文」である。文によって関数は呼び出される。たとえば,printf関数を呼び出す文は,

printf("5月号\n");

と書く。そう,この文は「printf関数を呼び出す」という意味だったのである。

main関数

だが,「関数は文から呼び出される」ということに何か矛盾を感じないだろうか? 文は関数の内部にのみ存在し,関数が呼び出されなければ実行されることはない。まさに鶏が先か卵が先かの話である。いったいどうなっているのだろうか。

C言語の場合は「関数の呼び出し」が先である。プログラムは,人間の指示やほかのプログラムによって,たいていWindowsやMac OSやUNIXといったOSを介して実行されている。そのとき,OSはそのプログラムのある特殊な名前の関数を呼び出しているのである(本当は,OSはmain関数を呼び出しているわけではない。ただ,C言語だけしかない世界を考えた場合は概念的にそうであるといってもよいし,そのほうが理解しやすいので,「OSがmain関数を呼び出している」という表現をとった。)。

その特殊な名前とは「main関数」である。どこかで見たことはないだろうか? そう,前回書いたプログラムにもすでに出ていたのである。これをもう一度だけList 4に示しておく。

List 4:Cで愛してる!

#include <stdio.h>

main()
{
  printf("愛してる!\n");
}

このように,関数は「{」で始まり,「}」で終わる。この中に文が入るわけである。

前回はチンプンカンプンだったと思うが,今回はもうList 4の意味がなんとなくわかるであろう。つまり,List 4は「printf関数を呼び出す文を含んだmain関数を作った」だけのものなのだ。OSはプログラムの実行を開始するためにmain関数を一番最初に呼び出すので,main関数の指示(この場合はprintf関数を呼び出す)によってprintf関数が「愛してる!」という文字列とともに呼び出され,画面上にその文字が表示されたのである。

Fig. 1を見て,文と関数とOSの関係を頭の中で整理していただきたい。

Fig. 1: 文と関数とOSの関係

/c/calc-fig1.png

#include <stdio.h>

List 4の1行目の「#include <stdio.h>」について説明しよう。

コンパイル作業は大まかに見ると「プリプロセッサ」と「コンパイラ」で行われ,プリプロセッサはこの「#include」という文字を見つけると指定されたファイル(つまりここでは「stdio.h」というファイル)の中身をこの位置に追加する。これをインクルードという。

stdio.hという名前のファイルは,コンパイラをインストールしたときに,どこかに作られているはずである(LSI-Cならば,INCLUDEディレクトリに入っている)。このファイルには標準的な入出力に関するさまざまな処理が書いてあり,printf関数もこのファイルの中で宣言されているのだ。したがって,printf関数を使うときはstdio.hをインクルードしなくてはならない。

つまり,これはプログラマが楽をするために作られた仕組みである。毎回必ず同じことを書かなければならないことがあるのならば,それを1つのファイルにまとめてしまい,後からこの「#include」で始まる1行を書くだけでよしとしよう,というわけである。一度,stdio.hの中身をエディタなどで見てみるとよいだろう。

このように,さまざまな関数などの宣言や定義がされているファイルをヘッダファイルといい,必要に応じて#includeによってインクルードする。

ちなみにこの「stdio」という名前は,Standard Input/Outputを略したものである。間違ってもstudio.hなどとは書かないようにしたい。


計算をさせる」へ進む

広告


©Toshio Koide 1996-2007.

目次

リンクについて

リンクは御自由にどうぞ。

メール

mail.gif

広告