C,C++分科会テキスト01

目的

具体的なソースの書き方をやる。
関数と型が内容である

さきにまとめてしまうと、
プログラムの骨組みは関数である。
関数は値を受け取って、何かをしでかして、値を返す。
値は何についての値かを示すをもっている。
関数の宣言によって関数が受け取る値と返す値の型を示す
関数の定義が「実際に関数が何を返すのか」と「何をしでかすのか」を示す

具体的な関数の定義の仕方は次回
この回の話があまりわからない場合でも次回のテキストを読むことをお勧めします。

目次

hello, world\n
簡単なプログラムを実際に作ってみる。このあとで
大まかな流れ
基本的にソースはmainという関数をはじめとしていくつかの関数を連鎖的に呼ぶことによって成り立つ。
型と関数
関数は型のある値を受け取って、いろいろやって、型のある値を返す。
関数の宣言と定義
関数はそれを使うことを示す文が出る前に宣言しなくてはならない。関数の定義はどこに書いても良い。 関数の定義はコンパイル済みでも良い。

hello, world\n

まず、ソースの例を書こう。

/* helloworld.cppの中身 */

//関数の宣言 etc.

#include <stdio.h>

int main();

//関数の定義

int main (){
  printf("hello, world\n");
  return 0;
}
			
このソースをコンパイル(してリンクする)と、画面のコンソール部にhello, worldと表示される。

まず少し決まりを述べると、

  1. #から始まる文は終わりで必ず改行をしなくてはならない。
  2. その他は改行は自由に行え、行のはじめの空白も自由である。
  3. ;が文の終わりを告げるのでいくら改行してもいいのです。
  4. /*と*/ではさまれたところはコメントと呼ばれ、プログラム上あっても無くても同じである。つまりコンパイラによって無視される。
  5. //から改行されるまでは/*から*/と同様にコメントである。プログラムをわかりやすくするために入れるのである。
これを順序を追って理解しよう。

大まかな流れ

プログラムはいくつもの関数が骨組みとなってできている。
そして、プログラムが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をよぶ。
そして、printfが終わるとhogehogeにもどってreturn 0をして終了する。
するとhogeがreturn 0を実行して終了するので今度はmainがreturn 0を実行して終わる。
ということを行うわけです。

型と関数

さて、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というファイルを埋め込むことができる。
さていまあげた標準入出力関数だが、たくさん有る。しかもジャンルわけされていて、ジャンルごとにインクルードするファイルは違う。 まだ話が抽象的なのは関数の定義の仕方がまだだからである。 次回はいろいろ関数を定義するのにぜひとも必要な変数と演算子の話。

なぜhogeなのか気になる人はA page of HOGEへ行ってましょう。
上記のページはなくなってしまいました。ここに転載されています。