*コンパイル [#h2c785d0]
ある言語で書かれたものを別の言語で書かれたものに変換(翻訳)することを''コンパイル''といいます。
この授業では、C言語で書かれたプログラムをコンピューターが実行可能な機械語のプログラムにコンパイルしています。
**コンパイラー [#rba646af]
コンパイルするソフトウェアのことを''コンパイラー''といいます。
この授業では、''gcc''というコンパイラーを使用しています。
gccを用いてCプログラムのファイル名だけを指定してコンパイルすると、 ''a.out'' という名前の実行形式のファイルが出力されます。
#geshi(sh){{
luna% gcc hello.c
}}
**実行形式のファイル名を指定する [#qbe406af]
gccに ''-o'' オプションを指定すると、出力される実行形式のファイルの名前を指定することができます。
#geshi(sh){{
luna% gcc -o hello hello.c
}}
**演習1 [#sd56e6f9]
画面にHello World!と出力するプログラムhello.cを作成し、実行形式のファイル名をhelloにしてコンパイルせよ。
*他のファイルに定義された関数を使う(外部結合) [#ic383494]
これまでは、すべてのプログラムが一つのファイルに記述されていました。
大規模なソフトウェアになると、機能などのまとまりごとにモジュールに分割してプログラムを作成します。
すると、他のファイルに定義されている関数を呼び出すことがあります。
このようなとき、記憶域指定子として ''extern'' をつけてプロトタイプ宣言を記述します。
#geshi(c){{
extern 戻り値の型 関数名(引数1の型 引数1の名前, 引数2の型 引数2の名前, ...);
}}
例えば、次のようなプログラムがファイル add.c に定義されているとします(プログラム1a)。
#geshi(c){{
/*
* add.c
*/
double add(double x, double y) {
return x + y;
}
}}
これを、main.c というファイルのmain関数から呼び出すときには、呼び出す前にexternを付けたプロトタイプ宣言が必要になります(プログラム1b)。
#geshi(c){{
/*
* main.c
*/
#include <stdio.h>
extern double add(double x, double y);
int main(void) {
double x = 1.0, y = 2.0;
double z = add(x, y);
printf("%f\n", z);
return 0;
}
}}
複数のファイルに分けて記述されたプログラムをコンパイルするときは、すべてのプログラムを同時に指定します。
#geshi(sh){{
luna% gcc add.c main.c
}}
これらのプログラムは、単体では実行可能なファイルにコンパイルすることができません。
#geshi(sh){{
luna% gcc add.c
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld はステータス 1 で終了しました
luna% gcc main.c
/tmp/ccUSNIu9.o: In function `main':
main.c:(.text+0x3f): undefined reference to `add'
collect2: ld はステータス 1 で終了しました
}}
**演習2 [#o7ee209c]
プログラム1a, 1bを作成し、実行結果を確認せよ。
*オブジェクト・ファイル [#xbba462f]
大規模なプログラムになると、コンパイルにかなりの時間がかかります。
一部だけに誤りがあったり、一部だけを変更したときに、すべてのプログラムをコンパイルしなおすのは、大変です。
そこで、ファイルごとにCプログラムを中間ファイルにコンパイルします。
この中間ファイルのことを''オブジェクト・ファイル''といいます。
Cプログラムをオジェクト・ファイルにコンパイルするには、gccに ''-c'' オプションを指定します。
#geshi(sh){{
luna% gcc -o add.c
luna% gcc -o main.c
luna% gcc -c add.c
luna% gcc -c main.c
}}
オブジェクト・ファイルの名前は、Cプログラム(ソース・ファイル)の名前の拡張子を ''.o'' に変えたものになります。
**演習3 [#xac1421a]
プログラム1a, 1bについて、それぞれオブジェクト・ファイルにコンパイルせよ。
*リンク [#o84f9750]
ファイルごとにオブジェクト・ファイル作成し、必要なオブジェクト・ファイルがすべて揃ったら、オブジェクト・ファイルを結合し、実行可能なファイルを作成します。
これを''リンク''といいます。
オブジェクト・ファイルをリンクして実行可能なファイルを作成するのにもgccを使います。
#geshi(sh){{
luna% gcc add.o main.o
}}
**演習4 [#y85f1933]
演習3で作成したオブジェクト・ファイルをリンクし、実行可能なファイルを作成せよ。
*まとめ [#d7dee275]
ある言語で書かれたものを別の言語で書かれたものに変換することを''コンパイル''といいます。
プログラムが複数のファイルで構成されているとき、Cプログラムをそれぞれ''オブジェクト・ファイル''にコンパイルし、オブジェクト・ファイルを''リンク''して実行可能なファイルを作成します。
他のファイルで定義されている関数を使用するときは、''extern''という記憶域指定子を指定したプロトタイプ宣言が必要です。