200 likes | 308 Views
プログラミング演習 II. 2004 年 10 月 26 日(第 2 回) 理学部数学科・木村巌. 前回までの復習. ローカル変数 グローバル変数 変数の可視範囲 変数の寿命 static なローカル変数. 今日学ぶこと. 関数の宣言 複数のファイルからなるプログラムを作成できるようになる 複数のファイルからなるプログラムでのスコープを理解する 標準ライブラリ関数とは何かを理解する 標準ライブラリ関数の使い方を身につける 教科書 8.8 から( p. 261 ~). 関数の宣言. 関数プロトタイプ宣言
E N D
プログラミング演習II 2004年10月26日(第2回) 理学部数学科・木村巌
前回までの復習 • ローカル変数 • グローバル変数 • 変数の可視範囲 • 変数の寿命 • staticなローカル変数
今日学ぶこと • 関数の宣言 • 複数のファイルからなるプログラムを作成できるようになる • 複数のファイルからなるプログラムでのスコープを理解する • 標準ライブラリ関数とは何かを理解する • 標準ライブラリ関数の使い方を身につける • 教科書8.8から(p. 261~)
関数の宣言 • 関数プロトタイプ宣言 • 関数の名前、引数の数、引数の型、返値の型をコンパイラに知らせる • コンパイラは、コンパイル時にこれらをチェックできる(静的な検査) • 構文 戻り値の型 関数名 (引数リスト); • 最後のセミコロンを忘れないこと • Sample12.cを入力して、コンパイル・実行してみよう
ファイルを分割する • 関数プロトタイプ宣言は、複数のファイルからなるプログラムの作成に特に有効 • 他のプログラムでも作成するような関数は、用途別に別のファイルにしておく • その関数のプロトタイプ宣言も、いわゆる「ヘッダーファイル」に別に記述しておく
複数ファイルからなるプログラムの例 • myfunc.h, myfunc.c, Sample13.c (p.264)を入力し、コンパイル、実行してみよう • (次のスライド参照) • コンパイル・リンク・オブジェクトファイルといった専門用語については、前期の4/28の回のスライドを参照
コンパイルの仕方 • コンパイルの仕方:二通りある • 一気に実行ファイルを作成する • gcc –o Sample13 Sample13.c myfunc.c • 一旦オブジェクトファイルを作り、それらをリンクする • gcc –c Sample13.c • gcc –c myfunc.c • gcc –o Sample13 Sample13.o myfunc.o
コンパイルの仕方(続き) • 一度オブジェクトファイルを作ると、変更を加えなかった方は、コンパイルし直さなくてもよい • 例:Sample13.cは変更したが、myfunc.cは変更していない場合: • gcc –o Sample13 Sample13.c myfunc.o • 巨大なプログラムの場合、コンパイルするだけで何時間もかかることがある
標準ライブラリ関数の仕組みを知る • 標準ライブラリ関数 • C言語の規格で定められている、基本的な処理(入出力、文字列操作など)を行うための関数 • どのCコンパイラにも付属している • 例:printf(), scanf()などなど • 標準ライブラリ関数のプロトタイプ宣言 • それぞれ記述されているヘッダファイルが定められている • 例:printf()ならstdio.h のように
ヘッダファイルの指定 • 標準のヘッダファイルの読み込み • #include <stdio.h>のように、<>で指示する • 自分で作成したヘッダファイルの読み込み • #include “myfunc.h” のように、””で指示する
標準ライブラリ関数はどこにあるのか? • 標準ライブラリ関数の実体は、/usr/bin/libc.a という、スタティックライブラリに含まれている • 複数のオブジェクトファイルを、ひとつのアーカイブファイル(archive file)にまとめる事ができる • リンク時に、リンカが必要な関数を取り出して、実行ファイルにまとめる • ar –t /usr/lib/libc.a で、libc.a内のオブジェクトファイル一覧を見ることができる
ライブラリを作ってみる • myfunc1.c と myfunc2.c を作る。それぞれ、void myfunc1(void){}, void myfunc2(void){}のみ含むことにする • gcc –c myfunc1.c • gcc –c myfunc2.c • これで、myfunc1.oとmyfunc2.oができる • ar –q libmyfunc.a myfunc1.o myfunc2.o • これで、libmyfunc.a というアーカイブができる
ライブラリを使ってみる • main.c というファイルに、main()を書いておく • main()内で、myfunc1(), myfunc2()を呼び出す • gcc –o main main.exe –L. –lmyfunc • これで、main.exeができる • main.exe には、libmyfunc.aから、myfunc1()とmyfunc2()がリンクされる
複数のファイルからなるプログラムでのスコープ複数のファイルからなるプログラムでのスコープ • 識別子がプログラムの全域で可視:「外部リンケージを持つ」という • 識別子が、宣言されたファイルでのみ可視:「内部リンケージを持つ」という • 外部リンケージを持つのは:関数名、グローバル変数名 • 内部リンケージを持つのは:それ以外 • 例外あり(次のスライド)
複数のファイルからなるプログラムでのスコープ(続き)複数のファイルからなるプログラムでのスコープ(続き) • staticをつけた関数名は、内部リンケージを持つ • 変数名に付けるstatic(変数の寿命の指定)とは、意味がまったく異なるので、注意
グローバル変数は乱用しない • グローバル変数:プログラムの全体から読み書き可能 • 使い方を誤ると、厄介なバグ(bug, プログラムの不具合)を招く • プログラムのどの箇所で変更されたのか、追跡しづらい • 絶対に必要な場合にしか使わないこと
自作のライブラリを作る場合 • ライブラリのユーザにとって、簡便で、使いやすいライブラリになることを目指す • 不必要な関数は、staticにして、内部リンケージを持たせる • 必要な関数のみ、ヘッダファイルに記述して、プログラムから使えるようにする
今日学んだこと • 関数の宣言 • 複数のファイルからなるプログラム • 複数のファイルからなるプログラムでのスコープ • 標準ライブラリ関数とは何か • 標準ライブラリ関数の使い方
レポート課題 • 与えられたlongが素数なら1, そうでないなら0を返す関数int isprime (long p)を含むisprime.c, そのプロトタイプ宣言を含むisprime.h, main()関数を含むmain.cをそれぞれ作成せよ.main()を実行すると、整数を入力するよう促し、素数であるか、そうでないかを表示すること. • 締め切り:2004年11月1日一杯(日本時間で) • 提出:メールで木村(iwao@sci.toyama-u.ac.jp)まで. • 感想などあると木村が喜びます
レポートのヒント int isprime (long p) ; /* プロトタイプ宣言 */ int isprime (long p) { … } /* 関数の定義 */ • main.cでは #include <stdio.h> #include “isprime.h” int main (void) { … }