具体的なソースの書き方をやる。
関数と型が内容である
さきにまとめてしまうと、
プログラムの骨組みは関数である。
関数は値を受け取って、何かをしでかして、値を返す。
値は何についての値かを示す型をもっている。
関数の宣言によって関数が受け取る値と返す値の型を示す
関数の定義が「実際に関数が何を返すのか」と「何をしでかすのか」を示す
具体的な関数の定義の仕方は次回
この回の話があまりわからない場合でも次回のテキストを読むことをお勧めします。
まず、ソースの例を書こう。
/* helloworld.cppの中身 */ //関数の宣言 etc. #include <stdio.h> int main(); //関数の定義 int main (){ printf("hello, world\n"); return 0; }このソースをコンパイル(してリンクする)と、画面のコンソール部にhello, worldと表示される。
まず少し決まりを述べると、
プログラムはいくつもの関数が骨組みとなってできている。
そして、プログラムがOSによって呼び出されると、ここでmainと書いた関数がはじめに呼び出される。
この関数がさらにprintfという関数を呼び出す仕組みになっている。
printfという関数がやるべきこと(hello,worldを表示する)をやって終了すると、main関数のなかでprintfを呼んだところに戻ってくる。
すると、次の行へ実行が移りreturn 0をおこなう。return 0というのはこのmain関数がOSに0という値を送ってmainが終了するという意味である。
詳しくはこのあとすぐ「型と関数」のところで説明する。
関数はちゃんと呼び出しを行った元の位置に戻ってくれるので何重にも呼び出すことが可能である。
たとえば
//関数の宣言etc. #include <stdio.h> int main(); int hoge(); int hogehoge(); //関数の定義 int main (){ hoge(); return 0; } int hoge(){ hogehoge(); return 0; } int hogehoge(){ printf("hello, world\n"); return 0; }mainがhogeをよんでhogeがhogehogeをよんでhogehogeがprintfをよぶ。
さて、0を返すとか書いた。さらに、printf()の括弧の中に"hello, world\n"がはいっている。
これは関数が何かをしでかす(たとえば画面に文字を出す)ほかに数学でいう関数のように値を受け取って、値を返す事もしてくれるからである。
値を返すというのは具体的には、先ほどあげた例で言えばhogehoge()は何も問題が無ければ実行後に0という値になるということである。
次に挙げるhelloworld()という関数は実行すると"hello, world\n"という値になるのでそのままこのhelloworld()をprintf()に入れてやれば、printf("hello, world\n")とやったのと同じ事となるのだ。
//関数の宣言etc. #include <stdio.h> int main(); char* helloworld(); //関数の定義 int main (){ printf(helloworld()); return 0; } char* helloworld(){ return "hello, world\n"; }
printfに入れるなどといっていたが、それが値を受け取るということである。
受け取る値のことを「引数」(ひきすう)とよび返す値を「戻り値」とよぶ。
これを「何々を引数として何々を返す」などと表記する事が多い。
値は型を持つ。
型というのは整数型とかポインタ型とか浮動小数点数型とか文字型であり、値がどのような意味で使われるのかを示す。
たとえば'h'というのは文字の型を持つ値である。1243というのは整数の型か浮動小数点数型かその他の値である。
そして関数が受け取る値と返す値にも型が指定されている。そしてその指定がint とか char*とかである。
つまりint chartoint(char)となっていれば、char型(文字)の値を受け取ってint型(整数)の値をかえす。
helloworld()は何も受け取らずにchar*型(文字列を示す)を返すというわけである。
関数はどんな型の値を受け取ってどんな型の値を返すかを使う前に書いておかなくてはならない。それが「関数の宣言」である。
int hoge(); //関数hogeは何も受け取らずint型の値を返すという意味になる。実際どのような値を返すか、この関数が呼ばれたときに何をしでかすか(どんな関数を呼ぶかなど)は「関数の定義」でおこなう。
また、関数の定義は関数の宣言をかねるので、
//関数の宣言etc. #include <stdio.h> //関数の定義兼宣言 int hogehoge(){ printf("hello, world\n"); return 0; } int hoge(){ hogehoge(); return 0; } int main (){ hoge(); return 0; }とやることも可能。
ところでprintf関数は定義されていない。
printf関数は別のコンパイル済みのファイルで定義されている。
この関数は標準入出力関数なので、ユーザーが(ソース上で)このファイルを指定しなくてもCコンパイラーが自動的にやる。
またこの関数printf()の宣言はstdio.hという名前のファイルにかかれており、
そこにはint printf(const char*,...);とか言う形でprintf関数やその他の標準入出力関数の宣言がかいてある。
それゆえ、
#include <stdio.h>などとかくのだ。ここでまた、このファイルの書いてあるディレクトリを(ソース上で)指定する必要は無い。これもコンパイラが自動的にやってくれる。 これによってこの場所にstdio.hというファイルを埋め込むことができる。