C言語超入門(?)第二回

前回の復習と今回の概要

  1. C言語のプログラムはmain関数から始まる。
  2. C言語はreturnという指示で関数を終了する。
  3. C言語のプログラムは(最初に実行した)main関数の終了とともに終了する。

今日はC言語の型と関数について。
型というのは「もの」の種類。
関数というのは「指示」の集まりとその「結果」を出すもの*1
ちなみに正しくない用語を使い続けるのもいやなので、これ以降「指示」ではなくて「命令」と呼ぶ。気になる場合はがんばって置き換えてほしい。
というわけで、今日の講座を始める。

「もの」には種類がある。文字とか、整数とか、小数とか。
これが大きく見たときの「型」である。
今回は、この中で「文字」と「整数」の「型」について。
これから、それぞれ「文字型」と「整数型」と呼ぶことにしよう。


C言語には「元々決まっている」型があり、文字型も整数型も元々決まっている型である。
そして当然、型を表現する名前がある。名前がないと指定も何もできないし。
文字型はchar、整数型はintという名前である。
それぞれ、英語のcharacter(文字)とinteger(整数)の頭の3〜4文字をとったもの。


整数型の「もの」といったら、そう考えなくても思いつくだろう。0とか1とか-1とか。ちなみに、1.0は整数ではない*2
じゃあ文字型は?というと、'a'とか'b'とか書いたりする。それぞれaという文字、bという文字を表す。ちなみに、'ab'は文字ではない。
文字型は常に1文字。そして'で囲んだものは必ず文字型だと認識されるので、'ab'は根本的にC言語として正しくない*3
実は、C言語では文字型は小さな整数の集まりである。文字と整数が対応していて、'a'は97、'A'は65である。


最後にちょっとだけ文字「列」型について。
列、というだけあって、これは期待通り複数の文字を入れられる。"abc"とか、"Hello World!"とか*4、"で囲んだもの、である。
なお、こちらは一文字でもいいし、空っぽでもいい。"a"とか、""となる。
これが「実際にどういうものなのか」はだいぶ先になる。今は「こういう書き方ができて、これが文字列型である」ということだけ覚えておいてほしい。

関数の定義

さて、前回書いた何もしないプログラムをもう一度見てみよう。

int main() { return 0; }

intというのが最初に書かれていることがわかる。ついさっきいったとおり、intは整数型を表す。
だから、main関数はintとなにか関係があることは何となく見えてくるだろう。
このintというのは、returnという命令に付け加える「もの」の種類を表している。
今回の場合、return 0なので、0が整数である、といっていることになる。確かに整数だ。
ちなみに、return 0;をreturn;に書き換えると文句を言われる。


では、関数の定義の書き方を。

型 関数の名前(引数) { したいこと }

この中でわからないのは引数(ひきすう、と読む)だろう。したいこと?まだ命令を、return以外説明してないし、いらないだろう。
というわけで、引数の説明。

引数

関数には、その内容を実行するときに「もの」を渡すことができる。
引数とは、関数に「渡すもの」のこと。
だが、関数の側から「渡されるもの」はわからない。そこで、関数の側には「仮に渡されたものがあるとして、こういう名前で扱う」というものを書く。
したがって、単に「引数」というのではなく、正式には「仮引数*5」と呼ぶ。


で、この仮引数だが、実際の書き方は、「渡されるもの」の型と、扱う際の名前を書く。例えば、int(整数)であるxとか、char(文字)であるcとか。
こういった並びを、型と名前をひとまとめとして、コンマ区切りで書く。例えばint x, char cとか。これが上の「引数」と書いた場所に入るものである。
というわけで、int(整数)を一つだけ受け取る関数fというものを宣言しよう。せっかくなので、returnに書けるものもint(整数)にしよう。

int f(int x) { return x; }

今度は謎がもう一つ、returnにxがついている。
このxは何か、というと引数のところにあるxである。
xは「渡されたもの」を扱うための名前なので、return命令が実行されるときはxが実際に「渡されたもの」に置き換わる。


ちなみに、仮引数は「受け取れるもの」であり、同時に「受け取らなければならないもの」でもある*6
もし仮引数と、実際の引数(つまり関数を実行しようとしたときに渡してるもの)の数や種類が合っていない場合はやはり文句を言われる。


ここまで来たら、関数の利用も目前。あとは「どうやって関数を渡すか」と「returnにくっつけるものは何か」が問題である。

関数の実行

せっかく書いた関数である。使わなければ意味はない。
プログラムを書くとき、「自分が使うといっていないものは使われない」ということを忘れないように。
関数を実行する(一般には呼びだすと言う)には、次の書き方をする。

関数の名前(渡したいもの)

この「渡したいもの」が本来の「引数」である。上の仮引数と明確に区別するために、実際の引数だから「実引数*7」と呼ぶ。*8
とはいえ、書くものは別に変わったものもない。例えば、f(1)とか、main()とか書けばいいわけである。
というわけで、最初の頃よりmain関数の内容を増やそう。

int f(int x) { return x; }


int main() { f(1); return 0; }

;(セミコロン)は命令の末尾を表す。よって、f(1);で「fという関数を呼び出す。実引数は1である。」という命令が書かれていることになる。
この関数の呼び出しは、fという名前の関数の中でreturn命令が実行されたときのものと置き換えられる。
今回の場合、fではreturn x;となっているので、xと置き換えられるのだが、xは仮引数として書かれているので、実引数1と置き換えられる。
残ったのはreturn 1;である。よってfの呼び出しは1と置き換えられる。
つまり、直感的には次のプログラムと同じことをやっているようなものである。

int main() { 1; return 0; }

はて、1という命令とはなんぞや?と聞かれるかもしれない。
C言語では、(ある意味悲しいことに)命令としてただの「もの」を書いた場合、何もしないで次の命令に進む。
なお、return命令以外では、命令が終了したら次の命令に進むことになっているので、今回の場合1という命令(?)を終えて、return命令に進む。
つまりこのプログラムは、相変わらず何もしないプログラムというわけである。
なんて悲しい・・・

補足・整数の加減乗除

C言語の整数は足し算やかけ算といった簡単な計算ができる。
例えば1+1という計算もできる。当然これは2になる。
かけ算と割り算に関しては通常の文字が半角文字にないので、*(アスタリスク)と/(スラッシュ)を用いて表現する。
2*2は2×2のことで、2/2は2÷2のことである。
引数もこの中に入れることができる。x-1とか。上のfとmain関数内での呼び出しを例にすると、fの呼び出しでの実引数は1なので、xは1。よってfの中でx-1は0になる。
まあ、書ける、と知っていれば、内容は不思議でも何でもないことなので、特にこれ以上の説明はしない。
ちなみに、割り算は整数の中で終わるので、余りがあったら捨てられる。10/3は3であって3.333333...ではない(整数ではないから)。

まとめ

  1. 型とは「もの」の種類のこと。今回はint(整数)とchar(文字)について。
  2. 関数の呼び出しは関数に書かれた命令を実行して、最後にreturnに書かれた「もの」と置き換えられる。
  3. 仮引数は関数が受け取ることのできるもののリストで、それぞれに名前がつけられている。
  4. 仮引数にある名前は、指定した型の「もの」と同じ扱いができる。
  5. 関数に渡すものを実引数という。仮引数は、実引数の内容と置き換えられる。
  6. ただの「もの」しかない命令は何もしないのと同じ。
  7. おまけ:整数は加減乗除が実行できる。

次回予告

次回は「C言語で既に作られている関数」の使い方を説明する。
これでようやく文字が出せる。Hello World!まであと一日。
ただし明日私が書くかは不明なのであしからず。

最後に

今回の説明は、通常C言語に用いられない。
仮引数における名前xが実引数1と「置き換えられる」とはあまり言わないためだ。
これに関しては・・・次の次くらいで話をする予定。多分。

*1:C言語では区別しないのだが、「指示の集まりだけのもの」と「結果を出すもの」を区別する言語もある。その場合、前者を手続き、後者を関数と呼ぶ。

*2:1.0は小数。確かに数字としては1と全く同じものなのだが、プログラミング言語では1.0と1をはっきり区別する。

*3:もっとも、最初の頃は時々間違える。

*4:Hello World!というのはよくC言語の入門書で見かける。だが、私の講座では次回まで出てこない。

*5:英語だとparameter。

*6:そうでないと名前だけが残って、非常に困る。

*7:英語ではargument。

*8:明確に区別する場合は確かに仮引数・実引数と呼ぶのだが、実際はどちらも引数と呼ぶことが多い。